You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: source/guide/computed.md
+81-21Lines changed: 81 additions & 21 deletions
Original file line number
Diff line number
Diff line change
@@ -5,47 +5,107 @@ order: 8
5
5
6
6
Vue.js' inline expressions are very convenient, but the best use cases for them are simple boolean operations or string concatenations. For more complicated logic, you should use **computed properties**.
7
7
8
-
In Vue.js, you define computed properties with the `computed` option:
8
+
A computed property is used to declaratively describe a value that depends on other values. When you data-bind to a computed property inside the template, Vue knows when to update the DOM when any of the values depended upon by the computed property has changed. This can be very power and makes your code more declarative, data-driven and thus easier to maintain.
9
+
10
+
It is often a better idea to use a computed property rather than an imperative `$watch` callback. Consider this example:
11
+
12
+
```html
13
+
<divid="demo">{{fullName}}</div>
14
+
```
15
+
16
+
```js
17
+
var vm =newVue({
18
+
data: {
19
+
firstName:'Foo',
20
+
lastName:'Bar',
21
+
fullName:'Foo Bar'
22
+
}
23
+
})
24
+
25
+
vm.$watch('firstName', function (val) {
26
+
this.fullName= val +''+this.lastName
27
+
})
28
+
29
+
vm.$watch('lastName', function (val) {
30
+
this.fullName=this.firstName+''+ val
31
+
})
32
+
```
33
+
34
+
The above code is imperative and cumbersome. Compare it with a computed property version:
9
35
10
36
```js
11
-
vardemo=newVue({
37
+
varvm=newVue({
12
38
data: {
13
39
firstName:'Foo',
14
40
lastName:'Bar'
15
41
},
16
42
computed: {
17
-
fullName: {
18
-
// the getter should return the desired value
19
-
get:function () {
20
-
returnthis.firstName+''+this.lastName
21
-
},
22
-
// the setter is optional
23
-
set:function (newValue) {
24
-
var names =newValue.split('')
25
-
this.firstName= names[0]
26
-
this.lastName= names[names.length-1]
27
-
}
43
+
fullName:function () {
44
+
returnthis.firstName+''+this.lastName
28
45
}
29
46
}
30
47
})
31
-
32
-
demo.fullName// 'Foo Bar'
33
48
```
34
49
35
-
When you only need the getter, you can provide a single function instead of an object:
50
+
Much better. In addition, you can also provide a setter for a computed property:
36
51
37
52
```js
38
53
// ...
39
54
computed: {
40
-
fullName:function () {
41
-
returnthis.firstName+''+this.lastName
42
-
}
55
+
fullName: {
56
+
// getter
57
+
get:function () {
58
+
returnthis.firstName+''+this.lastName
59
+
},
60
+
// setter
61
+
set:function (newValue) {
62
+
var names =newValue.split('')
63
+
this.firstName= names[0]
64
+
this.lastName= names[names.length-1]
65
+
}
66
+
}
43
67
}
44
68
// ...
45
69
```
46
70
47
-
A computed property is essentially a property defined with getter/setter functions. You can use a computed property just like a normal property, but when you access it, you get the value returned by the getter function; when you change its value, you trigger the setter function passing in the new value as its argument.
71
+
### Computed Poperty Caching
72
+
73
+
Before 0.12.8, computed properties behave just like getters - every time you access it, the getter function is re-evaluated. In 0.12.8 this has been improved - computed properties are cached and lazily re-evaluated only when one of its reactive dependencies have changed.
74
+
75
+
Imagine we have an expensive computed property A, which requires looping through a huge Array and doing a lot of computations. Then, we may have other computed properties that depend on A. Without caching, we'd be calling A's getter many more times than necessary and this could potentially cause performance issues. With caching, A's value will be cached as long as its dependencies haven't changed, and accessing it many times will not trigger unnecessary computations.
76
+
77
+
However, it is important to understand what is considered a "reactive dependency":
78
+
79
+
```js
80
+
var vm =newVue({
81
+
data: {
82
+
msg:'hi'
83
+
},
84
+
computed: {
85
+
example: {
86
+
returnDate.now() +this.msg
87
+
}
88
+
}
89
+
})
90
+
```
91
+
92
+
In the example above, the computed property relies on `vm.msg`. Because this is an observed data property on the Vue instance, it is considered a reactive dependency. Whenever `vm.msg` is changed, `vm.example`'s value will be re-evaludated.
93
+
94
+
However, `Date.now()` is **not** a reactive dependency, because it has nothing to do with Vue's data observation system. Therefore, when you programatically access `vm.computed`, you will find the timestamp to remain the same unless `vm.msg` triggered a re-evaluation.
95
+
96
+
Sometimes you may want to preserve the simple getter-like behavior, where every time you access `vm.example` it is simply re-evaluated. Starting in 0.12.11, it's possible to turn off caching for a specific computed property:
97
+
98
+
```js
99
+
computed: {
100
+
example: {
101
+
cache:false,
102
+
get:function () {
103
+
returnDate.now() +this.msg
104
+
}
105
+
}
106
+
}
107
+
```
48
108
49
-
Before 0.12.8, computed properties behave just like getters - every time you access it, the getter function is re-evaluated. In 0.12.8 this has been improved - computed properties are cached and lazily re-evaluated only when necessary.
109
+
Now, every time you access `vm.example`, the timestamp will be up-to-date. However, note this only affects programmatic access inside JavaScript; data-bindings are still dependency-drive. When you bind to a computed property in the template as {% raw %}`{{example}}`{% endraw %}, the DOM will only be updated when a reactive dependency has changed.
50
110
51
111
Next, let's learn about how to [write a custom directive](/guide/custom-directive.html).
0 commit comments