文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue.js之VNode的使用

2024-04-02 19:55

关注

什么是VNode

在vue.js中存在一个VNode类,使用它可以实例化不同类型的vnode实例,而不同类型的vnode实例各自表示不同类型的DOM元素。

例如,DOM元素有元素节点,文本节点,注释节点等,vnode实例也会对应着有元素节点和文本节点和注释节点。

VNode类代码如下:


 export default class VNode {
    constructor(tag, data, children, text, elm, context, componentOptions, asyncFactory) {
       this.tag = tag
        this.data = data
        this.children = children
        this.text = text
        this.elm = elm
        this.ns = undefined
        this.context = context
        this.functionalContext = undefined
        this.functionalOptions = undefined
        this.functionalScopeId = undefined
        this.key = data && data.key
        this.componentOptions = componentOptions
        this.componentInstance = undefined
        this.parent = undefined
        this.raw = false
        this.isStatic = false
        this.isRootInsert = true
        this.isComment = false
        this.isCloned = false
        this.isOnce = false
        this.asyncFactory = asyncFactory
        this.asyncMeta = undefined
        this.isAsyncPlaceholder = false
    }
    get child() {
        return this.componentInstance
    }
 }
 

从上面的代码可以看出,vnode只是一个名字,本质上来说就是一个普通的JavaScript对象,是从VNode类实例化的对象。我们用这个JavaScript对象来描述一个真实DOM元素的话,那么该DOM元素上的所有属性在VNode这个对象上都存在对应得属性。

简单来说,vnode可以理解成节点描述对象,他描述了应该怎样去创建真实的DOM节点。
例如,tag表示一个元素节点的名称,text表示一个文本节点的文本,children表示子节点等。vnode表示一个真实的DOM元素,所有真实的DOM节点都是用vnode创建并插入到页面中。

VNode创建DOM并插入到视图

图中展示了使用vnode创建真实的DOM并渲染到视图的过程。可以得知,vnode和视图是一一对应的。我们可以把vnode理解成JavaScript对象版本的DOM元素。

渲染视图的过程是先创建vnode,然后在使用vnode去生成真实的DOM元素,最后插入到页面渲染视图。

VNode的作用

由于每次渲染视图时都是先创建vnode,然后使用它创建的真实DOM插入到页面中,所以可以将上一次渲染视图时先所创建的vnode先缓存起来,之后每当需要重新渲染视图时,将新创建的vnode和上一次缓存的vnode对比,查看他们之间有哪些不一样的地方,找出不一样的地方并基于此去修改真实的DOM。

Vue.js目前对状态的侦测策略采用了中等粒度。当状态发生变化时,只通知到组件级别,然后组件内使用虚拟DOM来渲染视图。

如图下所示,当某个状态发生变化时,只通知使用了这个状态的组件。也就是说,只要组件使用的众多状态中有一个发生了变化,那么整个组件就要重新渲染。

如果组件只有一个节点发生了变化,那么重新渲染整个组件的所有节点,很明显会造成很大的性能浪费。因此,对vnode惊醒缓存,并将上一次的缓存和当前创建的vnode对比,只更新有差异的节点就变得很重要。这也是vnode最重要的一个作用。

VNode的类型

vnode有很多不同的类型,有以下几种:

注释节点

  1. 文本节点
  2. 元素节点
  3. 组件节点
  4. 函数式节点
  5. 克隆节点

前面介绍了vnode是一个JavaScript对象,不同类型的vnode之间其实属性不同,准确说是有效属性不同。因为当使用VNode类创建一个vnode时,通过参数为实例设置属性时,无效的属性会默认设置为undefined或者false。对于 vnode身上的无效属性,直接忽略就好。

1.注释节点

由于创建注释节点的过程非常简单,所以直接通过代码来介绍它有哪些属性:


    export const createEmptyVNode = text => {
        const node = new VNode()
        node.text = text;
        node.isComment = true;
        return node
    }

一个注释节点只有两个有效属性 text 和 isComment。其余属性全是默认undefined或者false。

例如一个真实的注释节点,所对应的vnode是下面的样子:


// <!-- 注释节点 -->
{
    text: "注释节点",
    isComment: true
}

2.文本节点

文本节点的创建过程也非常简单,代码如下:


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

当文本类型的vnode被创建时,它只有一个text属性:


{
    text: "文本节点"
}
 

3.克隆节点

克隆节点是将现有节点的属性赋值到新节点中,让新创建的节点和被克隆的节点的属性保持一致,从而实现克隆效果。它的作用是优化静态节点和插槽节点(slot node)。

以静态节点为例,当组件内某个状态发生变化后,当前组件会通过虚拟DOM重新渲染视图,静态节点因为它的内容不会改变,所以除了首次渲染需要执行渲染函数获取vnode之外,后续更新不需要执行渲染函数重新生成vnode。

因此,这是就会使用创建克隆节点的方法将vnode克隆一份,使用克隆节点进行渲染。这样就不需要执行渲染函数生成新的静态节点的vnode,从而提升一定的性能。

创建克隆节点的代码如下:


export function cloneVNode(vnode, deep) {
        const cloned = new VNode(vnode.tag, vnode.data, vnode.children, vnode.text, vnode.elm, vnode.context, vnode.componentOptions, vnode.asyncFactory)
        cloned.ns = vnode.ns
        cloned.isStatic = vnode.isStatic
        cloned.key = vnode.key
        cloned.isComment = vnode.isComment
        cloned.isCloned = true
        if (deep && vnode.children) {
            cloned.children = cloneVNodes(vnode.children)
        }
        return cloned
    }

克隆现有节点,只需要将现有节点的属性全部赋值到新节点中。
克隆节点和被克隆节点位移的区别是isCloned属性,克隆节点为true,被克隆的原始节点为false。

4.元素节点

元素节点通常会存在以下4中有效属性。

一个真实的元素节点,对应得vnode是下面这样:


    // <p><span>Hello</span><span>World</span></p>
    {
        children: [VNode, VNode],
        context: {...},
        data: {...},
        tag: "p",
        ...
    }
 

5.组件节点

组件节点和元素节点类似,有以下两个独有的属性。

componentOptions:组件节点的选项参数,其中包含了propsData、tag和children等信息
componentInstance:组件的实例,也就是Vue.js的实例。事实上,在Vue.js中,每个组件都有一个Vue.js实例。

一个组件节点,对应得vnode是下面这样:


    // <child></child>
    {
        componentInstance: {...},
        componentOptions: {...},
        context: {...},
        data: {...},
        tag: "vue-component-1-child",
        ...    
    }

6.函数式节点

函数式节点和组件节点类似,他有两个独有的属性functionalContext和functionalOptions。
通常,一个函数式节点的vnode是下面这样:


     {
        functionalContext: {...},
        functionalOptions: {...},
        context: {...},
        data: {...},
        tag: "div"
      }

总结

VNode是一个类,可以生产不同类型的vnode实例,不同类型的实例表示不同类型的真实DOM。

由于Vue.js对组件采用了虚拟DOM来更新视图,当属性发生变化时,整个组件都要进行重新渲染的操作,但组件内并不是所有的DOM节点都需要更新,所以将vnode缓存并将当前新生成的vnode和缓存的vnode作对比,只对需要更新的部分进行DOM操作可以提升很多的性能。

vnode有很多类型,它们本质上都是Vnode实例化出的对象,其唯一区别是属性不同。

到此这篇关于Vue.js之VNode的使用的文章就介绍到这了,更多相关VNode使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯