更新Element
更新element节点,主要是更新props和子节点,内部还涉及到动态patch更新。
const patchElement = (n1,n2,parentComponent,parentSuspense,isSVG,optimized) => {const el = (n2.el = n1.el)let { patchFlag, dynamicChildren, dirs } = n2patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */const oldProps = n1.props || EMPTY_OBJconst newProps = n2.props || EMPTY_OBJif (patchFlag > 0) {if (patchFlag & 16 /* FULL_PROPS */) {// 更新propspatchProps(el,n2,oldProps,newProps,parentComponent,parentSuspense,isSVG)} else {// classif (patchFlag & 2 /* CLASS */) {if (oldProps.class !== newProps.class) {// 更新classhostPatchProp(el, 'class', null, newProps.class, isSVG)}}// styleif (patchFlag & 4 /* STYLE */) {hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG)}// propsif (patchFlag & 8 /* PROPS */) {const propsToUpdate = n2.dynamicProps/*** propsToUpdate是 onClick | onUpdate:modelValue 这些。* 示例:<polygon :points="points"></polygon> propsToUpdate === ["points"]*/for (let i = 0; i < propsToUpdate.length; i++) {const key = propsToUpdate[i]const prev = oldProps[key]const next = newProps[key]// 这里的next可能是 string number function object boolean// 比较不同就更新if (next !== prev ||(hostForcePatchProp && hostForcePatchProp(el, key))) {hostPatchProp(el,key,prev,next,isSVG,n1.children,parentComponent,parentSuspense,unmountChildren)}}}}// textif (patchFlag & 1 /* TEXT */) {if (n1.children !== n2.children) {hostSetElementText(el, n2.children)}}}else if (!optimized && dynamicChildren == null) {// unoptimized, full diffpatchProps(el,n2,oldProps,newProps,parentComponent,parentSuspense,isSVG)}// full diffpatchChildren(n1,n2,el,null,parentComponent,parentSuspense,areChildrenSVG)}
总结
主要做了以下几件事情:
- 更新 props
- 更新 class
- 更新 style
- 更新 text
- 更新子节点
patchChildren
