$mount function execution location
The _init private method is bound to the Vue prototype when initMixin is executed.
How to mount a component to a specified element
The $mount function defines the position
The $mount function defines two positions:
The first is in the SRC/platforms/web/runtime/index. Js
$mount is a public mount method. This is because there are many builds of Vue, some of which rely on this method for some customization, which will be explained later.
// Public mount method // el: can be a string or Dom element // Hydrating is the Virtual Dom patch algorithm parameter vue.prototype.$mount = function( el? : string | Element, hydrating? : Boolean): Component {// determine the EL, as well as the host environment, and then override the EL using the query utility function. el = el &&inBrowser ? Query (el) : undefined // Performs the actual mount and returnsreturn mountComponent(this, el, hydrating)
}
Copy the code
SRC/platforms/web/runtime/index. The js file is the runtime version of the entrance to the Vue file, so this method is a runtime version Vue $mount of execution.
For details about the different builds of Vue, see Vue’s explanation of the different builds.
You can also learn about the query function encapsulated by the author:
/**
* Query an element selector if it's not an element already. */ export function query (el: string | Element): Element { if (typeof el === 'string') { const selected = document.querySelector(el) if (! Process.env.node_env! = = 'production' && warn( 'Cannot find element: Return document.createElement(' + el) // Error tolerance if not founddiv') } return selected } else { return el } }Copy the code
The second place to define the $mount function is in the SRC /platforms/web/entry-runtime-with-compiler.js file, which is the entry file for the full Vue(runtime + compiler).
Runtime + Compiler vs. Compiler Only the runtime is included.
// Cache run-time defined public$mountConst mount = vue.prototype.$mount
Vue.prototype.$mount = function( el? : string | Element, hydrating? : Boolean): Component {// Override EL (mount point: Component mount) el = el && query(el) /* Istanbul ignoreif* / / / tip can't put the body/HTML as a mount point, the development environment is given error / / because the mount point will be replaced by component template itself, obviously the body/HTML can not be replacedif(el === document.body || el === document.documentElement) { process.env.NODE_ENV ! = ='production' && warn(
`Do not mount Vue to <html> or <body> - mount to normal elements instead.`
)
return this
}
// $optionsNew Vue(options) is executed inside the _init method$optionsYou can access all properties of options such as data, Filter, Components, and directives const options = this.$options
// resolve template/el and convert to render function// If the render function is included, the execution jumps out and directly executes the runtime version$mountmethodsif(! Options. Render) {// The template property is preferred when there is no render functionlet template = options.template
if(template) {// Template exists and the type of template is stringif (typeof template === 'string') {
if (template.charAt(0) === The '#') {// template is ID template = idToTemplate(template) /* Istanbul ignoreif* /if(process.env.NODE_ENV ! = ='production' && !template) {
warn(
`Template element not found or is empty: ${options.template}`,
this
)
}
}
} else if(template.nodetype) {// If the template type is an element node, use the innerHTML of that element as the template template = template.innerHTML}else{// If template is neither a string nor an element node, the development environment will prompt the developer that the template option passed is invalidif(process.env.NODE_ENV ! = ='production') {
warn('invalid template option:' + template, this)
}
return this
}
} else if(el) {// If the template option does not exist, then use the outerHTML of the EL element as the template content. Template = getOuterHTML(el)if (template) {
/* istanbul ignore if* /if(process.env.NODE_ENV ! = ='production' && config.performance && mark) {
mark('compile'} // Get the converted render function with staticRenderFns and hang on$optionsConst {render, staticRenderFns} = compileToFunctions(template, {outputSourceRange: process.env.node_env! = ='production',
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)
options.render = render
options.staticRenderFns = staticRenderFns
/* istanbul ignore if*/ // use this to measure compiler performance. Config is a global configuration objectif(process.env.NODE_ENV ! = ='production' && config.performance && mark) {
mark('compile end')
measure(`vue ${this._name} compile`, 'compile'.'compile end'}}} // call the public mount method // override$mountMethod is used to add functionality for template compilationreturn mount.call(this, el, hydrating)
}
Copy the code
About the idToTemplate method: Get the ID from the QUERY to get the DOM and use the innerHTML of the element as the template
const idToTemplate = cached(id => {
const el = query(id)
return el && el.innerHTML
})
Copy the code
GetOuterHTML method:
/**
* Get outerHTML of elements, taking care
* of SVG elements in IE as well.
*/
function getOuterHTML (el: Element): string {
if (el.outerHTML) {
return el.outerHTML
} elseConst Container = document.createElement() const container = document.createElement() const Container = document.createElement();'div')
container.appendChild(el.cloneNode(true))
return container.innerHTML
}
}
Copy the code
For compileToFunctions, see SRC /platforms/web/entry- Runtime -with-compiler.js that will be mounted to Vue as a global method.
The mountComponent method: actually executes the bound component
MountComponent function is in the SRC/core/instance/lifecycle. Js.
export functionMountComponent (VM: Component, // vm EL:? Element, // mount point hydrating? : Boolean): Component {// Add to the Component instance object$elAttributes / /$elThe value of is the reference VM for the root element of the component template.$el = el
if(! vm.$options.render) {// The render function does not exist, an empty VNode object VM will be created.$options.render = createEmptyVNode
if(process.env.NODE_ENV ! = ='production') {
/* istanbul ignore if* /if ((vm.$options.template && vm.$options.template.charAt(0) ! = =The '#') ||
vm.$options.el || el) {
warn(
'You are using the runtime-only build of Vue where the template ' +
'compiler is not available. Either pre-compile the templates into ' +
'render functions, or use the compiler-included build.',
vm
)
} else {
warn(
'Failed to mount component: template or render function not defined.'}}} // Triggers beforeMount lifecycle hook callHook(VM,'beforeMount'// the function vm._render calls the VM.$optionsRender function and return the generated virtual node (vnode) Template => render => vnode // v._update (); vnode => real dom nodeletUpdateComponent // Renders the virtual DOM generated by the render function to a real DOM /* Istanbul ignoreif* /if(process.env.NODE_ENV ! = ='production' && config.performance && mark) {
updateComponent = () => {
const name = vm._name
const id = vm._uid
const startTag = `vue-perf-start:${id}`
const endTag = `vue-perf-end:${id}`
mark(startTag)
const vnode = vm._render()
mark(endTag)
measure(`vue ${name} render`, startTag, endTag)
mark(startTag)
vm._update(vnode, hydrating)
mark(endTag)
measure(`vue ${name} patch`, startTag, endTag)
}
} else {
updateComponent = () => {
vm._update(vm._render(), hydrating)
}
}
// we set this to vm._watcher inside the watcher's constructor // since the watcher's initial patch may call $forceUpdate (e.g. inside child
// component// Create an observer of the Render function, which relies heavily on the vm._watcher being already defined. New watcher (vm, updateComponent, noop, {before () {if (vm._ismounted &&! vm._isDestroyed) { callHook(vm, 'beforeUpdate') } } }, true /* isRenderWatcher */) hydrating = false // manually mounted instance, call mounted on self // mounted is called for render-created child components in its inserted hook if (vm.$vnode == null) { vm._isMounted = true callHook(vm, 'mounted') } return vm }Copy the code