shapeFLagvnode的shapeFLag属性以二进制形式描述组件的类型。shapeFLag的值类型是一个枚举:exportconstenumShapeFlags{ELEMENT=1,//表示一个普通的HTML元素FUNCTIONAL_COMPONENT=1<<1,//功能组件STATEFUL_COMPONENT=1<<2,//状态组件TEXT_CHILDREN=1<<3,//子节点是文本ARRAY_CHILDREN=1<<4,//子节点是数组SLOTS_CHILDREN=1<<5,//子节点是槽TELEPORT=1<<6,//表示vnode描述了一个传送componentSUSPENSE=1<<7,//表示vnode描述了一个suspense组件COMPONENT_SHOULD_KEEP_ALIVE=1<<8,//表示需要保活的有状态组件COMPONENT_KEPT_ALIVE=1<<9,//有状态的组件有已保持活动状态COMPONENT=ShapeFlags.STATEFUL_COMPONENT|ShapeFlags.FUNCTIONAL_COMPONENT//组件,统称为有状态组件和功能组件}一个vnode可以有多种不同的类型,比如:vnode.shapeFlag=ShapeFlags.ELEMENT|ShapeFlags.ARRAY_CHILDREN可以通过vnode.shapeFlag&ShapeFlags.ELEMENT来判断一个vnode的类型,或者判断一个vnode是否同时是多种类型。vnode.shapeFlag和ShapeFlags.ELEMENT|ShapeFlags.ARRAY_CHILDRENpatchFlagpatchFlag是编译在template模板中,在vnode中添加了一个标识信息。该标识信息反映了vnode的哪些部分绑定到动态值。这样,在runtime阶段,就可以根据patchFlag判断哪些内容需要更新,并实现有针对性的更新。patchFlag的类型和shapeFLag一样,也是枚举类型:exportconstenumPatchFlags{//表示vnode有动态textContent元素TEXT=1,//表示vnode有动态textContent类CLASS=1<<1,//表示它有动态样式STYLE=1<<2,//表示它有动态非类和样式道具PROPS=1<<3,//表示道具有动态key,ConflictwithCLASS,STYLE,PROPSFULL_PROPS=1<<4,//表示有监听事件(同构时需要添加)HYDRATE_EVENTS=1<<5,//表示vnode是一个fragment,其顺序为children不会改变STABLE_FRAGMENT=1<<6,//表示children有一个带键的片段KEYED_FRAGMENT=1<<7,//表示children有一个没有键的片段UNKEYED_FRAGMENT=1<<8,//表示vnode只需要非props补丁。比如label中只有ref或instructionsNEED_PATCH=1<<9,//表示vnode中有dynamicslot。例如,动态插槽名称DYNAMIC_SLOTS=1<<10,//表示用户创建的片段,在模板的根级别带有注释,这是一个仅限开发的标志,因为注释在生产中被删除DEV_ROOT_FRAGMENT=1<<11,//下面是一些使用位运算无法匹配的特殊标志//表示vnode已经静态改进HOISTED=-1,//diff算法应该退出优化模式BAIL=-2}的以下是针对不同patchFlag的一些示例PatchFlags.TEXT{{msg}}h1>标签中只绑定了动态textContext,所以上面template转为vnode后,patchFlag为PatchFlags.TEXT。您可以复制代码在VueSFCPlayground中进行测试。PatchFlags.CLASS,PatchFlags.STYLE
标签绑定动态类、style、textContent,所以patchFlag是PatchFlags.TEXT|补丁标志.CLASS|PatchFlags.STYLEVueSFCPlaygroundPatchFlags.PROPS{{msg}}
标签绑定了动态title和textContent,所以patchFlag为PatchFlags.TEXT|PatchFlags.PROPSVueSFCPlaygroundPatchFlags.FULL_PROPS<模板>{{msg}}
标签绑定动态textContent和一个动态dynamicKey属性,所以patchFlag是PatchFlags.TEXT|PatchFlags.FULL_PROPSVueSFCPlaygroundPatchFlags.STABLE_FRAGMENT{{msg}}
text标签中有多个根标签,会创建一个Fragment类型的v??node,因为、标签顺序永远不会变,所以Fragment类型vnode的patchFlag是PatchFlags.STABLE_FRAGMENTVueSFCPlaygroundPatchFlags.KEYED_FRAGMENT{{item}}
标签中有多个根标签,每个标签都有一个key,所以Fragment类型的patchFlagVnodeforPatchFlags.KEYED_FRAGMENTVueSFCPlaygroundPatchFlags.UNKEYED_FRAGMENT{{item}} 标签中有多个根标签,但是没有一个标签有key,所以Fragment类型的patchFlagvnode是PatchFlags.UNKEYED_FRAGMENTVueSFCPlaygroundPatchFlags.NEED_PATCH你好
和对应的vnode的patchFlag都是PatchFlags.NEED_PATCHVueSFCPlaygroundPatchFlags.DYNAMIC_SLOTS你好 {{name}} 两个slots可能会发生变化,所以它们对应的vnode的patchFlag是PatchFlags.DYNAMIC_SLOTSVueSFCPlaygroundPatchFlags.DEV_ROOT_FRAGMENTHello
的根是级别的注释,同时有多个标签,注释的顺序不会改变,所以根vnode的patchFlag是PatchFlags.STABLE_FRAGMENT|PatchFlags.DEV_ROOT_FRAGMENTVueSFCPlaygroundPatchFlags.HOISTEDHello
test
和
标签是两个静态标签,所以它们对应的vnode的patchFlag是PatchFlags.HOISTED如果只有一个静态标签,那么这个静态标签对应的vnode的patchFlag不是PatchFlags。HOISTED,但默认0你好
VueSFC游乐场
Hello
的根是级别的注释,同时有多个标签,注释的顺序不会改变,所以根vnode的patchFlag是PatchFlags.STABLE_FRAGMENT|PatchFlags.DEV_ROOT_FRAGMENTVueSFCPlaygroundPatchFlags.HOISTEDHello
test
和
标签是两个静态标签,所以它们对应的vnode的patchFlag是PatchFlags.HOISTED如果只有一个静态标签,那么这个静态标签对应的vnode的patchFlag不是PatchFlags。HOISTED,但默认0你好
VueSFC游乐场