挂载Element
const mountElement = ( vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { let el let vnodeHook const { type, props, shapeFlag, transition, scopeId, patchFlag, dirs, } = vnode { // 创建dom节点 el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is) if (shapeFlag & 8 /* TEXT_CHILDREN */) { hostSetElementText(el, vnode.children) } else if (shapeFlag & 16 /* ARRAY_CHILDREN */) { // 处理数组子节点 mountChildren( vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren ) } // vnode的props:例如 { id: 'search', type:'button' } if (props) { for (const key in props) { if (!isReservedProp(key)) { hostPatchProp( el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren ) } } } // 设置dom的一些attr属性 setScopeId(el, scopeId, vnode, parentComponent) } // 将虚拟节点缓存给dom,且不能被枚举出来。 { Object.defineProperty(el, '__vnode', { value: vnode, enumerable: false, }) Object.defineProperty(el, '__vueParentComponent', { value: parentComponent, enumerable: false, }) } // 把创建的 element,插入到节点中 hostInsert(el, container, anchor)}
总结
- 创建一个element,赋值给 vnode.el
- 判断子节点类型
- 子节点是文本:创建文本
- 子节点是数组:执行方法
mountChildren,批量挂载子节点
- 设置element的
props - 设置element的
attr 属性 - 把创建的element插入到
container 中