Vue3中常用的Composition(组合)API-watch(监视)函数

373 阅读4分钟

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配置有效