const myRef = ref(name: ‘jinD’)

修改 myRef.value.xxx时,不触发watchEffect的原因在于,触发trigger传入的对象是否相同,在 watchEffect 里面访问 myRef.value 时,此时 track的target 是refCompImpl实例,也就是ref

但是修改值时,是通过 myRef.value.xxx = newValue, 不是给 myRef.value = {}设置新值,触发的trigger是在 proxy 的 getter里面(ref 都给传入的对象调用了reative, 也就是把传入的对象转为了proxy),此时trigger的target = {name: ‘xxx’}, 和之前track的 target不一致,没有获取到对应的effect(一个effect就是一个依赖,这里可以理解为watchEffect传入的cb), 所以不会导致 watchEffect 传入的cb重新执行

代码解析:

import { defineComponent, computed, ref, watchEffect } from 'vue'

const obj = {
  name: 'jinD',
}
export default defineComponent({
  name: 'app',

  setup() {
    const myRef = ref({ name: 'jinD' })

    watchEffect(() => {
      console.log('watchEffect 执行')

      console.log(myRef.value) // 这里收集的依赖时 target = refCompImpL
    })

    // debugger
    // myRef.value = { name: 'ding123' }  这样才会导致 watchEffect 重新执行

    myRef.value.name = 'ding1' // 修改的是 name的值,没有修改ref.value的值,不会触发ref的trigger,触发的trigger是在 myRef.value这个proxy上面的,修改 myRef.value.name 时,触发的trigger是在 proxy的setter里面的,此时触发trigger ,target = {name: 'jinD'}, 但是没有给{name: 'jinD'} 收集依赖,所以不会触发 watchEffect 的 cb

    return () => {
      
      return <p>123</p>
    }
  },
})

Logo

前往低代码交流专区

更多推荐