代码
<template><div>Counter: {{ counter }}</div><div>Double Counter: {{ doubleCounter }}</div>
</template><script setup lang="ts">
import { ref, computed } from "vue";const counter = ref(0);const doubleCounter = computed(() => {console.log("doubleCounter computed");return counter.value * 2;
});setTimeout(() => {counter.value = 1;
}, 1000);// 直接引用 doubleCounter
doubleCounter;
</script>
问题
-
代码运行时,
console.log("doubleCounter computed")
会被打印几次?为什么?- 如果不会打印,请说明原因。
- 如果会打印,请描述每次打印的时机。
-
如果将
doubleCounter;
替换为console.log(doubleCounter.value);
,会发生什么变化?- 分析控制台的输出结果,并解释原因。
-
如果在模板中移除
{{ doubleCounter }}
,会对代码的行为产生什么影响?- 分析
console.log("doubleCounter computed")
的打印次数和时机。
- 分析
-
如何修改代码以确保
console.log("doubleCounter computed")
在初始渲染和counter
更新时都被打印?
答案提示
-
初次运行时
- 控制台会打印
"doubleCounter computed"
并在counter
更新时再次打印。
- 控制台会打印
-
替换为
console.log(doubleCounter.value);
后- 访问
doubleCounter.value
会触发computed的回调函数。 - 控制台会打印
"doubleCounter computed"
,并在counter
更新时再次打印。
- 访问
-
移除模板中的
{{ doubleCounter }}
- 模板不再读取
doubleCounter.value
,因此 computed 的回调函数不会被触发。 - 即使
counter
更新,也不会打印"doubleCounter computed"
。
- 模板不再读取
-
确保打印的修改方式
- 在模板中保留
{{ doubleCounter }}
,或者在脚本中显式访问doubleCounter.value
(如通过watch或其他逻辑)。
- 在模板中保留
总结
console.log(“doubleCounter computed”) 被打印的前提是以下任意一种情况:
- 访问 doubleCounter.value:显式读取 computed 属性的值。
- 在模板中使用 doubleCounter:Vue 自动读取 doubleCounter.value。
通过这道题目,开发者可以深入理解 Vue 的响应式系统、computed属性的工作原理,以及依赖追踪的触发条件。