Vue计算属性(computed)和侦听器(watcher)

Vue计算属性(computed)和侦听器(watcher)

[computed属性](API — Vue.js (vuejs.org))

计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。

注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。

计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖 (比如非响应式 property) 在该实例范畴之外,则计算属性是不会被更新的。

举例:

1
2
3
4
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var vm = new Vue({
el: '#example',
data: {
message: 'Hello',
reverse: false
},
computed: {
rev: vm => vm.message.split('').reverse().join(''),
reversedMessage:{
get(){
return this.rev
},
set(){}
}
}
})

结果:

Original message: “Hello”

Computed reversed message: “olleH”

[watch属性](API — Vue.js (vuejs.org))

methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。

注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。因为箭头函数绑定了父级作用域的上下文,这样 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
new Vue({
data: {
n: 0,
history: [],
inUndoMode: false
},
watch: {
n: function (newValue, oldValue) {
console.log(this.inUndoMode?"正在撤销":'');
if (!this.inUndoMode) {
this.history.push({ from: oldValue, to: newValue });
}
}
},
// 不如用 computed 来计算 displayName
template: `
<div>
{{n}}
<hr />
<button @click="add1">+1</button>
<hr/>
<button @click="undo">撤销</button>
<hr/>

{{history}}
</div>
`,
methods: {
add1() {
this.n += 1;
},
undo() {
const last = this.history.pop();
console.log(last);
this.inUndoMode = true;
this.n = last.from;
this.$nextTick(()=>{
this.inUndoMode = false;
},0)
}
}
}).$mount("#app");

以上代码中,不能直接执行 this.inUndoMode = false; ,因为 watch 是异步的,当执行 this.n = last.from; 时,不会立刻执行 watch 代码,它只会等 undo 全部执行完毕才会执行。

此处有两种解绝方法:可以将 this.inUndoMode = false; 置于 watch 的最后一句 。或者,放在 this.$nextTick() 中。为了逻辑清晰,此处选择第二种解决方法。

选择使用 nextTick() 函数执行异步操作,是因为 watch 内部所使用的异步 API 也是这个函数,同级别异步函数会按照代码顺序执行。

测试:lucid-shamir-cpcw3 - CodeSandbox

总结

computed 计算属性。它会根据你所以来的数据动态显示新的计算结果。它具有如下特点:

  1. 调用时不需要加括号;
  2. 可以根据依赖自动缓存:当依赖不变时,computed不会重新计算。
  3. computed不支持异步操作,当computed内部有异步操作时无效,无法监听数据变化。

watch 用来监听依赖变化,当依赖的 data 变化时执行回调。它有两个常用选项:

  1. immediate 表示是否在第一次渲染时执行回调;
  2. deep 表示监听某个对象时,是否要同时监听该对象内部的属性变化。
  3. watch本身是异步的,内部使用的异步 AP 是 nextTick()

版权声明:本文作者为「Andy8421」.本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!