Vue2 中 computed 和 watch 区别

Vue2 中 computed 和 watch 区别

两者 API 都实现了对数据的监听,但还是有些许差别的。可以看官网介绍

computed

对于视图渲染的任何复杂逻辑都可以使用 计算属性 computed
使用 computed 可以防止 template 模版过重,且使用大量复杂逻辑表达式处理数据时,会对页面的可维护性造成很大影响
计算的属性不在 data 和 props 中

基础使用

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
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>

// bad
<p>{{ this.message.split('').reverse().join('') }}</p>
</div>

var vm = new Vue({
el: '#example',

data() {
return {
message: 'Hello'
}
},

computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})

只有依赖数据发生改变,才会重新进行计算

计算属性基于 data 中声明过或者父组件传递的 props 中的数据通过计算得到的一个新值
computed 方法中使用未声明的属性会报错。

computed 带有缓存功能

computed 内定义的 function 只执行一次,仅当初始化显示或者相关的 data、props 等属性数据发生变化的时候调用
computed 属性值默认会缓存计算结果,计算属性是基于它们的响应式依赖进行缓存的
只有当 computed 属性被使用后,才会执行 computed 的代码,在重复的调用中,只要依赖数据不变,直接取缓存中的计算结果。只有依赖型数据发生改变,computed 才会重新计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<p>姓名:{{ reversedMessage }}</p>
<p>姓名:{{ reversedMessage }}</p>
<p>姓名:{{ reversedMessage }}</p>
<p>姓名:{{ reversedMessage }}</p>
<p>姓名:{{ reversedMessage }}</p>
... ...

computed: {
reversedMessage: function () {
console.log('computed') // 在控制台只打印了一次
return this.message.split('').reverse().join('')
}
}

computed 属性的高级使用

computed 中的属性都有一个 get 和一个 set 方法。
当数据变化时,调用 set 方法。可以通过计算属性的 getter/setter 方法来实现对属性数据的显示和监视,即双向绑定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
computed: {
fullName: {
get() {
// 读取当前属性值的回调,根据相关的数据计算并返回当前属性的值
return this.firstName + ' ' + this.lastName
},
set(val) {
// 当属性值 fullName 发生改变时回调,更新相关的属性数据,val就是 fullName 的最新属性值
const names = val ? val.split(' ') : []
this.firstName = names[0]
this.lastName = names[1]
}
}
}

watch

watch 官网介绍

观察和响应 Vue 实例上数据变动 监听属性 watch

通过 vm 对象的 $watch() 或 watch 配置来监听 Vue 实例上的属性变化,或某些特定数据的变化,然后执行某些具体的业务逻辑操作。
当属性变化时,回调函数自动调用,在函数内部进行计算。其可以监听的数据来源:data,props,computed 内的数据。

监听的属性变更,则触发相应的操作

接收两个参数,第一个参数是最新的值,第二个参数是之前的值。
监听的数据必须是 data, props 中声明过的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
watch: {
// 监听 data 中的 firstName,如果发生了变化,就把变化的值给 data 中的 fullName, val 就是 firstName 的最新值
firstName: function(val) {
this.fullName = val + ' ' + this.lastName
},
fullName.lastName: {
handler(newVal, oldVal) {
console.log(newVal, oldVal)
},
deep: true,
immediate: true
}
}

监听复杂数据类型就需要用到深度监听 deep

computed 和 watch 的区别

computed watch
监听数据源 data、props data,props,computed 内的数据
支持缓存 支持 不支持
支持异步操作 不支持 支持

总结

如果一个数据依赖于其他数据,处理复杂的逻辑运算,则使用 computed
如果要监听某个数据的变更,并且执行一些业务逻辑,则使用 watch

参考

Vue 中 computed 和 watch 的区别1
Vue 中 computed 和 watch 的区别2