Vue的patch函数通过key-value精确比对新旧VNode响应式属性,class走专用分支(字符串直比、对象/数组标准化后更新),style则细粒度合并清理,遵循最小DOM操作与语义分离原则。

属性比对基于新旧 VNode 的 key-value 精确对比
Vue 的 patch 函数在更新 DOM 时,并不遍历所有属性,而是只比对新旧两个 VNode 中显式声明的响应式属性。它以 对象键(key)为单位 进行逐项比对:若某属性在新 VNode 中存在、旧 VNode 中不存在,则新增;反之则移除;若双方都存在,则进一步判断值是否变化。这个过程不依赖字符串全量 diff,而是直接读取 JavaScript 对象属性,效率高且语义明确。
Class 更新走专门的 class 处理分支
对于 class 属性,patch 不会当作普通字符串处理。Vue 内部识别到 class 后,会进入专用逻辑:
- 若新旧 class 都是字符串,直接比对是否相等,不等则替换 setAttribute
- 若其中一方是对象(如 { active: isAct, disabled: isDis })或数组,则调用 renderClass 工具函数标准化为字符串,再做差异计算
- 最终通过 el.className = finalString 或 el.setAttribute('class', ...) 单次写入,避免反复操作 DOM
Style 更新采用细粒度合并与清理策略
style 的处理更精细:patch 会把新旧 style 值都转为对象(无论原始是字符串、对象还是数组),然后:
- 遍历旧 style 的每个 key,若新 style 中无此 key,则从 DOM 元素上 removeProperty 清除
- 遍历新 style 的每个 key,若值发生变化(包括从空变非空),则用 setProperty 设置或更新
- 特殊处理浏览器前缀(如 transform → webkitTransform),由 CSS 属性标准化模块自动补全
- 不会重写整个 style.cssText,避免意外覆盖内联 style 中的非响应式样式
关键设计原则:最小化 DOM 操作 + 属性语义分离
patch 对 class 和 style 的特殊处理,本质是遵循两个底层约定:
- class 是离散状态集合,适合“全量计算 + 一次性赋值”
- style 是连续样式映射,适合“增量更新 + 按需清理”
这种区分让 Vue 能在保持模板简洁的同时,在运行时精准控制真实 DOM 行为,既避免过度渲染,也防止样式残留










