Stevv's Blog

Do not go gentle into that good night

Vue3中的Watch使用场景

使用 reactive 声明的响应式数据,类型是 Proxy
使用 ref 声明的响应式数据,类型是 RefImpl
使用 computed 得到的响应式数据,类型也属于 RefImpl
使用 ref声明时,如果是引用类型,内部会将数据使用 reactive包裹成Proxy

五种场景

案例相关数据代码


情况一:监视ref所定义的一个响应式数据

1
2
3
watch(sum,(newValue,oldValue)=>{
console.log('sum的值变了,',newValue,oldValue);
})

情况二:监视ref所定义的多个响应式数据

虽然Vue3支持多个Watch同时存在,但比较冗余,建议封装成数组形式

1
2
3
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum or msg的值变了,',newValue,oldValue);
},{immediate:true})

情况三:监视reactive所定义的响应式数据

  1. 当监听的响应式数据是 Proxy 类型时,newValueoldValue 由于是同一个引用,所以属性值是一样的;
  2. 当监听的响应式数据是 Proxy 类型时,deep 属性无效,无论设置成 true 还是 false,都会进行深度监听。
1
2
3
watch(person,(newValue,oldValue)=>{
console.log('person改变了',newValue,oldValue);
},{deep:false})

情况四:监视reactive所定义的响应式数据中的某一个属性

  1. 需要将监听值写成函数返回形式,vue3无法直接监听对象的某个属性变化

  2. 监听的属性值是基本类型数据,需要写成函数返回该属性的方式才能监听到

此处监视person.age属性

1
2
3
watch(()=>person.age, (newValue, oldValue) => {
console.log("person.age改变了", newValue, oldValue);
});

情况五:监视reactive所定义的响应式数据中的某些属性

此处监视person.name以及person.name,与情况四相同,需要将监听值写成函数返回形式

1
2
3
watch(()=>[person.name,person.age],(newValue,oldValue)=>{
console.log("person的姓名或者年龄改变了", newValue, oldValue);
})

Vue3新增的WatchEffect

  • watch的套路是:既要指明监视的属性,也要指明监视的回调。
  • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
  • watchEffect有点像computed:
  • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
  • 而vatchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
1
2
3
4
5
watchEffect(()=>{
const x1 = sum.value
const x2 = person.job.j1.salary
console.log('WatchEffect所指向的回调执行了');
})