v-memo 是 Vue 3.2+ 的实验性指令,用于优化长列表渲染性能,仅当依赖数组各项浅层引用均未变化时复用子树,需配合 v-for 和稳定 key 使用。

v-memo 是 Vue 3.2 引入的实验性指令,专为优化长列表(尤其是 v-for)的渲染性能而设计。它不是全局缓存,也不替代 key,而是让 Vue 在满足条件时跳过整块 vnode 的 diff 和 patch 过程——前提是“依赖数组”未变化。用对了,能显著减少虚拟 DOM 比较开销;用错了,反而引发渲染错误或状态不同步。
理解 v-memo 的工作原理
v-memo 接收一个数组作为依赖项(类似 computed 的依赖追踪),只有当数组中**每个值的浅层引用都未改变**时,Vue 才复用上一次生成的子树。它作用于模板片段,必须与 v-for 配合使用,且需显式提供 key:
- 语法:
v-memo="[dep1, dep2]",数组元素必须是响应式数据(ref、reactive 属性等) - 不支持动态数组长度变化(如
v-memo="[...items.map(i => i.id)]"会失效) - 若依赖项含 undefined / null / NaN,v-memo 会退化为始终不缓存(每次重渲染)
- 不能嵌套在 v-if / v-else 中使用,否则缓存行为不可预测
长列表中正确使用 v-memo 的典型场景
适用于列表项结构稳定、仅局部数据更新的场景,比如消息列表、商品卡片、日志条目:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
- ✅ 推荐:每项只依赖自身字段,如
v-memo="[item.id, item.status, item.unread]" - ✅ 推荐:结合计算属性预处理,避免模板内调用函数(函数返回新对象会破坏缓存)
- ❌ 避免:写成
v-memo="[item]"(对象引用总变)、v-memo="[index]"(索引非稳定标识) - ❌ 避免:依赖父级响应式对象整体(如
v-memo="[list]"),应拆解到具体字段
对比 v-once 和 v-memo 的关键区别
两者都跳过更新,但语义和适用阶段完全不同:
立即学习“前端免费学习笔记(深入)”;
- v-once:首次渲染后完全静态,后续任何响应式变化都不触发更新 —— 适合纯展示、永不变更的内容
- v-memo:有条件地复用,依赖数组变化时仍会重新渲染 —— 适合“大部分时间不变,偶尔局部更新”的列表项
- 举例:聊天消息气泡中,头像 URL、昵称、发送时间固定,仅“已读状态”会变 → 用
v-memo="[msg.id, msg.avatar, msg.name, msg.time]",比整个msg对象更安全
实战调试与避坑建议
开启 Vue Devtools 的 Performance 面板,观察 patch 节点数下降可验证效果;常见问题这样解决:
- 缓存未生效?检查依赖数组是否含响应式丢失字段(如解构赋值后的普通变量)
- 列表错乱/状态错位?确认 key 与 v-memo 依赖逻辑一致(key 应该是稳定唯一标识,如 id)
- 内存占用升高?v-memo 不自动释放缓存,大量离屏项建议配合
virtual-scroller或分页 - 升级后报错 “v-memo is not supported in this version”?确保使用 Vue ≥ 3.2.25,且未在非兼容构建中启用


















