阅读 2972

computed和watch的区别

computed

computed虽然写法上像个函数,但是实际上是计算属性。它会根据data数据的数据对象做计算处理,就类似于getter跟setter一样创造一个存取器属性。它有个特点,就是Vue内部做了缓存处理,只有它的依赖属性发生了变化,它才会重新计算并且触发渲染。否则不会再次触发计算。

写法

类型:{ [key: string]: Function | { get: Function, set: Function } }

普通写法

const vm=new Vue({
	data:{
    	a:1
    },
    computed:{
    	b:function(){
        	return this.a+1
        },
        c(){ // es6写法
        return this.a+2
        }
    }
})
vm.b //2
vm.c //3
复制代码

上面的属性只有getter效果,我们只能够读取计算属性的值

存取器写法

const vm=new Vue({
	data:{n: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

类型:{ [key: string]: string | Function | Object | Array }

watch翻译为观察,在vue中它是一个侦听器,会对依赖属性进行侦听(观察)。当侦听的属性发生变化时,就会执行一个函数。值得注意的是,watch是异步函数,如果我们的属性需要在侦听后再执行某个变化,可以使用$nextTick这个API

写法

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变了
vm.b={c:2,x:3} //b变了
vm.b={c:3} //b 变了  b.c变了
vm.b.c=100 //b.c变了
vm.d.e.f=4 //d变了
复制代码

要了解watch,首先要知道属性发生变化的几种类型。

属性值的不同影响watch结果

  • 当属性值为简单数据类型时,以vm.a为例,由于此时属性值是简单数据类型,所以很容易监听到其发生变化。此时属性值!==改变后的属性值,就会触发watch

  • 当属性值为复杂数据类型时,以vm.b为例子,它保存了{c:2}这个值。

如果它的内存地址发生变化,也就是说原先的{c:2}和我后来设置的{c:2}的内存地址不一致,所以就会触发b变了

结论

  • 当监听属性的属性值为简单数据类型,就互相比较值,值不一样就触发watch

  • 如果监听的属性的属性值是复杂数据类型,就比较地址。地址不一样就触发watch

deep 和 immediate

deep表示深侦听,也就是我设置的属性对应的属性值即使是复杂数据类型,加上deep,就全方位侦听,包括地址、内层属性的地址、内层属性的属性值。

immediate是表示当侦听开始时就先触发callback函数,默认为一开始不会触发watch效果,而仅仅是侦听。

两者的应用场景

当我们试图通过数据对象来创造另一个属性时,推荐使用computed

当我们试图通过侦听数据对象的改变来做点什么(比如执行一个函数),我们就可以使用watch,在使用watch时尤其要注意其为异步执行的特点。

文章分类
前端
文章标签