Skip to content

Commit c8e036a

Browse files
Update computed properties example (vuejs#289)
* chore: update computed properties example * Update src/guide/computed.md Co-authored-by: Ben Hong <[email protected]> * Update src/guide/computed.md Co-authored-by: Ben Hong <[email protected]> * Update src/guide/computed.md Co-authored-by: Ben Hong <[email protected]> * Update src/guide/computed.md Co-authored-by: Ben Hong <[email protected]> * Update src/guide/computed.md Co-authored-by: Ben Hong <[email protected]> * Update src/guide/computed.md Co-authored-by: Ben Hong <[email protected]> Co-authored-by: Ben Hong <[email protected]>
1 parent b6b0339 commit c8e036a

File tree

1 file changed

+46
-28
lines changed

1 file changed

+46
-28
lines changed

src/guide/computed.md

+46-28
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,69 @@
22

33
## Computed Properties
44

5-
In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example:
5+
In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example, if we have an object with a nested array:
6+
7+
```js
8+
Vue.createApp({
9+
data() {
10+
return {
11+
author: {
12+
name: 'John Doe',
13+
books: [
14+
'Vue 2 - Advanced Guide',
15+
'Vue 3 - Basic Guide',
16+
'Vue 4 - The Mystery'
17+
]
18+
}
19+
}
20+
}
21+
})
22+
```
23+
24+
And we want to display different messages depending on if `author` already has some books or not
625

726
```html
8-
<div id="example">
9-
{{ message.split('').reverse().join('') }}
27+
<div id="computed-basics">
28+
<p>Has published books:</p>
29+
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
1030
</div>
1131
```
1232

13-
At this point, the template is no longer simple and declarative. You have to look at it for a second before realizing that it displays `message` in reverse. The problem is made worse when you want to include the reversed message in your template more than once.
33+
At this point, the template is no longer simple and declarative. You have to look at it for a second before realizing that it performs a calculation depending on `author.books`. The problem is made worse when you want to include this calculation in your template more than once.
1434

1535
That's why for complex logic that includes reactive data, you should use a **computed property**.
1636

1737
### Basic Example
1838

1939
```html
20-
<div id="computed-basic">
21-
<p>Original message: "{{ message }}"</p>
22-
<p>Computed reversed message: "{{ reversedMessage }}"</p>
40+
<div id="computed-basics">
41+
<p>Has published books:</p>
42+
<span>{{ publishedBooksMessage }}</span>
2343
</div>
2444
```
2545

2646
```js
27-
const vm = Vue.createApp({
47+
Vue.createApp({
2848
data() {
2949
return {
30-
message: 'Hello'
50+
author: {
51+
name: 'John Doe',
52+
books: [
53+
'Vue 2 - Advanced Guide',
54+
'Vue 3 - Basic Guide',
55+
'Vue 4 - The Mystery'
56+
]
57+
}
3158
}
3259
},
3360
computed: {
3461
// a computed getter
35-
reversedMessage() {
62+
publishedBooksMessage() {
3663
// `this` points to the vm instance
37-
return this.message
38-
.split('')
39-
.reverse()
40-
.join('')
64+
return this.author.books.length > 0 ? 'Yes' : 'No'
4165
}
4266
}
43-
}).mount('#computed-basic')
67+
}).mount('#computed-basics')
4468
```
4569

4670
Result:
@@ -52,36 +76,30 @@ Result:
5276
</p>
5377
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
5478

55-
Here we have declared a computed property `reversedMessage`. The function we provided will be used as the getter function for the property `vm.reversedMessage`:
56-
57-
```js
58-
console.log(vm.reversedMessage) // => 'olleH'
59-
vm.message = 'Goodbye'
60-
console.log(vm.reversedMessage) // => 'eybdooG'
61-
```
79+
Here we have declared a computed property `publishedBooksMessage`.
6280

63-
Try to change the value of `message` in the application `data` and you will see how `reversedMessage` is changing accordingly.
81+
Try to change the value of `books` array in the application `data` and you will see how `publishedBooksMessage` is changing accordingly.
6482

65-
You can data-bind to computed properties in templates just like a normal property. Vue is aware that `vm.reversedMessage` depends on `vm.message`, so it will update any bindings that depend on `vm.reversedMessage` when `vm.message` changes. And the best part is that we've created this dependency relationship declaratively: the computed getter function has no side effects, which makes it easier to test and understand.
83+
You can data-bind to computed properties in templates just like a normal property. Vue is aware that `vm.publishedBooksMessage` depends on `vm.author.books`, so it will update any bindings that depend on `vm.publishedBooksMessage` when `vm.author.books` changes. And the best part is that we've created this dependency relationship declaratively: the computed getter function has no side effects, which makes it easier to test and understand.
6684

6785
### Computed Caching vs Methods
6886

6987
You may have noticed we can achieve the same result by invoking a method in the expression:
7088

7189
```html
72-
<p>Reversed message: "{{ reverseMessage() }}"</p>
90+
<p>{{ calculateBooksMessage() }}</p>
7391
```
7492

7593
```js
7694
// in component
7795
methods: {
78-
reverseMessage() {
79-
return this.message.split('').reverse().join('')
96+
calculateBooksMessage()() {
97+
return this.author.books.length > 0 ? 'Yes' : 'No'
8098
}
8199
}
82100
```
83101

84-
Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that **computed properties are cached based on their reactive dependencies.** A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as `message` has not changed, multiple access to the `reversedMessage` computed property will immediately return the previously computed result without having to run the function again.
102+
Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that **computed properties are cached based on their reactive dependencies.** A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as `author.books` has not changed, multiple access to the `publishedBooksMessage` computed property will immediately return the previously computed result without having to run the function again.
85103

86104
This also means the following computed property will never update, because `Date.now()` is not a reactive dependency:
87105

0 commit comments

Comments
 (0)