学习VUE的虚拟DOM(Virtual DOM)
虚拟dom就是用 JS 对象去描述一个 DOM 节点,因为真实的dom非常复杂,有很多用不到的属性。使用用createElement 创建一个div:
var div = document.createElement("div");
var str ="";
for(var key in div){ str += key+"," }
打印结果:
可以看到真实的dom是非常复杂的,而前端开发需要频繁的更新dom,频繁更新dom会产生性能问题。
虚拟dom用js对象描述一个节点,只用了必要的属性去描述节点,vue中使用vnode描述节点,
vnode
https://github.com/vuejs/vue/blob/dev/src/core/vdom/vnode.js
VNode对真实 DOM 进行抽象的描述,它定义了几个关键属性,标签名、数据、子节点、键值等。VNode 只是用来映射到真实 DOM 的渲染,不需要包含操作 DOM 的方法,因此很轻量。映射到真实的 DOM 实际上要经历 VNode 的 create、diff、patch 等过程。
creat
VNode 的 create 是通过 createElement 方法创建的
createElement:https://github.com/vuejs/vue/blob/dev/src/core/vdom/create-element.js
createElement 方法是对 _createElement 进行了一层封装,它对传入的数据进行了初步处理使得可传入的数据更灵活,在处理这些参数后,调用真正创建 VNode 的函数 _createElement
同dom节点一样,vnode可能会有多个子节点,这些子节点也应该是vnode类型,但是_createElement 的children参数是any类型,需要对chidren参数 进行处理,规范为 vnode类型,根据 normalizationType ,调用了 normalizeChildren(children) 和 simpleNormalizeChildren(children) 方法,
对children规范化代码位置:
https://github.com/vuejs/vue/blob/dev/src/core/vdom/helpers/normalize-children.js
接下来回到 createElement
let vnode, ns
if (typeof tag === 'string') {
let Ctor
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
if (config.isReservedTag(tag)) {
// platform built-in elements
if (process.env.NODE_ENV !== 'production' && isDef(data) && isDef(data.nativeOn) && data.tag !== 'component') {
warn(
`The .native modifier for v-on is only valid on components but it was used on <${tag}>.`,
context
)
}
vnode = new VNode(
config.parsePlatformTagName(tag), data, children,
undefined, undefined, context
)
} else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
// component
vnode = createComponent(Ctor, data, context, children, tag)
} else {
// unknown or unlisted namespaced elements
// check at runtime because it may get assigned a namespace when its
// parent normalizes children
vnode = new VNode(
tag, data, children,
undefined, undefined, context
)
}
} else {
// direct component options / constructor
vnode = createComponent(tag, data, context, children)
}
这里对 tag 做判断,如果是 string 类型,则接着判断是内置节点的话直接创建一个普通 VNode,如果是为已注册的组件名,则通过 createComponent 创建一个组件类型的 VNode,否则创建一个未知的标签的 VNode。
createElement用于创建vnode,vnode有children,children的元素也是vnode,形成了 vnode tree,模拟了dom tree。
版权声明:
作者:东明兄
链接:https://blog.crazyming.com/note/2646/
来源:CrazyMing
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论