有关vue3 watchEffect 依赖收集的疑问?

const queryParams = ref({
  pageSize: 10,
  page: 1,
})
const tableData = shallowRef([])
const loading = ref(false)
const totalNum = ref(0)
function onSearch() {
  loading.value = true
  return InspectionServer.getInspectionTask(queryParams.value).then((res) => {
    tableData.value = res.rows
    loading.value = false
    totalNum.value = res.total
  })
}

watchEffect(onSearch)

为什么只有queryParams变化的时候才会触发watchEffectwatchEffect依赖收集好像是通过访问属性来收集的,queryParams.value访问了属性我理解,loading.value = true 不也访问了属性吗,在后面的then函数里我改变了它的值,但是却不重新执行,虽然从业务逻辑的角度来看不重新执行是对的。

然后我测试了一下,在onSearch里面添加了console.log(loading.value)之后,就无限发送请求了。是不是赋值操作watchEffect里面不算访问属性,所以依赖没有收集?
新测试:在then函数里添加console.log(loading.value)不会无限触发,在loading.value = true下面打印会无限触发。这个现象我的理解是then函数里的属性watchEffect收集的时候还没有执行,所以收集不到。

阅读 1.7k
3 个回答

访问响应式属性就是读取值的时候,而loading.value = true 这个属于属性赋值操作,就是getset的区别。

https://cn.vuejs.org/guide/essentials/watchers.html#watcheffect

watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。

没怎么用过Vue3,但是基本还是Vue响应式原理那一套,watchEffect的回调会立即执行,执行过程中访问到的响应式数据时会进行依赖收集,当响应式数据变化时会触发依赖更新,也就是watchEffect的回调。

你的猜测是对的,loading.value = true 是赋值,不叫访问,所以只会触发 setter,不会触发 getter

const loading = new Proxy({ value: false }, {
    get(...args) { console.log('get', args) },
    set(...args) { console.log('set', args) }
})

// 赋值
loading.value = true // set...
// 这里才存在对 loading.value 的值访问
const v = loading.value // get...

loading.value = xxx 只是赋值,不是读取啊~~~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏