v-once是编译时静态冻结,生成常量vnode并彻底跳过后续所有更新流程;v-memo是运行时条件记忆化,通过浅比较依赖数组决定是否跳过子树diff和patch。

v-once 和 v-memo 都是用来减少 Vue 渲染开销的指令,但它们解决的问题不同:v-once 是“彻底不更新”,v-memo 是“按需跳过更新”。用对了能明显降低 patch 压力,尤其在列表、静态区块或高频更新区域。
静态内容用 v-once,一次渲染永不响应
v-once 不是缓存,而是编译时标记。Vue 会把它包裹的内容提升为常量 vnode,后续所有更新周期都直接复用,完全绕过响应式追踪、diff 对比和 DOM 操作。
- 适合页脚版权、导航栏、协议说明等真正不变的内容
- 子组件、插槽、{{ }} 中的函数调用也只执行一次,无法再响应数据变化
- 不能用于可能需要后续更新的区域;若要动态控制,得配合 v-if 切换
v-memo 用于条件性跳过,依赖不变就复用子树
v-memo 在运行时工作,靠浅比较依赖数组(如 v-memo="[item.id, item.status]")决定是否跳过整块子树的 diff 和 patch。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 依赖全部相等 → 复用上次生成的 vnode,不重新创建、不比对、不打补丁
- 任一值变化 → 正常走完整流程,并更新缓存数组
- 它保留响应式能力,子组件 props 变化仍可响应,只是父级跳过了这一层
长列表中正确使用 v-memo 的关键点
v-memo 最常用于 v-for 场景,但必须注意结构和写法:
立即学习“前端免费学习笔记(深入)”;
- :key 必须在外层 v-for 元素上,保证列表重排逻辑正常
- v-memo 放在每项内部最稳定的容器上,包裹所有不随外部状态变动的节点
- 依赖项只列真正影响该区块渲染结果的字段,比如 item.id 和 item.isRead,避免引入 user.theme 这类全局状态
- 数组长度必须固定,不能用对象引用(v-memo="[item]" 会失效),也不能用 index 或未定义值
别混淆,也别混用
v-once 和 v-memo 语义不同,也不能共存于同一元素:
- v-memo="[]" 等价于 v-once 的效果,但含义是“无依赖”,不是“永不变”
- v-once 是编译期硬冻结,v-memo 是运行时软决策
- 两者都不加速首次渲染,只优化后续更新;也不替代 key,更不解决数据获取慢的问题

















