watch(监视)函数
vue3的数据监视和vue2配置功能是一样的,都是对变化的数据进行监视
案例展示
vue3中也是支持vue2中编写数据监视方式的,但是不推荐(都用vue3了,还写啥vue2啊!)
下面通过案例演示分别演示vue2和vue3的写法
vue2实现
分为简单写法和完整写法
简单形式
直接把要监视的数据写成一个函数,会有两个参数,新值和老值
完整形式
完整形式要把监视的属性写成一个对象,而不是函数,对象里面有很多的配置,其中最重要的是handler,它同样可以接受到新值和老值两个参数
它相比于简单形式,优势在于可以配置更多的属性,比如立即监听(immediate),深度监视(deep)等
vue3实现
以上无论是简单形式还是完整形式,都只是vue2中的写法
在vue3中,watch和computed一样,变成了一个组合式的API,使用的时候需要先引入。
引入watch
// 引入watch函数
import {watch} from "vue";
引入完成之后就可以使用了,在vue3中使用watch十分简单,但是有一些不同的使用场景和坑,下面说明
情况1:监视定义ref定义的一个响应式数据
情况2:监视定义ref定义的多个响应式数据
这时候新增一个需求,再定义一个ref响应式数据进行监听
最笨的办法就行,再写一个watch监听,把监听的数据写成info
这也是vue3和vue2的差距,在vue2中怎么可能写多个watch呢,只能写一个watch配置项,但是在vue3中就可以写多个watch函数
但是这种写法较为麻烦,有一个简单的写法,只写一个watch函数,监视的值为一个数组:
watch中加入属性
现在想在watch中加入一些属性,比如自动监听,这时候watch的第三个参数的作用就体现出来了,就是专门给我们加入监听的属性用的
watch的三个参数:
参数1:监视数据(属性),参数2:回调函数,参数3:配置属性
一上来就进行数据监视了,说明属性生效了
情况3:监视reactive定义的一个响应式数据全部属性
刚才监视的都是ref普通数据类型,如果使用reactive监视对象类型的数据,会有一些坑,下面演示一下
坑1:无法获取到正确的oldValue
注意:这里有一个坑,可以发现不管是姓名还是年龄,改变前后都一样,无法获取到正确的oldValue,而且这个问题目前无法解决
坑2:强制开启了深度监视且无法关闭
vue3默认(强制)开启了deep(深度监视)并且无法关闭
可以看到即使把deep设置为false,也是可以监视到的
既然deep属性关不了,那么肯定是影响效率的,所以就有了下面这种情况
情况4:监视reactive定义的一个响应式数据中的某一个属性
我们可以只监视对象中的某一个数学,可以使用函数,返回值就是这个属性:
情况5: 监视reactive定义的一个响应式数据中的某些属性
这种写法稍微复杂点,使用数组包裹起来要监视的属性即可:
特殊情况:
如果要监视reactive里面的多层次对象,需要开启deep:true:
watch函数总结
-
与Vue2.x中watch配置功能一致
-
两个小“坑”:
- 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
- 监视reactive定义的响应式数据中某个属性时:deep配置有效。
-
//情况一:监视ref定义的响应式数据 watch(sum,(newValue,oldValue)=>{ console.log('sum变化了',newValue,oldValue) },{immediate:true}) //情况二:监视多个ref定义的响应式数据 watch([sum,msg],(newValue,oldValue)=>{ console.log('sum或msg变化了',newValue,oldValue) }) /* 情况三:监视reactive定义的响应式数据 若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!! 若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 */ watch(person,(newValue,oldValue)=>{ console.log('person变化了',newValue,oldValue) },{immediate:true,deep:false}) //此处的deep配置不再奏效 //情况四:监视reactive定义的响应式数据中的某个属性 watch(()=>person.job,(newValue,oldValue)=>{ console.log('person的job变化了',newValue,oldValue) },{immediate:true,deep:true}) //情况五:监视reactive定义的响应式数据中的某些属性 watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{ console.log('person的job变化了',newValue,oldValue) },{immediate:true,deep:true}) //特殊情况 watch(()=>person.job,(newValue,oldValue)=>{ console.log('person的job变化了',newValue,oldValue) },{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效