Vue第一次渲染源码会在初始化结束时调用$mount挂载页面Vue.prototype._init=function(options?:Object){...if(vm.$options.el){//Mountpagevm.$mount(vm.$options.el)}}如果是带编译器的版本,会跳转到$mount的重写方法,将模板编译成render函数的操作比较多。详见//#platforms/web/entry-runtime-with-compiler.jsVue.prototype.$mount=function(){...//调用web/runtime/index.js下定义的$mount方法returnmount.call(this,el,hydrating)}最初定义的$mount方法处理了el并调用了mountComponent//#platforms/web/runtime/index.jsVue.prototype.$mount=function(el?:string|Element,hydrating?:boolean):Component{//为什么要&&这里?//如果有编译器版本,$mount方法会被重写。此时el已经在重写的方法中进行了初始化。//如果没有编译版本,在浏览器环境下,需要将el转换为dom,得到dom.innerHTML作为模板el=el&&inBrowser?query(el):undefinedreturnmountComponent(this,el,hydrating)}mountComponent方法定义在core/instance/lifecycle.jsmountComponent方法分析首先判断开发模式是否没有render功能,使用runtime版本,template模板会报错然后执行callHook(vm,'beforeMount')hook然后定义updateComponent方法,挂载操作的方法,(这个方法只定义不执行)updateComponent=()=>{//_render调用用户传入的render或者编译器生成的render,返回VNode虚拟dom//_update将虚拟dom转为真实domvm._update(vm._render(),hydrating)}在Watcher实例中调用updateComponent方法newWatcher(vm,updateComponent,noop,{before(){if(vm._isMounted&&!vm._isDestroyed){callHook(vm,'beforeUpdate')}}},true/*isRenderWatcher*/)最后执行callHook(vm,"mounted")hookWatcher类分析core/observer/watcher.js源码写的Watcher类watcher类会调用renderingwatcher(current)三次,计算属性watcherWatcher类中定义了watcher、listener等很多属性,lazy属性true用于计算属性watcher...get(){//每个组件对应一个watcher//如果组件嵌套,先渲染内部组件,需要保存父组件watcherpushTarget(this)//这里的getter是传入updataComponentvalue=this.getter.call(vm,vm)}...updateComponent解析core/instance/lifecycle.js下的这个方法(之前注册过),第一次渲染后执行updateComponent=()=>{//这是一个回调,wather会调用//_render或获取虚拟dom_update将虚拟dom转换为真实domvm._update(vm._render(),hydrating)}
