Vue 3 的 computed 自动完成依赖追踪与缓存:首次执行 getter 时静默收集响应式依赖,仅追踪实际使用的字段;默认惰性求值且缓存结果,依赖未变则不重算;需直接访问响应式数据以保持连接,支持带缓存的可写计算属性。
Vue 3 的 computed 是简化依赖追踪与自动缓存最直接、最自然的方式——它不需要手动监听、不用写 watch、也不用自己管理缓存开关,只要按规范使用响应式数据,Vue 就会自动完成全部工作。
Vue 3 基于 Proxy 实现响应式系统,computed 在首次执行 getter 函数时,会静默收集所有被读取的响应式属性(如 ref.value、reactive 对象的属性),形成精准依赖图。
user.profile.name 变化不会触发依赖 user.id 的计算属性push、splice、索引赋值)也能被完整追踪,不像 Vue 2 需要特殊处理计算属性默认是惰性 + 缓存的。它不会在定义时执行,也不会在依赖变化时立刻重算;只有当它的值被访问(例如模板渲染、.value 读取)且缓存已“脏”时,才重新执行 getter。
computed,比如 {{ listCount }} {{ listCount }} {{ listCount }},底层只执行一次 gettermyComputed.value 多次,只要依赖没变,就始终返回缓存值缓存和追踪生效的前提,是计算逻辑真正依赖 ref、reactive 或其他 computed 返回的响应式对象。
count.value、user.name、filteredList.value
const { name } = user; return name —— 这会丢失响应式连接await)、定时器、DOM 查询等副作用不能放在 getter 中,它们不参与响应式系统当需要支持赋值(如 v-model 绑定)时,可用对象形式定义 get 和 set,其中 get 依然享受完整缓存,set 负责反向同步源数据。
例如:
const firstName = ref('张')const lastName = ref('三')
const fullName = computed({
get: () => `${firstName.value} ${lastName.value}`,
set: (val) => {
[firstName.value, lastName.value] = val.split(' ')
}
})
这里 fullName.value 读取时缓存有效;赋值时只触发 set,不影响 get 的缓存逻辑。