Props 变化驱动子组件重渲染,真正的局部更新发生在 VNode diff 阶段;优化关键在于提升 Props 稳定性,如将判断逻辑上移、解构响应式对象、用 v-memo 控制更新边界、合理拆分组件粒度。

Props 变化本身不会直接触发局部更新,而是驱动子组件重渲染;真正的“局部更新”发生在新旧 VNode 的 diff 阶段——只更新实际变化的 DOM 节点。优化的关键不是阻止 Props 变,而是让 Props 的变化更精准、更稳定,从而缩小重渲染范围。
让传入的 Props 尽量保持稳定
父组件频繁变更某个 prop(如 activeId),会导致所有接收该 prop 的子组件全部重渲染,哪怕其中绝大多数状态并未真正改变。
- ❌ 错误写法:
<Item v-for="item in list" :id="item.id" :active-id="activeId" />—— 每次activeId变,所有Item都更新 - ✅ 正确做法:把判断逻辑上移,在父组件中计算好布尔值再传入:
<Item v-for="item in list" :id="item.id" :active="item.id === activeId" />—— 大部分Item的active值不变,跳过更新
避免深层对象 props 触发无效重渲染
Vue 默认对 props 做浅响应式处理。若传入一个对象(如 user),模板中只用到 user.name,但父组件修改了 user.avatar,子组件仍会重渲染——因为整个 user 对象被当作一个响应式单元传递。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 推荐显式解构 +
toRefs:在setup中使用const { name, email } = toRefs(props),让每个字段独立建立响应关系 - 如需监听嵌套字段变化,用
watch(() => props.user.name, ...),而非watch(() => props.user, ..., { deep: true })—— 后者开销大且易误触 - 对仅作展示、不参与响应式依赖的复杂对象,可用
shallowRef或markRaw包裹,避免 Proxy 代理开销
用 v-memo 控制子树更新边界
当子组件 props 稳定性受限(例如必须传整个配置对象),可用 v-memo 显式声明“仅当某些值变化时才更新这部分”。
立即学习“前端免费学习笔记(深入)”;
- 适用场景:列表项中含复杂子组件、图表、富文本等高开销内容
- 示例:
<UserProfile v-memo="[user.id]" :user="user" />—— 只有user.id改变时才重新渲染UserProfile - 注意:
v-memo的依赖数组应尽量精简,避免包含响应式对象本身(如[user]),否则失去意义
合理设计组件粒度与数据流向
组件越小、职责越单一,props 越容易稳定,更新边界越清晰。
- 把通用逻辑(如“是否激活”“是否加载中”)提前计算好,作为简单布尔/字符串传入,而不是把整块业务状态对象透传下去
- 避免“万能 props”:一个组件接收
config、data、options三个大对象,极易因任意字段变更而全量更新 - 必要时拆分子组件,让每个只消费自己真正需要的那部分数据,天然形成更新隔离

















