PatchFlag 通过位掩码编码动态性,每个标志对应唯一二进制位(如TEXT=1、CLASS=2、STYLE=4),编译时用按位或(|)组合,运行时用按位与(&)精准分流更新逻辑,实现O(1)纳秒级靶向更新。

Vue 能精准定位具体动态属性,靠的不是猜、不是遍历,而是编译时就写进 VNode 的数字标记——PatchFlag,再配合运行时一次按位与(&)就能立刻知道“该动哪”。
这个机制的核心不在复杂逻辑,而在用二进制位代表一类变化维度,用位运算做开关判断。
PatchFlag 是怎么编码动态性的?
每个 PatchFlag 值对应一个独立的二进制位:
-
TEXT = 1→ 二进制0001 -
CLASS = 2→ 二进制0010 -
STYLE = 4→ 二进制0100 -
PROPS = 8→ 二进制1000
它们互不重叠,靠左移(1 )生成,确保任意组合都能无歧义还原。比如:
立即学习“前端免费学习笔记(深入)”;
-
<div :class="cls" :style="s">{{ msg }}</div>
编译后patchFlag = 1 | 2 | 4 = 7(二进制0111)
这个 7 不是随便加的和,而是三个独立能力的“并集快照”。
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
运行时如何靠一个数字判断该更新什么?
在 patchElement 中,Vue 不会去遍历 props 对象或检查每个字段是否变化,而是直接做位运算分流:
if (patchFlag & PatchFlags.TEXT) {
updateTextContent(el, next.children)
}
if (patchFlag & PatchFlags.CLASS) {
patchClass(el, next.props.class)
}
if (patchFlag & PatchFlags.STYLE) {
patchStyle(el, next.props.style)
}
if (patchFlag & PatchFlags.PROPS) {
patchProps(el, next, prev.props, next.props)
}关键点在于:
- 每次
&运算是 O(1) 纳秒级操作,不读取未标记字段 -
7 & 1→true,触发文本更新 -
7 & 2→true,触发 class 更新 -
7 & 8→false,跳过所有 props 相关逻辑
没有 if-else 嵌套,没有对象键枚举,没有深度比对——只看哪几位是 1,就执行对应分支。
为什么位运算能保证不漏、不误、不冗余?
因为:
- 编译器静态分析模板,只给真正动态的部分打标;静态 class、静态 style、纯文字节点全不参与 patch
- 多个动态项共存时,用
|合并标志,每位含义唯一,可无损拆解 - 运行时
&是精确匹配:flag & CLASS为真 ⇔ CLASS 这一位在 flag 中被置起 ⇔ 该节点 class 确实可能变化
它把“哪些地方会变”这个语义信息,压缩成一个整数,在运行时零成本解码。
不复杂但容易忽略:PatchFlag 不是 Vue 主动“优化”的结果,而是编译器提前把人眼可见的动态性,固化成了机器可速查的位图。

















