v-memo 是 Vue 3.2+ 提供的性能优化指令,用于跳过未变化子树的 diff 和 patch;必须配合 v-for 使用,依赖数组需全等才复用 vnode,适用于长列表中稳定字段(如 id、status)的缓存。

v-memo 是 Vue 3.2+ 提供的性能优化指令,专为减少长列表中不必要的虚拟 DOM 更新而设计。它不改变渲染逻辑,而是告诉 Vue:“只要这些值没变,这块模板就别动”,从而跳过整棵子树的 diff 和 patch 过程,显著降低 CPU 开销。
v-memo 的基本写法和触发条件
它必须配合 v-for 使用(Vue 3.4+ 版本强制要求),语法是 v-memo="[dep1, dep2, ...]",括号内是一个响应式依赖数组。
- 只有当数组中每一个值都与上一次完全相等(使用 === 判断),Vue 才复用上次生成的 vnode 子树
- 只要数组中任一值变化,就会重新渲染该节点及其全部子内容
- 依赖项必须是响应式数据(如 ref、reactive 属性),不能是普通常量或非响应式对象
- :key 必须保留,且独立于 v-memo —— key 控制节点复用位置,v-memo 控制是否跳过更新
典型场景:优化用户列表渲染
比如一个 1000 条用户的列表,每项只显示姓名和在线状态,但全局可能有搜索、排序、loading 等状态变化:
<div v-for="user in filteredUsers" :key="user.id" v-memo="[user.id, user.status]">
<p>{{ user.name }}</p>
<span :class="user.status === 'online' ? 'online' : 'offline'">
{{ user.status }}
</span>
</div>
这里 v-memo 监控的是 每个用户的 id 和 status。即使全局 loading 变了,只要某位用户的 id 和 status 没变,那一整块 DOM 就直接复用,不走 diff 流程。
立即学习“前端免费学习笔记(深入)”;
- 避免写成
v-memo="[user]"—— user 是对象引用,每次 reactivity 触发都会生成新代理,导致缓存失效 - 也不建议用
v-memo="[user.name]"—— name 可能重复,无法唯一标识子树稳定性 - 推荐组合使用不可变字段,如
[user.id, user.status]或[user.id, user.updatedAt]
和 v-once 的区别与配合使用
v-once 是“渲染一次就冻结”,适合完全静态内容;v-memo 是“按需缓存”,适合部分动态、大部分稳定的结构。
-
v-once等价于v-memo="[]"—— 空数组意味着永远不更新 - 可以嵌套使用:外层用 v-memo 控制整体结构,内层对纯文本用 v-once 进一步锁定
- 例如:
<h2 v-once>{{ title }}</h2>+<div v-memo="[item.id]">...</div>
常见陷阱和注意事项
v-memo 不是银弹,用错反而引发渲染错误或数据不同步。
- 不要在 v-memo 依赖中传入函数调用、计算属性返回值或非响应式变量(如 Math.random())
- 避免嵌套 v-memo —— 子节点的 v-memo 会干扰父节点缓存判断,编译器可能警告
- 如果列表项包含子组件,确保子组件内部不依赖外部未声明的响应式状态
- 首次渲染时 v-memo 不起作用,它只影响后续更新;所以首屏性能靠其他手段(如分页、虚拟滚动)



















