当前位置: 首页 > 知识库问答 >
问题:

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

宣高朗
2024-09-03
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收集的时候还没有执行,所以收集不到。

共有2个答案

和和裕
2024-09-03

你的猜测是对的,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...
贺景山
2024-09-03

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

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

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

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

 类似资料:
  • 本文向大家介绍详解Vue依赖收集引发的问题,包括了详解Vue依赖收集引发的问题的使用技巧和注意事项,需要的朋友参考一下 问题背景 在我们的项目中有一个可视化配置的模块,是通过go.js生成canvas来实现的。但是,我们发现这个模块在浏览器中经常会引起该tab页崩溃。开启chrome的任务管理器一看,进入该页面内存和cpu就会暴涨,内存经常会飙到700多M。但是我们的canvas实际的像素只有约5

  • 我正在寻找一种方法来收集给定项目的所有依赖约束(通过常规和/或和/或“手动”执行),从一个自定义Gradle插件。 在Maven world中,您可以解析“工件描述符”,该描述符将提供对工件上强制执行的所有托管依赖项的有效列表的访问。我到目前为止还找不到这种信息是如何在Gradle收集的。 有什么建议吗?谢谢!

  • 我想构建这个项目,以便最终的jar在一个jar文件中包含所有依赖项(如果不可能的话,包括从依赖项到jar文件的类),我遵循了线程Including dependencies in a jar with Maven,但它也包含了我在pom中甚至没有提到的依赖项。这是我的POM,它只有两个依赖项。 我想当Final构建时,它包括pom中提到的特定依赖项(以类或jar形式)

  • 编写的PHP扩展需要需要依赖另外一个扩展,在PHP-X中可以调用Extension->require来实现。 PHPX_EXTENSION() { Extension *ext = new Extension("test", "0.0.1"); ext->require("swoole"); ext->require("sockets"); return ext;

  • 依赖关系 这是一个非常轻量级的模块,没有其他依赖项。希望大家在JVM或Android上使用以太坊的RLP编码的项目时会选择使用这个模块,而不再编写自己的实现。

  • 依赖关系 ABI一个非常轻量级的模块,唯一的第三方依赖是 Bouncy Castle,用于hash加密 (Spongy Castle on Android)。 最后希望java和安卓开发者,在JVM或Android上有以太坊ABI合作的项目时会选择使用这个模块,而不是再编写自己的实现。