在Vue3中watch监视reactive中数据的几种情况

142 阅读2分钟

公共测试代码部分

const sum = ref(0)
const number = ref(1)
const person = reactive({
      name: "Ricardo",
      age: 21,
      job: {
        web: {
          salary: 20,
        },
      },
    });`
  1. 情况一.watch监视reactive所定义的一个响应式数据,代码如下。
watch(person,(newValue,oldValue)=>{
    console.log("new", newValue);
    console.log("old", newValue);
},{deep:false})//此处的配置不在奏效

1651673276184.png

由示例图可知,即使每次对person.age进行加1的操作,其打印输出的newValue和oldValue的变化都是一致的,我们知道oldValue照理应该打印其上一次的旧值,而不是与新值一致。同时我们可以看待公共测试代码部分person.job.web.salary,同样对salary进行加1的操作,即使开启了{deep:false},但同样可以检测到salary的变化。

总结:当watch监视reactive所定义的一个响应式数据时,是无法检测到oldValue的变化,同时也是强制开启深度监视的。

2.情况二:watch监视reactive所定义的某一个属性时,代码如下。

watch(()=>person.name,(newValue,oldValue)=>{
    
})

3.情况三:watch监视reactive所定义的多个属性时,代码如下。

watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{

})

总结:我们可以从情况二、三也可以清楚的发现,其写法与watch监视ref定义的一个响应式数据和多个响应式数据大体相似。

监视一个ref响应式数据
watch(sum,(newValue,oldValue)=>{})
监视多个ref响应式数据
watch([sum,number],(newValue,oldValue))

4.情况四:当watch监视reactive所定义的引用类型属性时,代码如下。

watch(()=>person.job,(newValue,oldValue)=>{
    console.log("person的job",newValue,oldValue)
},{deep:true})//监视对象里的某个属性时(必须是引用数据类型(对象)),配置deep有效。

1651674852773.png 示例图如上所示,当我们为person中的salary进行加1操作做时,我们可以清楚的看到oldValue都没有按照其原本的应当展示的样子展示,即无法监测到oldValue。值得注意的是这里我们开启了深度监视deep:true,如果我们不开启则操作salary时不会有变化,这与情况一有一定的区别。

综上所述:当watch监视引用类型的数据时,是无法有效检测到oldValue的变化的,同时也要区分开启深度监视的问题。 那么也许会有人说ref也可以定义对象(数组)类型的数据,但是其ref内部会自动通过reactive转为代理对象(Proxy)