vue3创建组件的过程探究(createApp(),mount()函数解析)

614 阅读2分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战

vue3创建组件的过程探究

vue3中,我们执行createApp到底发生了什么呢,接下来,我们来一步一步的捋一下。

创建vue实例时,我们经常使用createApp(),然后通过ceateApp函数返回的app对象,来使用mount()来挂载我们的组件。接下来,我们来看一下createApp()和mount()在源码中的执行流程。

createApp

我们使用createApp(),使用的是vue源码中runtime-dom/src/index.ts文件导出的createApp函数。

  1. 调用runtime-dom/src/index.ts中导出的createApp函数。

  2. createApp()中调用ensureRenderer( )

  3. ensureRenderer( )中调用createRenderer( )

  4. createRenderer( )中调用baseCreateRenderer(),baseCreateRenderer返回

    {render, hydrate, createApp: createAppAPI(render, hydrate)}

  5. 最后实际上我们调用的是createAppAPI( )中返回的createApp函数。

  6. 最后执行完createApp以后,返回app对象,app对象中包含mount,use,mixin,component,directive,provide等全局api方法。

执行mount

  1. 执行createApp中的mount()函数

  2. mount中调用baseCreateRenderer返回值中的render()渲染函数。

  3. 如果vnode不为null,则执行patch(),挂载vnode.

  4. patch()中会进行类型判断,在这里我们是一个组件,因此执行processComponent

    1. 是组件则执行processComponent。
    2. 是元素则执行processElement
    3. 是fragement则执行processFragment
  5. 执行processComponent中的mountComponent()

  6. mountComponent() 中先执行createComponentInstance(),创建组件实例,然后执行setupComponent(),初始化组件实例。

  7. 调用设置和渲染有副作用的函数,setupRenderEffect()

  8. setupRenderEffect(),如果没有根元素,则获取到subTree。(subTree是用Fragement包裹的所有元素)

  9. 执行patch函数

  10. 有根元素,则执行processElement().

  11. 如果有n1(旧vnode)为null,则执行mountElement,否则执行patchElement.

  12. mountElement中根据vnode,通过hostCreateElement()创建真实的element.

  13. 如果有子元素,则通过mountChildren()挂载子元素。

  14. 最后通过hostInsert(),将el挂载到container中。

setup初始化实例

  1. 处理props和attrs
  2. 处理slots
  3. 执行setup()
  4. 编译tempalte,将template模板转为render函数。
  5. 对vue2中options API 进行处理。

比较浅的解析vue3中创建组件的流程,后续添加详细的解析。