Vue instance mounted implement (six)

We Vue by  $mount example of a method to mount  vm , the $mount method has the definition as in multiple files  src/platform/web/entry-runtime-with-compiler.js, src/platform/web/runtime/index.js, src/platform/weex/runtime/index.js. Because the  $mount implementation of this method is and platforms, building methods are related. Next, we focus on analysis with a  compiler version of  $mount realization, because aside webpack of vue-loader, front-end pure principles of our work environment analysis Vue browser, helps to further our understanding of the principles.

compiler Version  $mount to achieve a very interesting first look at the  src/platform/web/entry-runtime-with-compiler.js file definition:

const mount = Vue.prototype.$mount
Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean ): Component { el = el && query(el) /* istanbul ignore if */ if (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 } const options = this.$options // resolve template/el and convert to render function if (!options.render) { let template = options.template if (template) { if (typeof template === 'string') { if (template.charAt(0) === '#') { template = idToTemplate(template) /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && !template) { warn( `Template element not found or is empty: ${options.template}`, this ) } } } else if (template.nodeType) { template = template.innerHTML } else { if (process.env.NODE_ENV !== 'production') { warn('invalid template option:' + template, this) } return this } } else if (el) { template = getOuterHTML(el) } if (template) { /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && config.performance && mark) { mark('compile') } const { render, staticRenderFns } = compileToFunctions(template, { shouldDecodeNewlines, shouldDecodeNewlinesForHref, delimiters: options.delimiters, comments: options.comments }, this) options.render = render options.staticRenderFns = staticRenderFns /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && config.performance && mark) { mark('compile end') measure(`vue ${this._name} compile`, 'compile', 'compile end') } } } return mount.call(this, el, hydrating) } 

The code first cached on the prototype  $mount method, and then redefine this method, we first analyze the code. First, it  el did limit, Vue can not mount  body, html such a root node. The following logic is critical - if not defined  render method, will be to  el or  template string into  render a method. Here we have to bear in mind Vue version 2.0, rendering all the components of the Vue eventually require  render method, whether we are single file .vue way to develop components, or write  el or  template property, will eventually be converted to a  render method, then the process is a Vue "on-line compilation" process, which is to call the  compileToFunctions method to achieve, then we will introduce the compilation process. Finally, call the original prototype  $mount method to mount.

On the original prototype  $mount method  src/platform/web/runtime/index.js is defined, the reason for such a design is entirely for reuse, because it can be  runtime only used directly versions of Vue.

// public mount method
Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean ): Component { el = el && inBrowser ? query(el) : undefined return mountComponent(this, el, hydrating) } 

$mount Methods support incoming two parameters, the first is  elthat it represents a mounted element, can be a string, it can also be a DOM object, if the string is invoked in a browser environment  query method of converting into a DOM object. The second parameter is the rendering and server-related, in the browser environment, we do not need to pass the second parameter.

$mount The method actually to call  mountComponent method, which is defined in the  src/core/instance/lifecycle.js file:

export function mountComponent (
  vm: Component, el: ?Element, hydrating?: boolean ): Component { vm.$el = el if (!vm.$options.render) { vm.$options.render = createEmptyVNode if (process.env.NODE_ENV !== 'production') { /* istanbul ignore if */ if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') || 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.', vm ) } } } callHook(vm, 'beforeMount') let updateComponent /* istanbul ignore if */ 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's mounted hook), which relies on vm._watcher being already defined new Watcher(vm, updateComponent, noop, { before () { if (vm._isMounted) { 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 } 

You can see from the above code, mountComponent the core is the first example of a rendering Watcher, in its callback function calls the  updateComponent method, called this method  vm._render Xiansheng method as virtual Node, the final call to  vm._update update the DOM.

Watcher Here it serves two purposes, one is to initialize the callback function will execute when the other is when the monitored data vm instances of changes callback function, we'll introduce this child in later chapters.

The last function is determined when the root node set  vm._isMounted to  trueindicate that the example has been mounted, while performing  mounted hook function. Note here that  vm.$vnode represents the parent virtual instance Vue Node, it is  Null said that the current instance is the root of Vue.

to sum up

mountComponent The logical approach is very clear, it will complete the rendering work, then we have to focus on the details of the analysis, which is the core of two methods: vm._render and  vm._update.

 

 

----------------- switched network vue Source Mu class parses content of the video tutorial -----------------

Guess you like

Origin www.cnblogs.com/bobo1/p/11351722.html