var mount = Vue.prototype.$mount; Vue.prototype.$mount = function (el,hydrating) { el = el && query(el);
/* ... */
var options = this.$options; // resolve template/el and convert to render function if (!options.render) { var template = options.template; /* ... */ if (template) { /* istanbul ignore if */ if (config.performance && mark) { mark('compile'); }
var ref = compileToFunctions(template, { shouldDecodeNewlines: shouldDecodeNewlines, shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref, delimiters: options.delimiters, comments: options.comments }, this); var render = ref.render; var staticRenderFns = ref.staticRenderFns; options.render = render; options.staticRenderFns = staticRenderFns; /* ... */ } } return mount.call(this, el, hydrating) };
// public mount method Vue.prototype.$mount = function ( el, hydrating ) { el = el && inBrowser ? query(el) : undefined; returnmountComponent(this, el, hydrating) }; // 挂载模板 functionmountComponent (vm,el,hydrating) { vm.$el = el; if (!vm.$options.render) { vm.$options.render = createEmptyVNode; } // 调用挂载前函数 callHook(vm, 'beforeMount');
var updateComponent; /* istanbul ignore if */ if (config.performance && mark) { updateComponent = function () { var name = vm._name; var id = vm._uid; var startTag = "vue-perf-start:" + id; var endTag = "vue-perf-end:" + id;
mark(startTag); var vnode = vm._render(); mark(endTag); measure(("vue " + name + " render"), startTag, endTag);
// 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 newWatcher(vm, updateComponent, noop, { before: functionbefore () { 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; // 调用dom挂载完之后函数 callHook(vm, 'mounted'); } return vm }
对上面代码排除一些if判断和警告,剩下主要的代码就以下几行:
1 2 3 4 5 6 7 8 9 10 11 12 13
...... updateComponent = function () { vm._update(vm._render(), hydrating); }; ...... new Watcher(vm, updateComponent, noop, { before: function before () { if (vm._isMounted && !vm._isDestroyed) { callHook(vm, 'beforeUpdate'); } } }, true /* isRenderWatcher */);
Vue.prototype._render = function () { var vm = this; var ref = vm.$options; var render = ref.render; var _parentVnode = ref._parentVnode;
if (_parentVnode) { vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject; }
// set parent vnode. this allows render functions to have access // to the data on the placeholder node. vm.$vnode = _parentVnode; // render self var vnode= render.call(vm._renderProxy, vm.$createElement); /* .... */ // set parent vnode.parent = _parentVnode; return vnode }; }
Vue.prototype._update = function (vnode, hydrating) { var vm = this; var prevEl = vm.$el; var prevVnode = vm._vnode; var restoreActiveInstance = setActiveInstance(vm); vm._vnode = vnode; // Vue.prototype.__patch__ is injected in entry points // based on the rendering backend used. if (!prevVnode) { // initial render vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false/* removeOnly */); } else { // updates vm.$el = vm.__patch__(prevVnode, vnode); } restoreActiveInstance(); // update __vue__ reference if (prevEl) { prevEl.__vue__ = null; } if (vm.$el) { vm.$el.__vue__ = vm; } // if parent is an HOC, update its $el as well if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { vm.$parent.$el = vm.$el; } // updated hook is called by the scheduler to ensure that children are // updated in a parent's updated hook. };