function mountComponent (
vm,
el,
hydrating
) {
vm.$el = el;
if (!vm.$options.render) {
vm.$options.render = createEmptyVNode;
}
callHook(vm, 'beforeMount');
var updateComponent;
if (config.performance && mark) {
updateComponent = function () {
var vnode = vm._render(); // 执行render函数获得vnode,如果是模板语法,vue内部也会通过模板编译来将其转换成render函数
vm._update(vnode, hydrating); // vm._update函数内部其实也是通过patch来进行比对新旧vnode,从而进行更新
};
} else {
updateComponent = function () {
vm._update(vm._render(), hydrating);
};
}
// 每个vue组件都有对应的一个watcher对象
// 重点在这个实例化Watcher语句,参数传递了vm和updateComponent
new Watcher(vm, updateComponent, noop, {
before: function before () {
if (vm._isMounted && !vm._isDestroyed) {
callHook(vm, 'beforeUpdate');
}
}
}, true /* isRenderWatcher */);
// ...
return vm
}
也就是说,在初始化vue组件的watcher时,首先会将Dep.target指向watcher自身,然后执行一次vm.render进行渲染,同时也是让组件render引用的状态来收集watcher自身。