Vue之Watcher源码解析(2)

2020-06-13 10:14:43易采站长站整理

接着上节Vue Watcher源码的话,继续探讨,目前是这么个过程:

函数大概是这里:


// line-3846
Vue.prototype._render = function() {

// 获取参数

try {
// 死在这儿
vnode = render.call(vm._renderProxy, vm.$createElement);
} catch (e) {
// 报render错误
}
// return empty vnode in case the render function errored out
if (!(vnode instanceof VNode)) {
// 返回空节点
}
// set parent
vnode.parent = _parentVnode;
return vnode
};

然后,在上个月,我卡死在了render.call这个函数上面,因为所有vue实例被设置了proxy代理,所以会跳转到各种奇怪的检测函数中。

过了一个月,我依然看不懂,一点都不想讲,所以先跳过,直接看后面!

这里假设vnode已经返回了,来看看是个啥:

这是一个虚拟节点,由之前字符串化后的DOM树生成,主要包含子节点、上下文、属性、文本、标签名、类型等属性,这些可以直接从键名判断。

得到vnode后,由于这里是根节点,所以不存在_parentVnode,直接返回。

然后到了mountComponent函数:


// line-2374
function mountComponent(vm, el, hydrating) {
vm.$el = el;
// error
callHook(vm, 'beforeMount');

var updateComponent;
/* istanbul ignore if */
if ("development" !== 'production' && config.performance && mark) {
updateComponent = function() {
// 开发者模式下的处理方式
};
} else {
// 重新进入这里
updateComponent = function() {
vm._update(vm._render(), hydrating);
};
}

vm._watcher = new Watcher(vm, updateComponent, noop);
hydrating = false;

// manually mounted instance, call mounted on self
// mounted is called for render-created child components in its inserted hook
if (vm.$vnode == null) {
vm._isMounted = true;
callHook(vm, 'mounted');
}
return vm
}

这样,就带着返回的vode进入了_update函数,开始正式渲染页面。

函数如下:


// line-2374
Vue.prototype._update = function(vnode, hydrating) {
var vm = this;
if (vm._isMounted) {
callHook(vm, 'beforeUpdate');
}
// 保存原属性
var prevEl = vm.$el;
var prevVnode = vm._vnode;
var prevActiveInstance = activeInstance;