computed
computed虽然写法上像个函数,但是实际上是计算属性。它会根据data数据的数据对象做计算处理,就类似于getter跟setter一样创造一个存取器属性。它有个特点,就是Vue内部做了缓存处理,只有它的依赖属性发生了变化,它才会重新计算并且触发渲染。否则不会再次触发计算。
computed的实现
代码举例:普通写法
const vm = new Vue({
data:{
a:1
},
computed:{
b:function(){
return this.a+1
},
c(){ // es6写法,省略了:function
return this.a+2
}
}
})
vm.b //2
vm.c //3
上面的属性只有getter效果,我们只能够读取计算属性的值
存取器写法
const vm=new Vue({
data:{
a:1
},
computed:{
a:{
get(){
return this.n+1
},
set(value){
this.n=value-1
}
}
}
})
vm.n // 1
vm.a =3
vm.n //2
存取器的写法看上去就像设置一个属性一样了,而且我们还可以设置计算属性的值,上面的写法会影响到响应式属性n,当设置vm.a时,vm.n也会发生变化。
computed默认有缓存效果,当计算属性没有发生变化时,不会重新计算更不会重新渲染。
watch
watch翻译为侦察,在vue中它是一个侦听器,会对依赖属性进行侦听(观察)。当侦听的属性发生变化时,就会执行一个函数。注意,watch是异步函数,如果我们的属性需要在侦听后再执行某个变化,可以使用$nextTick这个Vue自己封装的一个异步API。
watch的实现
let vm = new Vue({
data: {
a: 1,
b: {
c: 2
},
d: {
e: {
f: 3
}
},
},
watch: {
a(newvalue, oldValue) {
console.log( 'a变了')
},
b: {
handler: function (v, oldv) {
console.log("b变了")
},
immediate: true //第一次加载做监听
},
'b.c': function (v, oldv) {
console.log("b.c变了")
},
d: {
handler: function (v, oldv) {
console.log("d变了")
},
deep: true // 深侦听,只要d、d.e包括d.e.f发生任何一个变化都会侦听到
}
}
})
// vm.b 变了
vm.a=2 //a变了
vm.b={c:2} // b变了,因为改变了b的地址
vm.b={c:2,x:3} //b变了,因为改变了b的地址
vm.b={c:3} //b 变了,因为改变了b的地址 b.cye变了
vm.b.c=100 //b.c变了,因为只是指定改变了b里面c的值
vm.d.e.f=4 // f变了,d变了,因为d做了deep: true,里面的任何一个发生变化则d都会变化。
如何区分别watch监听的数据是否发生了变化
- 当监听属性的属性值为简单数据类型,就互相比较值,值不一样就触发
watch - 如果监听的属性的属性值是复杂数据类型,就比较地址。地址不一样就触发
watc
watch中的deep和immediate
deep表示深侦听,也就是我设置的属性对应的属性值即使是复杂数据类型,加上deep:true,就全方位侦听,包括地址、内层属性的地址、内层属性的属性值。默认值为falseimmediate是表示当侦听开始时就先触发callback函数,默认为false一开始不会触发watch效果,而仅仅是侦听。
总结
-
功能上:
computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。 -
是否调用缓存:
computed支持缓存,相依赖的数据发生改变才会重新计算;watch不支持缓存,只要监听的数据变化就会触发相应操作 -
是否调用
return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。 -
computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加
immediate属性,设置为true(immediate:true)。 -
使用场景:当一个属性受多个属性影响的时候,使用computed;当一条数据影响多条数据的时候,使用watch。
-
computed不支持异步,当computed内有异步操作时是无法监听数据变化的;watch支持异步操作 -
computed属性的属性值是函数,函数返回值为属性的属性值,computed中每个属性都可以设置set与get方法。watch监听的数据必须是data中声明过或父组件传递过来的props中的数据,当数据变化时,触发监听器。