第6章 (第②篇 虚拟DOM)VNode

什么是VNode

在Vue.js中存在一个VNode类,使用它可以实例化不同类型的vnode实例,而不同类型的vnode实例各自表示不同类型的DOM元素,例元素节点,文本节点或者是注释节点。
VNode类的代码:

export default class VNode{
    constructor(tag...){    
        this.tag = tag
        this.data = data
        this.children = children
        this.text = text
        ......
    }
}

vnode事实上只是一个普通的js对象,是从Vnode类实例化的对象,用这个来描述某个真实DOM元素,那么该DOM元素上的所有属性都应该在VNode这个对象上都存在对应的属性。可以将vnode理解为节点描述对象,是JavaScript对象版本的DOM元素

VNode的作用

每次创建vnode后,在渲染视图时都要缓存起来,以便之后需要重新渲染的时候,可以利用新老vnode进行比对来查找出不同的地方,基于此来修改真实的DOM。
现在对状态的侦测采用中等粒度,所以当状态发生变化的时候,只通知到组件级别,当组件中的任何一个状态发生变化,需要对整个组件进行重新渲染,如果只有一个发生变化,重新渲染整个组件会造成很大的性能浪费,所以对vnode进行缓存,利用新老vnode进行比对,只修改更新变化后的节点就变得很重要。

VNode的类型

注释节点/文本节点/元素节点/组件节点/函数式组件/克隆节点
vnode在不同类型节点之间其实就是属性不同,在创建成vnode的时候,通过参数为实例设置属性,无效的属性会被设置为undefined或false,只在意节点的有效属性即可。

1.注释节点

<! -- 注释节点 -->
//创建注释节点
export const createEmptyVNode = text =>{
    const node = new VNode()
    node.text = text //注释的文本内容
    node.isComment = true  //是否是注释
    return node
}

2.文本节点

export function createTextVNode(val){
    return new VNode(undefined,undefined,undefined,String(val))
}

{
    text:'Hello World'
}

文本节点只有一个text属性

3.克隆节点

克隆节点是将现有节点的属性复制到新节点中,让新创建的节点和被克隆节点的属性保持一致,达到克隆效果。作用是用来优化静态节点和插槽节点(slot node)
静态节点在第一次渲染时所需要获取vnode之外,之后更新不需要重新渲染生成vnode,所以此时会使用创建克隆节点,将vnode静态节点克隆一份,使用克隆节点进行渲染,就不需要重新生成渲染函数来生成新的静态节点,从一定程度上提升了性能。
克隆现有节点时,只需要将现有的节点属性全部复制到新节点之中即可。克隆节点和被克隆节点之间唯一的区别就是isCloned属性,克隆节点为true,被克隆的原始节点为false。

4.元素节点

元素节点通常会存在4种有效属性
1.tag:节点的名称。例如p,div,li等等
2.data:包含了一些节点上的数据。例如attrs,class,style等等
3.chidren:当前节点的子节点列表。
4.context:它时当前组建的Vue.js实例

//例如一个真实的元素节点
<p><span>Hello</span><span>World!</span></p>
//所对应的vnode
{
    children:[VNode,VNode]
    context:{...},
    data:{...},
    tag:"p",
    ......
}

5.组件节点

组件节点有两个一下独有的属性
componentOptions:组件节点的选项参数,其中包含propsData、tag和children等信息
componentInstance:组件的实例,也是Vue.js的实例。每一个组件都是一个Vue.js实例。

//一个组件节点
<child></child>
{
    componentInstance:{...},
    componentOptions:{...},
    context:{...},
    data:{...},
    tag:"vue-component-1-child",
    ......
}

6.函数式组件

函数式组件和组件节点类似,有两个独有属性
functionalContext和functionalOptions

总结

Vnode是一个类,可以生成不同类型的vnode实例,而不同类型的vnode表示不同类型的真实DOM元素。
由于Vue.js对组件采用了虚拟DOM来更新视图,当属性发生变化时,整个组件都要进行重新渲染的操作,但组件内并不是所有的DOM节点都需要更新,所以将vnode缓存并将当前新生成的vnode和上一次缓存的oldVnod进行对比,只对需要更新的部分进行DOM操作可以提升更多的性能。
vnode有很多类型,它们本质上都是从VNode类实例化出的对象,其唯一区别就是属性不同。

深入浅出Vue.js 文章被收录于专栏

记录一下阅读vue源码的收获

全部评论

相关推荐

秋招之BrianGriffin:你再跟他说华为工资也低(相对互联网)就可以享受私信爆炸了😋
点赞 评论 收藏
分享
2024-12-29 11:08
湖南工业大学 Java
程序员牛肉:简历没什么大问题了。 而且不要再换项目了。三月份就开暑期实习了,现在都一月份了。实在来不及重新开一下项目了。把一个项目写完或许很快,但是把一个项目搞懂吃透并不简单。所以不要换项目了,把你简历上面的两个项目好好挖一挖吧。 具体 体现在:你能不能流利的说出你的项目的每一个功能点代码实现?你能不能说出在这块除了A技术之外,还有其他技术能够实现嘛?如果有其他技术能够实现,那你这块为什么选择了你当前用的这个技术?
投递牛客等公司
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务