之前文章分析过,createApp 方法执行完后,会赋值给 app,而 app 里 mount 方法是 vue 的挂载方法。
组件渲染、proxy 代理都在这个方法里面。
const { mount } = app
//重写 mount 方法
app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {
//先清空挂载标签下的内容
container.innerHTML = \\\'\\\'
//执行 mount 方法
const proxy = mount(container)
//返回 proxy
return proxy
}
mount(rootContainer: HostElement, isHydrate?: boolean): any {
if (!isMounted) {
const vnode = createVNode(
rootComponent as ConcreteComponent,
rootProps
)
//渲染vnode,挂载到页面指定的 demo 上
render(vnode, rootContainer)
//设置为 true
isMounted = true
return vnode.component!.proxy
}else{
//...
}
}
const render: RootRenderFunction = (vnode, container) => {
//执行 patch 方法
patch(container._vnode || null, vnode, container)
}
//通过 patch 方法跳转到 过程组件
processComponent(n1,n2,container,anchor,parentComponent,parentSuspense,isSVG,optimized)
//通过过程组件,跳转到挂载组件方法
mountComponent(n2,container,anchor,parentComponent,parentSuspense,isSVG,optimized)
const mountComponent: MountComponentFn = (initialVNode,container,anchor,parentComponent,parentSuspense,isSVG,optimized
) => {
//实例化组件
const instance: ComponentInternalInstance = (initialVNode.component = createComponentInstance(
initialVNode,
parentComponent,
parentSuspense
))
//设置组件
setupComponent(instance)
}
export function createComponentInstance(
vnode: VNode,
parent: ComponentInternalInstance | null,
suspense: SuspenseBoundary | null
) {
//VNode 类型
const type = vnode.type as ConcreteComponent
// inherit parent app context - or - if root, adopt from root vnode
//继承父组件实例的 appContext ,如果是根组件,则从根 VNode 中取
const appContext =
(parent ? parent.appContext : vnode.appContext) || emptyAppContext
//初始化当前组件实例
//实例中添加了很多属性,uid、vnode、数据、是否挂载、是否卸载、生命周期等等...
const instance: ComponentInternalInstance = {
uid: uid++,
vnode,
// state
ctx: EMPTY_OBJ,
data: EMPTY_OBJ,
props: EMPTY_OBJ,
// lifecycle hooks
isMounted: false,
bc: null,
c: null,
bm: null,
...
}
//声明是否是根组件
instance.root = parent ? parent.root : instance
//派发事件
instance.emit = emit.bind(null, instance)
return instance
}
export function setupComponent(
instance: ComponentInternalInstance,
isSSR = false
) {
//解构数据和子组件和状态
const { props, children, shapeFlag } = instance.vnode
//判断是否是有状态的
const isStateful = shapeFlag & ShapeFlags.STATEFUL_COMPONENT
//初始化 props 和 slots
initProps(instance, props, isStateful, isSSR)
initSlots(instance, children)
//根据 isStateful 来创建有状态的组件
const setupResult = isStateful
? setupStatefulComponent(instance, isSSR)
: undefined
isInSSRComponentSetup = false
// 并返回结果
return setupResult
}
function setupStatefulComponent(
instance: ComponentInternalInstance,
isSSR: boolean
)
{
//渲染代理的属性访问缓存
instance.accessCache = Object.create(null)
instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers)
const { setup } = Component
if (setup) {
const setupContext = (instance.setupContext =
setup.length > 1 ? createSetupContext(instance) : null)
currentInstance = instance
pauseTracking()
resetTracking()
currentInstance = null
//...
//处理 setup 结果
handleSetupResult(instance, setupResult, isSSR)
} else {
//完成组件 设置
finishComponentSetup(instance, isSSR)
}
}
原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34629.html