vue中computed 和 watch 区别
computed:通过属性计算而得来的属性
使用场景:当一个值受多个属性影响的时候
- computed 是计算属性,也就是依赖某个值或者 props 通过计算得来得数据;
- 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化;
- computed 内部的函数在调用时不加();
- computed 的值是在 getter 执行之后进行缓存的,只有在它依赖的数据发生变化,会重新调用 getter 来计算;
- computed 是依赖 vm 中 data 的属性变化而变化的,也就是说,当 data 中的属性发生改变的时候,当前函数才会执行,data 中的属性没有改变的时候,当前数不会执行;
- computed 中的函数必须用 return 返回;
- 在 computed 中不要对 data 中的属性进行赋值操作。如果对 data 中的属性进行赋值操作了,就是 data 中的属性发生改变,从而触发 computed 中的函数,成死循环了;
- 当 computed 中的函数所依赖的属性没有发生改变,那么调用当前函数的时候会从缓存中读取。
1 | <template> |
在 computed
中定义的每一个计算属性,都会被缓存起来,只有当计算属性里面依赖的一个或多个属性变化了,才会重新计算当前计算属性的值。上面的代码片段中,在 reversedMessage
中,它依赖了 message 和 number 这两个属性,一旦其中一个变化了,reversedMessage 会立刻重新计算输出新值。
watch:属性监听
使用场景:当一条数据的更改影响到多条数据的时候
- watch 是监听器,可以监听某一个数据,然后执行相应的操作;
- 不支持缓存,数据变直接会触发相应的操作;
- 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
- 支持异步操作;
- watch 中的函数名称必须要和 data 中的属性名一致,因为 watch 是依赖 data 中的属性,当 data 中的属性发生改变的时候,watch 中的函数就会执行;
- watch 中的函数有两个参数,前者是
newVal
,后者是oldVal
; - watch 中的函数是不需要调用的;
- watch 只会监听数据的值是否发生改变,而不会去监听数据的地址是否发生改变。也就是说,watch 想要监听引用类型数据的变化,需要进行深度监听。
"obj.name"(){ }
:如果 obj 的属性太多,这种方法的效率很低,obj:{ handler(newVal){ }, deep: true }
:用handler
+deep
的方式进行深度监听; - 特殊情况下,watch 无法监听到数组的变化,特殊情况就是说更改数组中的数据时,数组已经更改,但是视图没有更新。更改数组必须要用 splice()或者$set。
this.arr.splice(0,1,100)
:修改arr中第0项开始的1个数据为100,this.$set(this.arr,0,100)
:修改 arr 第 0 项值为 100; immediate:true
页面首次加载的时候做一次监听
1 | <template> |
上面的代码中,我们在 watch 中监听了 number 属性,并且在实例创建后 2s 执行对 number 属性的值的更改。输出如下:
1 | number has changed: 100 |
区别:
- 功能上:computed 是计算属性,watch 是监听一个值的变化,然后执行对应的回调。
- 是否调用缓存:computed 中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而 watch 在每次监听的值发生变化的时候都会执行回调。
- 是否调用 return:computed 中的函数必须要用 return 返回,watch 中的函数不是必须要用 return。
- 使用场景:computed—-当一个属性受多个属性影响的时候,使用 computed——-购物车商品结算。watch—-当一条数据影响多条数据的时候,使用 watch——-搜索框。
总结:computed 和 watch 的使用场景并不一样,computed 的话是通过几个数据的变化,来影响一个数据,而 watch,则是可以一个数据的变化,去影响多个数据。
补充:computed 跟 methods 里面的方法的区别,computed 的话访问的时候会直接返回已缓存的结果,而不会像 methods 一样再次计算