vue源码阅读记录4-VNODE
开始
上篇说道虚拟dom,虚拟dom是vue的一个核心渲染手段,因此VNODE也是一个重要的对象。使用虚拟DOM每次 dom 的更改就变成了js对象的属性的更改,这样一来就能查找 js 对象的属性变化,要比直接改变dom消耗要小的多。那vnode道理是什么东西呢。先看下src/core/vdom/vnode.js
这个文件,这是VNODE的一个类,里面提供了VNODE类和一些方法,比如创建Text的类的方法,克隆Vode的方法,和创建一个空的对象。 以下列出来的就是比较重要的属性,可以通过createElement方法创建虚拟DOM
export default class VNode {
tag: string | void;
data: VNodeData | void;
children: ?Array<VNode>;
text: string | void;
elm: Node | void;
ns: string | void;
context: Component | void; // rendered in this component's scope
key: string | number | void;
componentOptions: VNodeComponentOptions | void;
componentInstance: Component | void; // component instance
parent: VNode | void; // component placeholder node
.....
}
那么生成之后的VNODE如何使用呢,再看下_update这个方法.
Vue.prototype._update = function (vnode, hydrating) {
var vm = this;
var prevEl = vm.$el;
var prevVnode = vm._vnode;
var restoreActiveInstance = setActiveInstance(vm);
vm._vnode = vnode;
// Vue.prototype.__patch__ is injected in entry points
// based on the rendering backend used.
if (!prevVnode) {
// initial render
vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
} else {
// updates
vm.$el = vm.__patch__(prevVnode, vnode);
}
restoreActiveInstance();
// update __vue__ reference
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;
}
// updated hook is called by the scheduler to ensure that children are
// updated in a parent's updated hook.
};
这个方法是lifecycleMixin 的时候绑定的。主要的功能是生成真实的dom,_update
函数在src/core/instance/lifecycle.js
中定义,他的核心就是这个__patch__
方法。而矛头指向了 src/platforms/web/runtime/patch.js
,
export const patch: Function = createPatchFunction({ nodeOps, modules })
该方法的定义是调用 createPatchFunction 方法的返回值,这里传入了一个对象,包含 nodeOps 参数和 modules 参数。其中,nodeOps 封装了一系列 DOM 操作的方法,modules 定义了一些模块的钩子函数的实现。