vue patch 中 props 比对按语义分类处理:普通属性用===判等后 set/remove;布尔属性依js布尔值调用 toggleattribute;class/style 深度比对、增量更新;事件监听器仅在函数引用变化时替换。

Vue 的 Patch 过程中,Props 属性值比对不是简单地逐个字符串比较,而是按属性语义分类、分路径处理:只更新真正变化的部分,跳过未变项,避免 DOM 冗余操作。
普通 HTML 属性:有变更才 set/remove
像 id、src、title 这类属性,Vue 会检查新旧值是否“JS 相等”(===):
- 值从无到有(
undefined → 'abc'):调用el.setAttribute() - 值从有到无(
'abc' → null或undefined):调用el.removeAttribute() - 值相同或都为
null/undefined:完全跳过,不触发任何 DOM 操作
布尔属性:按 JS 布尔值判定,不看字符串
disabled、checked、readonly 等布尔属性,Vue 不依赖字符串值(如 "disabled"),而是直接判断 JS 布尔值:
-
true→ 调用el.toggleAttribute(name, true)或setAttribute -
false→ 调用el.toggleAttribute(name, false)或removeAttribute -
null/undefined视为false,同样移除属性
class 和 style:深度比对 + 智能操作
这两类高频更新属性被单独优化,绕过通用 props 流程:
-
class:支持对象、数组、字符串三种写法;内部用
el.classList增删切换,只操作变化项(比如{ active: true, hidden: false }→{ active: true, loading: true },仅添加loading、移除hidden) -
style:深度比对对象键值;仅设置/修改变动的 CSS 属性(如
{ color: 'red', fontSize: '14px' }→{ color: 'blue', lineHeight: '1.5' },只改color、增lineHeight、删fontSize);自动兼容驼峰(backgroundColor)与短横线(background-color)写法
事件监听器:引用比对 + 精准替换
Vue 缓存旧监听器(存在组件实例的 _vei 字段),更新时只关注 handler 引用是否变化:
- 新旧 handler 是同一个函数引用 → 完全跳过绑定/解绑
- 引用不同 → 先
removeEventListener旧的,再addEventListener新的 - 修饰符(如
.stop、.once)在运行时解析并传入addEventListener第三个参数 - 内联函数(如
@click="count++")每次 render 都生成新函数,必然触发替换——应避免










