Vue计算属性缓存机制是“依赖不变就不重算”,由响应式系统自动管理:仅当追踪的响应式数据变化时标记为脏,下次读取才重新计算,否则直接返回缓存值。

Vue 计算属性的缓存机制,核心是“依赖不变就不重算”。它不是靠定时检查或手动控制,而是由响应式系统自动管理:只有当它明确追踪到的响应式数据发生变化时,才会标记为“脏”,并在下一次读取时重新计算;其余所有访问都直接返回已缓存的结果。
缓存怎么工作的
计算属性内部维护一个缓存值和一个“是否脏”的状态标记。初始化时不执行,首次访问 .value(或模板中使用)时才运行 getter,并把结果存起来,同时记录当前依赖的响应式数据版本。之后每次读取前,先比对依赖数据的全局版本号——若没变,跳过执行,直接返回缓存值;若变了,才重新执行 getter 并更新缓存。
- 不依赖响应式数据的写法(如
Date.now()、Math.random())无法触发更新,因为它们不会被收集为依赖 - 依赖必须是响应式对象的属性(如
state.count、this.list),普通变量或局部常量不参与追踪 - 深层嵌套对象的属性变更,需确保是通过响应式方式修改(如用
ref或reactive包裹)
什么时候会重新计算
重新计算只发生在两个确切时机:
- 首次访问该计算属性时(惰性求值,初始化不执行)
- 它所依赖的任意一个响应式数据发生变更后,且该计算属性再次被读取时
注意:数据变了,计算属性不会立刻重算;只是被标记为“脏”。真正执行要等到下一次取值——这是“懒更新”,避免渲染过程中不必要的中间计算。
立即学习“前端免费学习笔记(深入)”;
和 methods 的关键区别
方法每次调用都会执行函数,不管依赖有没有变;计算属性则严格按依赖变化来决定是否执行:
- 模板里写
{{ listFilter() }}→ 每次重渲染都调用,哪怕list没动 - 写
{{ filteredList }}(computed)→ 仅当list或过滤条件响应式变化时才重算 - 适合大量数据处理(如搜索过滤、排序、聚合统计)的场景,避免重复开销
常见缓存失效情况
缓存看似稳定,但容易因写法不当而“意外失效”:
- 在 getter 中访问非响应式外部变量(如组件外的全局对象、未包裹的普通对象)
- 依赖了数组索引(
items[0])但没用ref或reactive做响应式处理 - 使用了
Object.freeze或不可代理对象,导致依赖收集失败 - 异步操作中修改了依赖,但未在响应式上下文中触发(比如在
setTimeout里直接改data而非通过ref.value)


















