Skip to content

Commit fb9622c

Browse files
author
ntepluhina
committed
feat: updated watchers to Vue 3 syntax
1 parent 31ce814 commit fb9622c

File tree

6 files changed

+179
-140
lines changed

6 files changed

+179
-140
lines changed

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@
55
"scripts": {
66
"serve": "vuepress dev src",
77
"build": "vuepress build src"
8+
},
9+
"dependencies": {
10+
"axios": "^0.19.1",
11+
"lodash": "^4.17.15"
812
}
913
}

src/.vuepress/components/computed-1.vue

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66
</template>
77

88
<script>
9-
export default {
10-
data() {
11-
return {
12-
message: 'Hello'
13-
}
14-
},
15-
computed: {
16-
reversedMessage: function () {
17-
return this.message.split('').reverse().join('')
18-
}
19-
}
9+
export default {
10+
data() {
11+
return {
12+
message: 'Hello'
13+
};
14+
},
15+
computed: {
16+
reversedMessage: function() {
17+
return this.message
18+
.split('')
19+
.reverse()
20+
.join('');
21+
}
2022
}
21-
</script>
23+
};
24+
</script>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<div class="demo">
3+
<p>
4+
Ask a yes/no question:
5+
<input v-model="question" />
6+
</p>
7+
<p>{{ answer }}</p>
8+
</div>
9+
</template>
10+
11+
<script>
12+
import { debounce, capitalize } from 'lodash'
13+
import axios from 'axios'
14+
export default {
15+
data() {
16+
return {
17+
question: '',
18+
answer: 'I cannot give you an answer until you ask a question!'
19+
}
20+
},
21+
watch: {
22+
question(newQuestion, oldQuestion) {
23+
this.answer = 'Waiting for you to stop typing...'
24+
this.debouncedGetAnswer()
25+
}
26+
},
27+
created() {
28+
this.debouncedGetAnswer = debounce(this.getAnswer, 500)
29+
},
30+
methods: {
31+
getAnswer() {
32+
if (this.question.indexOf('?') === -1) {
33+
this.answer = 'Questions usually contain a question mark. ;-)'
34+
return
35+
}
36+
this.answer = 'Thinking...'
37+
axios
38+
.get('https://yesno.wtf/api')
39+
.then(response => {
40+
this.answer = capitalize(response.data.answer)
41+
})
42+
.catch(error => {
43+
this.answer = 'Error! Could not reach the API. ' + error
44+
})
45+
}
46+
}
47+
}
48+
</script>

src/.vuepress/config.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ module.exports = {
2525
],
2626
sidebarDepth: 2,
2727
sidebar: {
28-
'/guide/': ['installation', 'introduction', 'instance', 'template-syntax']
28+
'/guide/': [
29+
'installation',
30+
'introduction',
31+
'instance',
32+
'template-syntax',
33+
'computed'
34+
]
2935
}
3036
},
3137
plugins: {
@@ -39,4 +45,4 @@ module.exports = {
3945
}
4046
}
4147
}
42-
};
48+
}

src/guide/computed.md

Lines changed: 83 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Computed Properties
44

5-
<div class="vueschool"><a href="https://vueschool.io/lessons/vuejs-computed-properties?friend=vuejs" target="_blank" rel="sponsored noopener" title="Learn how computed properties work with Vue School">Learn how computed properties work with a free lesson on Vue School</a></div>
5+
[Learn how computed properties work with a free lesson on Vue School](https://vueschool.io/lessons/vuejs-computed-properties?friend=vuejs)
66

77
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:
88

@@ -29,18 +29,21 @@ That's why for any complex logic, you should use a **computed property**.
2929
const vm = Vue.createApp().mount(
3030
{
3131
data: {
32-
message: "Hello"
32+
message: 'Hello'
3333
},
3434
computed: {
3535
// a computed getter
3636
reversedMessage() {
3737
// `this` points to the vm instance
38-
return this.message.split("").reverse().join("")
38+
return this.message
39+
.split('')
40+
.reverse()
41+
.join('')
3942
}
4043
}
4144
},
42-
"#example"
43-
);
45+
'#example'
46+
)
4447
```
4548

4649
Result:
@@ -50,9 +53,9 @@ Result:
5053
Here we have declared a computed property `reversedMessage`. The function we provided will be used as the getter function for the property `vm.reversedMessage`:
5154

5255
```js
53-
console.log(vm.reversedMessage); // => 'olleH'
54-
vm.message = "Goodbye";
55-
console.log(vm.reversedMessage); // => 'eybdooG'
56+
console.log(vm.reversedMessage) // => 'olleH'
57+
vm.message = 'Goodbye'
58+
console.log(vm.reversedMessage) // => 'eybdooG'
5659
```
5760

5861
You can open the sandbox(TODO) and play with the example vm yourself. The value of `vm.reversedMessage` is always dependent on the value of `vm.message`.
@@ -101,37 +104,43 @@ Vue does provide a more generic way to observe and react to data changes on a Vu
101104
```
102105

103106
```js
104-
const vm = Vue.createApp().mount({
105-
data: {
106-
firstName: "Foo",
107-
lastName: "Bar",
108-
fullName: "Foo Bar"
109-
},
110-
watch: {
111-
firstName(val) {
112-
this.fullName = val + " " + this.lastName;
107+
const vm = Vue.createApp().mount(
108+
{
109+
data: {
110+
firstName: 'Foo',
111+
lastName: 'Bar',
112+
fullName: 'Foo Bar'
113113
},
114-
lastName(val) {
115-
this.fullName = this.firstName + " " + val;
114+
watch: {
115+
firstName(val) {
116+
this.fullName = val + ' ' + this.lastName
117+
},
118+
lastName(val) {
119+
this.fullName = this.firstName + ' ' + val
120+
}
116121
}
117-
}
118-
}, '#demo');
122+
},
123+
'#demo'
124+
)
119125
```
120126

121127
The above code is imperative and repetitive. Compare it with a computed property version:
122128

123129
```js
124-
const vm = Vue.createApp().mount({
125-
data: {
126-
firstName: "Foo",
127-
lastName: "Bar"
128-
},
129-
computed: {
130-
fullName() {
131-
return this.firstName + " " + this.lastName;
130+
const vm = Vue.createApp().mount(
131+
{
132+
data: {
133+
firstName: 'Foo',
134+
lastName: 'Bar'
135+
},
136+
computed: {
137+
fullName() {
138+
return this.firstName + ' ' + this.lastName
139+
}
132140
}
133-
}
134-
}, '#demo');
141+
},
142+
'#demo'
143+
)
135144
```
136145

137146
Much better, isn't it?
@@ -185,101 +194,56 @@ For example:
185194
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
186195
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
187196
<script>
188-
var watchExampleVM = new Vue({
189-
el: "#watch-example",
190-
data: {
191-
question: "",
192-
answer: "I cannot give you an answer until you ask a question!"
193-
},
194-
watch: {
195-
// whenever question changes, this function will run
196-
question: function(newQuestion, oldQuestion) {
197-
this.answer = "Waiting for you to stop typing...";
198-
this.debouncedGetAnswer();
199-
}
200-
},
201-
created: function() {
202-
// _.debounce is a function provided by lodash to limit how
203-
// often a particularly expensive operation can be run.
204-
// In this case, we want to limit how often we access
205-
// yesno.wtf/api, waiting until the user has completely
206-
// finished typing before making the ajax request. To learn
207-
// more about the _.debounce function (and its cousin
208-
// _.throttle), visit: https://lodash.com/docs#debounce
209-
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500);
210-
},
211-
methods: {
212-
getAnswer: function() {
213-
if (this.question.indexOf("?") === -1) {
214-
this.answer = "Questions usually contain a question mark. ;-)";
215-
return;
197+
const watchExampleVM = Vue.createApp().mount(
198+
{
199+
data: {
200+
question: '',
201+
answer: 'I cannot give you an answer until you ask a question!'
202+
},
203+
watch: {
204+
// whenever question changes, this function will run
205+
question(newQuestion, oldQuestion) {
206+
this.answer = 'Waiting for you to stop typing...'
207+
this.debouncedGetAnswer()
208+
}
209+
},
210+
created() {
211+
// _.debounce is a function provided by lodash to limit how
212+
// often a particularly expensive operation can be run.
213+
// In this case, we want to limit how often we access
214+
// yesno.wtf/api, waiting until the user has completely
215+
// finished typing before making the ajax request. To learn
216+
// more about the _.debounce function (and its cousin
217+
// _.throttle), visit: https://lodash.com/docs#debounce
218+
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
219+
},
220+
methods: {
221+
getAnswer() {
222+
if (this.question.indexOf('?') === -1) {
223+
this.answer = 'Questions usually contain a question mark. ;-)'
224+
return
225+
}
226+
this.answer = 'Thinking...'
227+
axios
228+
.get('https://yesno.wtf/api')
229+
.then(response => {
230+
this.answer = _.capitalize(response.data.answer)
231+
})
232+
.catch(error => {
233+
this.answer = 'Error! Could not reach the API. ' + error
234+
})
216235
}
217-
this.answer = "Thinking...";
218-
var vm = this;
219-
axios
220-
.get("https://yesno.wtf/api")
221-
.then(function(response) {
222-
vm.answer = _.capitalize(response.data.answer);
223-
})
224-
.catch(function(error) {
225-
vm.answer = "Error! Could not reach the API. " + error;
226-
});
227236
}
228-
}
229-
});
237+
},
238+
'#watch-example'
239+
)
230240
</script>
231241
```
232242

233243
Result:
234244

235-
{% raw %}
236-
237-
<div id="watch-example" class="demo">
238-
<p>
239-
Ask a yes/no question:
240-
<input v-model="question">
241-
</p>
242-
<p>{{ answer }}</p>
243-
</div>
244-
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
245-
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
246-
<script>
247-
var watchExampleVM = new Vue({
248-
el: '#watch-example',
249-
data: {
250-
question: '',
251-
answer: 'I cannot give you an answer until you ask a question!'
252-
},
253-
watch: {
254-
question: function (newQuestion, oldQuestion) {
255-
this.answer = 'Waiting for you to stop typing...'
256-
this.debouncedGetAnswer()
257-
}
258-
},
259-
created: function () {
260-
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
261-
},
262-
methods: {
263-
getAnswer: function () {
264-
if (this.question.indexOf('?') === -1) {
265-
this.answer = 'Questions usually contain a question mark. ;-)'
266-
return
267-
}
268-
this.answer = 'Thinking...'
269-
var vm = this
270-
axios.get('https://yesno.wtf/api')
271-
.then(function (response) {
272-
vm.answer = _.capitalize(response.data.answer)
273-
})
274-
.catch(function (error) {
275-
vm.answer = 'Error! Could not reach the API. ' + error
276-
})
277-
}
278-
}
279-
})
280-
</script>
281-
{% endraw %}
245+
<computed-2 />
282246

283247
In this case, using the `watch` option allows us to perform an asynchronous operation (accessing an API), limit how often we perform that operation, and set intermediary states until we get a final answer. None of that would be possible with a computed property.
284248

285-
In addition to the `watch` option, you can also use the imperative [vm.\$watch API](../api/#vm-watch).
249+
In addition to the `watch` option, you can also use the imperative [vm.\$watch API](TODO:../api/#vm-watch).

0 commit comments

Comments
 (0)