What exactly does vue.CreateApp do?
When you call Vue.CreateApp you actually come to the following function
export const createApp = ((. args) = > {
// Call the ensureRenderer function first to ensure that there is a renderer
// final ensureRenderer() returns the object below
/** * {render, hydrate, createApp: createAppAPI(render, hydrate)} Calling createApp above is actually the return value of calling createAPI */
constapp = ensureRenderer().createApp(... args)// Destruct the mount method of the app object
const { mount } = app
// Override the mount method of app
// Call the above mount method in app.mount method
app.mount = () = > {
// ...
}
return app
})
Copy the code
EnsureRenderer function
// The renderer is deferred so that when the user does not use the renderer (for example, when the user only uses reactive modules), the renderer can be tree-shaking off
let renderer
function ensureRenderer() {
// If the renderer returns directly, if it does not, createRenderer is called and the value returned by createRenderer is saved to the renderer
return (
renderer ||
(renderer = createRenderer(rendererOptions))
)
}
Copy the code
CreateRenderer function
export function createRenderer(options) {
// createRenderer calls baseCreateRenderer
return baseCreateRenderer(options)
}
Copy the code
BaseCreateRenderer function
function baseCreateRenderer(options, createHydrationFns){
// Because the function is too long (more than 2000 lines), here is a direct display of the return value of the function and the value used by the return value
/ / render function
const render = (vnode, container, isSVG) = > {
if (vnode == null) {
if (container._vnode) {
unmount(container._vnode, null.null.true)}}else {
patch(container._vnode || null, vnode, container, null.null.null, isSVG)
}
flushPostFlushCbs()
container._vnode = vnode
}
// ...
return {
render,
hydrate,
// Here we pass the render function as an argument using currie
// Call the render function of domo, which is used by the function return function,
// We can also implement our own render function and pass it in so that we can use our own render function to make it more customizable
createApp: createAppAPI(render, hydrate)
}
}
Copy the code
CreateAppAPI function
export function createAppAPI(render, hydrate) {
The createApp property in the object returned by baseCreateRenderer is actually this function
return function createApp(rootComponent, rootProps = null) {
if(rootProps ! =null && !isObject(rootProps)) {
/ / processing props
}
// Create the app context and add it to the _context property of the app
const context = createAppContext()
const installedPlugins = new Set(a)// Create a variable to record whether it has been mounted
let isMounted = false
// Add the app property to the context to point to the app object, that is, the context and app refer to each other
const app = (context.app = {
_uid: uid++,
_component: rootComponent,
_props: rootProps,
_container: null._context: context,
_instance: null,
version,
get config() {
return context.config
},
set config(v) {
// ...
},
use(plugin, ... options) {
// ...
return app
},
mixin(mixin) {
// ...
return app
},
component(name, component) {
// ...
return app
},
directive(name, directive) {
// ...
return app
},
mount(rootContainer, isHydrate, isSVG) {
// ...
},
unmount() {
// ...
},
provide(key, value) {
// ...
return app
}
})
return app
}
}
Copy the code
conclusion
- Levue. CreateApp is called first with the ensureRenderer function that ensures there is a renderer.
- If one is not available, the createRenderer function is called to create a renderer.
- The baseCreateRenderer function is called inside the createRenderer function, which actually creates the renderer. This function returns a renderer object with the render function and createApp function.
- Once you have the renderer object, you start calling the createApp function on the renderer object, which is the function that actually creates the app object.
- The createApp function on the renderer object creates the app object and adds the use, mount, mixin, Component, directive, unmount, provide methods to the object. It also creates an app context that references the app object. It also creates an isMounted variable that records whether the app has been mounted.