v-once是Vue 3中专为静态内容设计的编译期硬冻结指令,仅渲染一次,永久跳过响应式追踪、diff对比与DOM操作,适用于永不变化且不依赖响应式数据的内容,如版权信息、协议文本、静态标题等。

v-once 是 Vue 3 中专为静态内容设计的轻量级优化指令,它不参与响应式系统,也不触发后续更新——内容只渲染一次,之后完全跳过依赖收集、diff 对比和 DOM 操作。用对了,能明显降低 patch 时间和内存开销,尤其在高频更新的父组件里效果更突出。
哪些内容适合加 v-once?
核心判断标准:初始化后**永不变化**,且**不依赖任何响应式数据**。
- 页脚版权信息(如
© 2026 MyApp) - 固定协议文本、帮助文档片段
- 静态标题、图标组件、不可变 banner 图文
- 初始化配置展示(如版本号、构建时间等只读字段)
怎么写才正确?
v-once 不接受参数,直接写在元素上即可。注意它会“冻结”整个节点及其所有子内容——包括插槽、计算属性、{{ }} 中的函数调用,都只执行一次。
✅ 正确示例:
立即学习“前端免费学习笔记(深入)”;
<div v-once> <h2>用户服务协议</h2> <p>本协议自 2026 年 1 月 1 日起生效...</p> </div>
❌ 错误用法:
- 给动态 key 的元素加 v-once(如
<div v-once :key="id">),key 变化时无法重新渲染 <li>包裹需要响应式更新的内容(如 <code><p v-once>{{ count }}</p>,count 变了也不会更新) - v-once:一旦标记,永远不更新,适合真正静态的部分
- v-memo:需传入依赖数组(如
v-memo="[item.id, item.status]"),仅当数组值全相等时才复用 vnode - 二者不能混用在同一元素上;
v-memo="[]"功能类似 v-once,但语义不同——它表达的是“无依赖需检查”,而非“永不变” - 跳过该节点的响应式追踪(effect 不触发)
- diff 过程中直接跳过整棵子树比对
- hydration 阶段更快,尤其 SSR 场景下更明显
和 v-memo 有什么区别?
v-once 是编译期“硬冻结”,v-memo 是运行时“条件跳过”。
实际效果怎么看?
在 DevTools 的 Performance 面板中录制一次交互,对比加 v-once 前后的 patch 阶段耗时。通常可见:



















