Vue3.0 - 01 - 01

163 阅读1分钟

初始化渲染


import { createApp } from 'vue'

import App from './App.vue'

createApp(App).mount('#app')

createApp


export const createApp = ((...args) => {

    // 初始化 app 对象

    const app = ensureRenderer().createApp(...args)

    if (__DEV__) {

    // 检查是否原生标签

    injectNativeTagCheck(app)

    // 检查是否自定义标签

    injectCompilerOptionsCheck(app)

    }

    // ...

    return app

}) as CreateAppFunction<Element>

从上面代码中可以看到 app 对象是通过 ensureRenderer 函数返回的 createApp 函数执行得出。


function ensureRenderer() {

    return (

    renderer || (renderer = createRenderer<Node, Element | ShadowRoot>(rendererOptions))

    )

}

rendererOptions 对象主要封装了对原生 DOM 对象操作的相关 API,比如:setAttributeinsertBeforecreateElement 等。将其作为参数传入 createRenderer 函数中。


export function createRenderer<

HostNode = RendererNode,

HostElement = RendererElement

>(options: RendererOptions<HostNode, HostElement>) {

    // 实质上是执行 baseCreateRenderer 函数

    // 入参 options 为 rendererOptions 对象

    return baseCreateRenderer<HostNode, HostElement>(options)

}


function baseCreateRenderer(

options: RendererOptions,

createHydrationFns?: typeof createHydrationFunctions

) {

    const {

    insert: hostInsert,

    remove: hostRemove,

    // ...

    cloneNode: hostCloneNode,

    insertStaticContent: hostInsertStaticContent

    } = options

    // ...

    return {

        // 渲染函数

        render,

        // SSR

        hydrate,

        // creteApp 本体

        createApp: createAppAPI(render, hydrate)

    }

}

createApp 即为 createAppAPI(render, hydrate) 返回的函数。baseCreateRenderer 函数本身就是一个大闭包,并且采用函数柯里化,很好的将方法、对象进行了私有化和缓存。

回到上面说的 const app = ensureRenderer().createApp(...args) 这换代码,实际等价于 createAppAPI(render, hydrate)(...args)


export function createAppAPI<HostElement>(

render: RootRenderFunction,

hydrate?: RootHydrateFunction

): CreateAppFunction<HostElement> {

    return function createApp(rootComponent, rootProps = null) {

    // ...

    const context = createAppContext()

    // ...

    const app: App = (context.app = {

        _uid: uid++,

        _component: rootComponent as ConcreteComponent,

        _props: rootProps,

        _container: null,

        _context: context,

        _instance: null,

        version,

        get config() {/* ... */},

        set config(v) {/* ... */},

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

        mixin(mixin: ComponentOptions) {/* ... */},

        component(name: string, component?: Component): any {/* ... */},

        mount(

        rootContainer: HostElement,

        isHydrate?: boolean,

        isSVG?: boolean

        ): any {/* ... */},

        unmount() {/* ... */},

        provide(key, value) {/* ... */}
    })

    // ...

    // app 对象本体
    return app

}

从上面的代码中可以看得出执行 const app = ensureRenderer().createApp(...args) 后,返回的 app 对象的具体属性及方法