vue中的VNode
VueJS的虚拟DOM是基于开源Snabbdom的。前端发展很多年,直到出现了虚拟DOM,才可以从操作DOM解脱出来。JQuery的出现,简化了操作DOM的过程,但是还是摆脱不了操作DOM。而虚拟DOM的目的是,使用虚拟节点代替真实节点,所有操作都发生在虚拟节点,然后通过diff算法对比新旧两棵虚拟DOM,计算出更新真实DOM的最少操作,由框架代替用户执行这些操作,所以用户可以把大量的精力放...
文章共704字 · 阅读需要大约3分钟
一键AI生成摘要,助你高效阅读
问答
·
VueJS的虚拟DOM是基于开源Snabbdom的。
前端发展很多年,直到出现了虚拟DOM,才可以从操作DOM解脱出来。
JQuery的出现,简化了操作DOM的过程,但是还是摆脱不了操作DOM。
而虚拟DOM的目的是,使用虚拟节点代替真实节点,所有操作都发生在虚拟节点,然后通过diff算法对比新旧两棵虚拟DOM,计算出更新真实DOM的最少操作,由框架代替用户执行这些操作,所以用户可以把大量的精力放在业务逻辑上。
VNode
在Vue里,使用VNode表示一个虚拟节点,在Vue里,VNode分两种类别:
- 普通VNode
- 组件VNode
它们的区别是普通VNode有children
属性,而组件VNode的children
属性为undefined
。VNode 的结构如下:
// src/core/vdom/vnode.js
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
// strictly internal
raw: boolean; // contains raw HTML? (server only)
isStatic: boolean; // hoisted static node
isRootInsert: boolean; // necessary for enter transition check
isComment: boolean; // empty comment placeholder?
isCloned: boolean; // is a cloned node?
isOnce: boolean; // is a v-once node?
asyncFactory: Function | void; // async component factory function
asyncMeta: Object | void;
isAsyncPlaceholder: boolean;
ssrContext: Object | void;
fnContext: Component | void; // real context vm for functional nodes
fnOptions: ?ComponentOptions; // for SSR caching
fnScopeId: ?string; // functioanl scope id support
constructor (
tag?: string,
data?: VNodeData,
children?: ?Array<VNode>,
text?: string,
elm?: Node,
context?: Component,
componentOptions?: VNodeComponentOptions,
asyncFactory?: Function
) {
this.tag = tag // 当前节点标签名
this.data = data // 当前节点数据(VNodeData类型)
this.children = children // 当前节点子节点
this.text = text // 当前节点文本
this.elm = elm // 当前节点对应的真实DOM节点
this.ns = undefined // 当前节点命名空间
this.context = context // 当前节点上下文
this.fnContext = undefined // 函数化组件上下文
this.fnOptions = undefined // 函数化组件配置项
this.fnScopeId = undefined // 函数化组件ScopeId
this.key = data && data.key // 子节点key属性
this.componentOptions = componentOptions // 组件配置项
this.componentInstance = undefined // 组件实例
this.parent = undefined // 当前节点父节点
this.raw = false // 是否为原生HTML或只是普通文本
this.isStatic = false // 静态节点标志 keep-alive
this.isRootInsert = true // 是否作为根节点插入
this.isComment = false // 是否为注释节点
this.isCloned = false // 是否为克隆节点
this.isOnce = false // 是否为v-once节点
this.asyncFactory = asyncFactory // 异步工厂方法
this.asyncMeta = undefined // 异步Meta
this.isAsyncPlaceholder = false // 是否为异步占位
}
// 容器实例向后兼容的别名
get child (): Component | void {
return this.componentInstance
}
}
在看VNode的时候小结以下几点:
- 所有对象的
context
选项都指向了 Vue 实例; elm
属性则指向了其相对应的真实 DOM 节点;- DOM 中的文本内容被当做了一个只有
text
没有tag
的节点; - 像
class
、id
等HTML属性都放在了data
中。
更多推荐
已为社区贡献1条内容
所有评论(0)