You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Vue.prototype._render=function(): VNode{constvm: Component=thisconst{ render, _parentVnode }=vm.$options// set parent vnode. this allows render functions to have access// to the data on the placeholder node.vm.$vnode=_parentVnode// render selfletvnodetry{vnode=render.call(vm._renderProxy,vm.$createElement)}catch(e){// 省略vnode=vm._vnode}// set parentvnode.parent=_parentVnodereturnvnode}
Vue.prototype._update=function(vnode: VNode,hydrating?: boolean){constvm: Component=thisconstprevEl=vm.$elconstprevVnode=vm._vnodeconstprevActiveInstance=activeInstanceactiveInstance=vmvm._vnode=vnode// Vue.prototype.__patch__ is injected in entry points// based on the rendering backend used.if(!prevVnode){// initial rendervm.$el=vm.__patch__(vm.$el,vnode,hydrating,false/* removeOnly */)}else{// updatesvm.$el=vm.__patch__(prevVnode,vnode)}// 省略}
回顾$mount 之前发生了什么
借用 Vue 官方这张经典的图来说明:
然我们回顾下在我们调用
$mount
挂载组件之前都发生了什么?,如上图所示,主要发生了这么些事情:initMixin
,stateMixin
等各种xxxxMixin
在Vue.prototype
上添加属性和方法,这在图中是没有显示的,因为这不是组件的生命周期,而是类的创建。new Vue()
开始构建Vue实例,组件的生命周期在这里开始。_init
函数中做mergeOptions
合并配置,其中包括一些由Vue提供的默认配置比如directives
等。图中并没有显示这一块beforeCreate
阶段,还是在_init
函数中, 做events
,lifecycle
等初始化create
阶段,做数据响应和数据注入。template
编译为render
函数,到这里就完成了mount
的准备工作。在
_init
结束之后,会调用$mount
挂载组件,进入一个新的阶段mount
阶段。那么,从$mount
函数开始,到生成真实DOM,中间经历了哪些步骤呢?Mount 开始
首先我们看
$mount
函数的定义:platforms/web/runtime/index.js
可以看到它主要是调用了
mountComponent
函数,这个函数我们在之前讲到过,他会创建一个Watcher
来监听vm
的变动,一旦发生任何变化都会调用vm._update
更新组件。mountComponent
核心的代码如下所示:core/instance/lifecycle.js
由于这里
lazy === false
所以在创建watcher
的时候会立刻进行一次求值,也就是调用vm._update(vm._render(), hydrating)
方法更新组件。这里的第一个参数是vm._update
的结果,因此我们先看看这个函数做了什么:core/instance/render.js
上面的代码经过了我的简化。我们可以看到,
_render
函数主要作用就是调用了_renderProxy
生成vnode
,并返回,而_renderProxy
其实就是调用了我们编译好的render
函数。所以我们知道了,每当组件有任何更新的时候,都会调用render
函数生成新的vnode
。那么我们再看updateComponent
函数,当组件更新的时候就变成了这样:因为我们更新了
vnode
,这个_update
函数的目的显然是会进行patch
,把更新同步到真实的DOM
上。来看看_update
函数的代码:core/instance/lifecycle.js
正如我们所料,
_update
函数主要做的事情就是调用了__patch__
方法。__patch__
方法会负责把vnode
渲染为真实的 DOM.我画了一个图,来表示整个$mount
以及update
的过程:$mount
函数其实是创建了上面这个流程,而不是发起了一次 渲染,因为在创建watcher的时候lazy === false
所以创建完成之后立刻会触发一次更新。图中的两个重要阶段
render
和patch
我们分别在接下来的两章详细讲解。下一章,让我们看看
render
函数是如何生成vnode
的。下一章:Vue2.x源码解析系列九:vnode的生成与更新机制
The text was updated successfully, but these errors were encountered: