From e4d79f2ca58cf2d670764cfed7084e70e58973dc Mon Sep 17 00:00:00 2001 From: NataliaTepluhina Date: Mon, 20 Jul 2020 17:59:39 +0300 Subject: [PATCH 1/7] chore: update computed properties example --- src/guide/computed.md | 74 +++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/guide/computed.md b/src/guide/computed.md index 79dc8bd76c..76255791e1 100644 --- a/src/guide/computed.md +++ b/src/guide/computed.md @@ -2,45 +2,69 @@ ## Computed Properties -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: +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: + +```js +Vue.createApp({ + data() { + return { + author: { + name: 'John Doe', + books: [ + 'Vue 2 Advanced guide', + 'Vue 3 Basic Guide', + 'Vue 4 - the Mystery' + ] + } + } + } +}) +``` + +And we want to display different messages depending on if `author` already has some books or not ```html -
- {{ message.split('').reverse().join('') }} +
+

Has published books:

+ {{ author.books.length > 0 ? 'Yes' : 'No' }}
``` -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. +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. That's why for complex logic that includes reactive data, you should use a **computed property**. ### Basic Example ```html -
-

Original message: "{{ message }}"

-

Computed reversed message: "{{ reversedMessage }}"

+
+

Has published books:

+ {{ publishedBooksMessage }}
``` ```js -const vm = Vue.createApp({ +Vue.createApp({ data() { return { - message: 'Hello' + author: { + name: 'John Doe', + books: [ + 'Vue 2 Advanced guide', + 'Vue 3 Basic Guide', + 'Vue 4 - the Mystery' + ] + } } }, computed: { // a computed getter - reversedMessage() { + publishedBooksMessage() { // `this` points to the vm instance - return this.message - .split('') - .reverse() - .join('') + return this.author.books.length > 0 ? 'Yes' : 'No' } } -}).mount('#computed-basic') +}).mount('#computed-basics') ``` Result: @@ -52,36 +76,30 @@ Result:

-Here we have declared a computed property `reversedMessage`. The function we provided will be used as the getter function for the property `vm.reversedMessage`: - -```js -console.log(vm.reversedMessage) // => 'olleH' -vm.message = 'Goodbye' -console.log(vm.reversedMessage) // => 'eybdooG' -``` +Here we have declared a computed property `publishedBooksMessage`. -Try to change the value of `message` in the application `data` and you will see how `reversedMessage` is changing accordingly. +Try to change the value of `books` array in the application `data` and you will see how `publishedBooksMessage` is changing accordingly. -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. +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. ### Computed Caching vs Methods You may have noticed we can achieve the same result by invoking a method in the expression: ```html -

Reversed message: "{{ reverseMessage() }}"

+

{{ calculateBooksMessage() }}

``` ```js // in component methods: { - reverseMessage() { - return this.message.split('').reverse().join('') + calculateBooksMessage()() { + return this.author.books.length > 0 ? 'Yes' : 'No' } } ``` -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. +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. This also means the following computed property will never update, because `Date.now()` is not a reactive dependency: From 388981a51c787c83f77317dbce12f3c57fbbde83 Mon Sep 17 00:00:00 2001 From: Natalia Tepluhina Date: Mon, 20 Jul 2020 18:07:49 +0300 Subject: [PATCH 2/7] Update src/guide/computed.md Co-authored-by: Ben Hong --- src/guide/computed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guide/computed.md b/src/guide/computed.md index 76255791e1..c892a419b0 100644 --- a/src/guide/computed.md +++ b/src/guide/computed.md @@ -11,7 +11,7 @@ Vue.createApp({ author: { name: 'John Doe', books: [ - 'Vue 2 Advanced guide', + 'Vue 2 - Advanced Guide', 'Vue 3 Basic Guide', 'Vue 4 - the Mystery' ] From 48347d1e45e6401f3ceacbd630219226b06f4713 Mon Sep 17 00:00:00 2001 From: Natalia Tepluhina Date: Mon, 20 Jul 2020 18:07:56 +0300 Subject: [PATCH 3/7] Update src/guide/computed.md Co-authored-by: Ben Hong --- src/guide/computed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guide/computed.md b/src/guide/computed.md index c892a419b0..fa4f7b5c7c 100644 --- a/src/guide/computed.md +++ b/src/guide/computed.md @@ -12,7 +12,7 @@ Vue.createApp({ name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', - 'Vue 3 Basic Guide', + 'Vue 3 - Basic Guide', 'Vue 4 - the Mystery' ] } From a7f266213b90ebd9ea9e2bdf1c0db446728c45a9 Mon Sep 17 00:00:00 2001 From: Natalia Tepluhina Date: Mon, 20 Jul 2020 18:08:02 +0300 Subject: [PATCH 4/7] Update src/guide/computed.md Co-authored-by: Ben Hong --- src/guide/computed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guide/computed.md b/src/guide/computed.md index fa4f7b5c7c..07073ce90f 100644 --- a/src/guide/computed.md +++ b/src/guide/computed.md @@ -50,7 +50,7 @@ Vue.createApp({ author: { name: 'John Doe', books: [ - 'Vue 2 Advanced guide', + 'Vue 2 - Advanced Guide', 'Vue 3 Basic Guide', 'Vue 4 - the Mystery' ] From a478c755106b30354addfbde92153236f4f625a2 Mon Sep 17 00:00:00 2001 From: Natalia Tepluhina Date: Mon, 20 Jul 2020 18:08:11 +0300 Subject: [PATCH 5/7] Update src/guide/computed.md Co-authored-by: Ben Hong --- src/guide/computed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guide/computed.md b/src/guide/computed.md index 07073ce90f..8cc9be8858 100644 --- a/src/guide/computed.md +++ b/src/guide/computed.md @@ -13,7 +13,7 @@ Vue.createApp({ books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', - 'Vue 4 - the Mystery' + 'Vue 4 - The Mystery' ] } } From e540942e63281417d620fd7c8269301d5a042ed6 Mon Sep 17 00:00:00 2001 From: Natalia Tepluhina Date: Mon, 20 Jul 2020 18:08:18 +0300 Subject: [PATCH 6/7] Update src/guide/computed.md Co-authored-by: Ben Hong --- src/guide/computed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guide/computed.md b/src/guide/computed.md index 8cc9be8858..458346c2c7 100644 --- a/src/guide/computed.md +++ b/src/guide/computed.md @@ -51,7 +51,7 @@ Vue.createApp({ name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', - 'Vue 3 Basic Guide', + 'Vue 3 - Basic Guide', 'Vue 4 - the Mystery' ] } From b60935466314d98e6fb939c3076e1c6680134373 Mon Sep 17 00:00:00 2001 From: Natalia Tepluhina Date: Mon, 20 Jul 2020 18:08:25 +0300 Subject: [PATCH 7/7] Update src/guide/computed.md Co-authored-by: Ben Hong --- src/guide/computed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guide/computed.md b/src/guide/computed.md index 458346c2c7..ce4754485b 100644 --- a/src/guide/computed.md +++ b/src/guide/computed.md @@ -52,7 +52,7 @@ Vue.createApp({ books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', - 'Vue 4 - the Mystery' + 'Vue 4 - The Mystery' ] } }