vue3 watch reactive对象的理解

2022-03-18  本文已影响0人  maomizone
const state = reactive({
  foo: 1,
  bar: 2,
  person: {
    name: 'andy',
    a: {
      b: 1
    }
  }
})
watch(state.person, () => {
  console.log('state.person变化了');
})
watch(() => state.person, () => {
  console.log('state.person变化了');
}, { deep: true })

// 如果是 state.person里面的属性改变了,那么watch(state.person, cb)这个cb会执行,因为reactive定义的响应式对象是强制开启deep:true
// watch( () => state.person, cb) 要加上配置项{ deep: true },cb才会执行
state.person.name = 'hehe'
state.person.a = {b: 666}
state.person.a.b = 999
// 如果把 state.person重新赋值,那么就需要watch(() => state.person, cb)这个cb才会执行
state.person = {name: 'ddd'}

state.person里面的属性改变了

state.person重新赋值

1. 当给state 的属性person重新赋值的时候,state.person从proxy对象变为普通对象

2. 直接watch(state.person, cb)是捕捉不到的,因为state.person已经不是reactive的了,这个watch已经失效

这和vue2中的watch不一样,因为看过vue2实现watch的源码,就是你监听state.person,即使重新赋值也是可以侦听到的,原理就是在Object.defineProperty的setter方法里面通知dep去update订阅者(watcher),而watcher就是去执行回调函数。

toRef toRefs

const refPerson = toRef(state, 'person')
// const { person: refPerson } = toRefs(state) // 另外一种写法
console.log(refPerson); // ObjectRefImpl
console.log(refPerson.value === state.person); // true

// 等同于watch( () => state.person, cb)
watch(refPerson, () => {
  console.log('state.person变化了');
}, {deep:true})

// 等同于watch(state.person, cb)
watch(refPerson.value, () => {
  console.log('state.person变化了');
})

vue3 watch源码部分截图

2.png
上一篇 下一篇

猜你喜欢

热点阅读