functionVue (options) { if (process.env.NODE_ENV !== 'production' && !(thisinstanceofVue) ) { warn('Vue is a constructor and should be called with the `new` keyword') } this._init(options) }
var mount = Vue.prototype.$mount; Vue.prototype.$mount = function (el, hydrating) { el = el && query(el); /* istanbul ignore if */ if (el === document.body || el === document.documentElement) { // 不能挂载到html/body warn("Do not mount Vue to <html> or <body> - mount to normal elements instead."); returnthis } var options = this.$options; // resolve template/el and convert to render function if (!options.render) { // render是已经编译好的渲染方法,如果没有渲染方法,则需要获取用户传入的模板内容将模板字符串转化为渲染方法 var template = options.template; if (template) { if (typeof template === 'string') { if (template.charAt(0) === '#') { template = idToTemplate(template); /* istanbul ignore if */ if ( !template) { warn(("Template element not found or is empty: " + (options.template)), this); } } } elseif (template.nodeType) { template = template.innerHTML; } else { { warn('invalid template option:' + template, this); } returnthis } } elseif (el) { template = getOuterHTML(el); } if (template) { /* istanbul ignore if */ if ( config.performance && mark) { mark('compile'); } var ref = compileToFunctions(template, { outputSourceRange: "development" !== 'production', 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; /* istanbul ignore if */ if ( config.performance && mark) { // 性能监控 mark('compile end'); measure(("vue " + (this._name) + " compile"), 'compile', 'compile end'); } } } return mount.call(this, el, hydrating) };
// src\core\instance\lifecycle.js functionmountComponent (vm, el, hydrating) { vm.$el = el; if (!vm.$options.render) { vm.$options.render = createEmptyVNode; // 创建默认的渲染函数 { /* 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'); 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); mark(startTag); vm._update(vnode, hydrating); mark(endTag); measure(("vue " + name + " patch"), startTag, endTag); }; } else { updateComponent = function () { vm._update(vm._render(), hydrating); // _render是对VNODE的一些处理 }; } newWatcher(vm, updateComponent, noop, { before: functionbefore () { if (vm._isMounted && !vm._isDestroyed) { callHook(vm, 'beforeUpdate'); } } }, true/* isRenderWatcher */); hydrating = false; if (vm.$vnode == null) { vm._isMounted = true; callHook(vm, 'mounted'); } return vm }
1 2 3 4 5 6 7 8 9 10 11
// src\core\observer\scheduler.js functioncallUpdatedHooks (queue) { var i = queue.length; while (i--) { var watcher = queue[i]; var vm = watcher.vm; if (vm._watcher === watcher && vm._isMounted && !vm._isDestroyed) { callHook(vm, 'updated'); } } }
Vue.prototype.$destroy = function () { var vm = this; if (vm._isBeingDestroyed) { return } callHook(vm, 'beforeDestroy'); vm._isBeingDestroyed = true; // remove self from parent var parent = vm.$parent; if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) { remove(parent.$children, vm); } // teardown watchers if (vm._watcher) { vm._watcher.teardown(); } var i = vm._watchers.length; while (i--) { vm._watchers[i].teardown(); } // remove reference from data ob // frozen object may not have observer. if (vm._data.__ob__) { vm._data.__ob__.vmCount--; } // call the last hook... vm._isDestroyed = true; // invoke destroy hooks on current rendered tree vm.__patch__(vm._vnode, null); // fire destroyed hook callHook(vm, 'destroyed'); // turn off all instance listeners. vm.$off(); // remove __vue__ reference if (vm.$el) { vm.$el.__vue__ = null; } // release circular reference (#6759) if (vm.$vnode) { vm.$vnode.parent = null; } };