# 组件更新过程
// 组件更新
updateComponent = () => {
// vm._render返回的就是一个Vnode
vm._update(vm._render(), hydrating)
}
1
2
3
4
5
2
3
4
5
// 新老vnode的patch过程,patch后找出差异,映射到真实的dom操作上
Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
const vm: Component = this
const prevEl = vm.$el
const prevVnode = vm._vnode
const restoreActiveInstance = setActiveInstance(vm)
vm._vnode = vnode
if (!prevVnode) {
// initial render
vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)
} else {
// updates
vm.$el = vm.__patch__(prevVnode, vnode)
}
restoreActiveInstance()
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
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
我想大家应该都知道虚拟dom,虚拟dom就是一个js对象,上边是vue中的两个源码片段,展示组件的更新过程,组件视图的更新就是靠调用_render
返回一个新的vnode,然后通过新老vnode的patch
找出差异,映射到真实的dom操作上。那这个_render
函数又是怎么实现的呢,我们看下面这个源码片段
Vue.prototype._render = function (): VNode {
const vm: Component = this
const { render, _parentVnode } = vm.$options
if (_parentVnode) {
vm.$scopedSlots = normalizeScopedSlots(
_parentVnode.data.scopedSlots,
vm.$slots,
vm.$scopedSlots
)
}
vm.$vnode = _parentVnode
// render self
let vnode
try {
currentRenderingInstance = vm
// 这里这个vm.$createElement就是我们写render函数的参数,这个vm.$createElement会在createElement的实现过程这一节讲
vnode = render.call(vm._renderProxy, vm.$createElement)
} catch (e) {
handleError(e, vm, `render`)
vnode = vm._vnode
} finally {
currentRenderingInstance = null
}
if (Array.isArray(vnode) && vnode.length === 1) {
vnode = vnode[0]
}
// return empty vnode in case the render function errored out
if (!(vnode instanceof VNode)) {
vnode = createEmptyVNode()
}
// set parent
vnode.parent = _parentVnode
return vnode
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40