Vue3源码学习01createApp

103 阅读1分钟
版本 3.4.24
 Vue.createApp({ }).mount('#app')

createApp都执行了什么?

runtime-dom 目录下runtime-dom/src/index.ts调用createApp

image.png

createApp


export const createApp = ((...args) => {
  const app = ensureRenderer().createApp(...args)
 ...
  const { mount } = app
  //这里重写了mount函数
  app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {
   ...
  }
  return app
}) as CreateAppFunction<Element>
  1. 调用ensureRenderer 中返回createApp,

2.在baseCreateRenderer中(ensureRenderer=>createRenderer=>在baseCreateRenderer) 创建一个渲染器 ,最终返回一个对象,包含createApp

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

调用createApp实际上是执行createAppAPIcreateAppAPI返回一个函数,createApp工厂函数,返回app实例


export function createAppAPI<HostElement>(
  render: RootRenderFunction<HostElement>,
  hydrate?: RootHydrateFunction,
): CreateAppFunction<HostElement> {
  return function createApp(rootComponent, rootProps = null) {
    if (!isFunction(rootComponent)) {
      rootComponent = extend({}, rootComponent)
    }
...

    const context = createAppContext()
    const installedPlugins = new WeakSet()

    let isMounted = false

    const app: App = (context.app = {
      _uid: uid++,
      _component: rootComponent as ConcreteComponent,
      _props: rootProps,
      _container: null,
      _context: context,
      _instance: null,

      version,

      get config() {
        return context.config
      },

      set config(v) {
   
      },

      use(plugin: Plugin, ...options: any[]) {

      },

      mixin(mixin: ComponentOptions) {

      },

      component(name: string, component?: Component): any {

      },

      directive(name: string, directive?: Directive) {

      },

      mount(
        rootContainer: HostElement,
        isHydrate?: boolean,
        namespace?: boolean | ElementNamespace,
      ): any {
       
      },

      unmount() {
   
      },

      provide(key, value) {

      },

      runWithContext(fn) {
     
      },
    })



    return app
  }
}

调用app实例上的mount方法,createApp中对app实例上的mount方法重写 在 app实例的mount方法中,创建vnode const vnode = createVNode(rootComponent, rootProps),在vnode上保存上下文vnode.appContext = context 区分是服务端渲染还是客户端渲染


          if (isHydrate && hydrate) {
            hydrate(vnode as VNode<Node, Element>, rootContainer as any)
          } else {
            render(vnode, rootContainer, namespace)
          }

这里调用render方法,将vnode渲染成真实的dom,渲染到页面;

createApp实际上是创建基础渲染器,调用渲染器createApp方法,生成app实例对象,调用并重写mount方法