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