接上篇:02. 认识 Vue 对象(二)
今天我们一口气,把剩下的 lifecycleMixin(Vue)
和 renderMixin(Vue)
都解决了💪。
lifecycleMixin(Vue)
新增 3 个方法:
Vue.prototype._update
Vue.prototype.$forceUpdate
Vue.prototype.$destroy
✨ _update
这个方法在源码中没有被直接使用,而是被包裹在一个 updateComponent
方法中,作为第二个参数传给 Watcher 实例。
_update
方法的作用就是更新 Vue 实例的虚拟节点 vnode
和关联的 DOM 对象 $el
。在这个方法中有个重要的方法 vm.__patch__
,我们在后面碰到的时候再详细说。
✨ $forceUpdate
该方法是强制 Vue 实例重新渲染,实现方法就是调用 vm._watcher
的 update()
方法。vm._watcher
是 Watcher
的一个实例,update
的方法调用链其实很长,我下面简单写一下
watcher.update -> watcher.run -> watcher.get -> (watcher.getter = _update)
注意啦!这里的 getter
方法引用的就是上面提到的 _update 方法
✨ $destroy
销毁 Vue 实例,包括该实例绑定的一切对象。大概会经历如下过程:
- 调用
beforeDestroy
钩子 - 如果有父对象,则从父对象的
parent.$children
中移除自身 - 关闭存在的 Watcher 监听:
vm._watcher.teardown()
&vm._watchers[i].teardown()
- 关闭存在于 data 上的 Observer 监听:
vm._data.__ob__.vmCount--
- 调用
destroyed
钩子 - 移除实例上的监听:
vm.$off()
上面好些实例上的属性大家可能并不熟悉,别着急,后面看到实例化对象的时候就清楚了。
下面是我们《认识 Vue 对象》的最后一个 Part:renderMixin(Vue)
,赶紧来看看你这个方法都对我们的 Vue 做了些什么:
首先执行了一个 installRenderHelpers(Vue.prototype)
方法,大家不要小看这一行代码,其实里面大有乾坤,大家看下面的源码自行感受下
// target 就是 Vue.prototype
export function installRenderHelpers (target: any) {
target._o = markOnce
target._n = toNumber
target._s = toString
target._l = renderList
target._t = renderSlot
target._q = looseEqual
target._i = looseIndexOf
target._m = renderStatic
target._f = resolveFilter
target._k = checkKeyCodes
target._b = bindObjectProps
target._v = createTextVNode
target._e = createEmptyVNode
target._u = resolveScopedSlots
target._g = bindObjectListeners
}
这个方法给 Vue 对象赋予了一堆方法的短名称,至于这些方法有什么用,我们后面碰到一个再解释一个吧。
然后是新增 2 个常规方法 Vue.prototype.$nextTick
和 Vue.prototype._render
。
✨ $nextTick
这个方法,涉及 JS 的Event Loop 机制:宏观(macro)事件队列和微观(micro)事件队列,先执行微观任务队列,当微观任务队列清空后,再执行宏观任务。
Vue 默认使用 Promise 将该方法传入的回调方法加入微观队列中,在宿主环境不支持 Promise 的情况下,使用宏观队列。
将回调放入微观事件队列的方法有:
- Promise
将回调放入宏观事件队列的方法有:
- setImmediate
- MessageChannel
- setTimeout
✨ _render
这是个很关键的方法,用于 vue 实例的渲染。这个方法也不会被直接调用(我们发现 _
开头的方法一般都不会直接调用),它是在 _update
方法里被调用的(这个方法是不是很熟?往上面翻翻)。这个 _render
方法会执行 vm.$options.render
方法,这个方法可是大有来头,我们后面会看到。