• 关于 Vue 中 h() 函数的一些东西


    最近在项目上需要一个信息弹窗,来显示信息。一开始只让它弹出了文字,而且只有一条信息。而给我的需求是多条文字和图片,而后我使用了element ui中的 Notification 通知组件来显示。当然,基础的 Notification 还不行,所以我使用了具有 HTML 片段的 Notification ,以及搭配 Vue 中的 h() 函数一起来使用。

    下面是element ui 中给出的 Notification 组件(具有 HTML 片段的 Notification )。

    1 ElNotification({
    2     title: 'HTML String',
    3     dangerouslyUseHTMLString: true,//是否将 message 属性作为 HTML 片段处理
    4     message: 'This is HTML string',//正文内容
    5   })

    而要完成我的需求,只需在 Notification 的正文内容使用 h() 函数即可。

    当我使用 h() 函数之后:

     1 ElNotification({
     2   title: 'HTML String',//标题
     3   type: 'warning',//类型
     4   offset: 80,//相对屏幕顶部的偏移量
     5   customClass: 'temperature',//自定义类名
     6   dangerouslyUseHTMLString: true,//是否将 message 属性作为 HTML 片段处理
     7   duration: 5000,//显示时间
     8   message: h('div', [
     9     h('img', { src: item[index].images[index], style: { width: '170px', height: '160px', float: 'left' } }),//插入的图片
    10     h('p', { class: 'userName', style: { color: 'orange', display: 'flex', margin: '0 0 0 15px' } }, '人员姓名:' + item[index].userName + ''),//插入的文字
    11   ],)

    代码写完了,接下来就讲讲 h() 函数以及它背后的 VNode (虚拟 DOM 节点 )

    什么是 h() 函数?Vue官方文档是这样解释的:

    Vue 提供了一个 h() 函数用于创建 vnodes。

    1 import { h } from 'vue'
    2 
    3 const vnode = h(
    4   'div', // type
    5   { id: 'foo', class: 'bar' }, // props
    6   [
    7     /* children */
    8   ]
    9 )

    h() 是 hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。这个名字来源于许多虚拟 DOM 实现默认形成的约定。一个更准确的名称应该是 createVnode(),但当你需要多次使用渲染函数时,一个简短的名字会更省力。

    h() 函数的使用方式非常的灵活:

     1 // 除了类型必填以外,其他的参数都是可选的
     2 h('div')
     3 h('div', { id: 'foo' })
     4 
     5 // attribute 和 property 都能在 prop 中书写
     6 // Vue 会自动将它们分配到正确的位置
     7 h('div', { class: 'bar', innerHTML: 'hello' })
     8 
     9 // props modifiers such as .prop and .attr can be added
    10 // with '.' and `^' prefixes respectively
    11 h('div', { '.name': 'some-name', '^width': '100' })
    12 
    13 // 类与样式可以像在模板中一样
    14 // 用数组或对象的形式书写
    15 h('div', { class: [foo, { bar }], style: { color: 'red' } })
    16 
    17 // 事件监听器应以 onXxx 的形式书写
    18 h('div', { onClick: () => {} })
    19 
    20 // children 可以是一个字符串
    21 h('div', { id: 'foo' }, 'hello')
    22 
    23 // 没有 props 时可以省略不写
    24 h('div', 'hello')
    25 h('div', [h('span', 'hello')])
    26 
    27 // children 数组可以同时包含 vnodes 与字符串
    28 h('div', ['hello', h('span', 'hello')])

    得到的 vnode 为如下形式:

    1 const vnode = h('div', { id: 'foo' }, [])
    2 
    3 vnode.type // 'div'
    4 vnode.props // { id: 'foo' }
    5 vnode.children // []
    6 vnode.key // null

    (完整的 VNode 接口包含其他内部属性,但是强烈建议避免使用这些没有在这里列举出的属性。这样能够避免因内部属性变更而导致的不兼容性问题。)

    所以总结下来,使用方法(很简单)
    h(标签, {属性},内容)
    h(标签, {属性},[可以继续嵌套h()])

     h() 函数已经会使用了,那 VNode 又是什么呢?(参考自qq_2268846315的文章。VNode 只是挑重点讲了下,并没有讲的超级详细,如有需要请参考 qq_2268846315 的文章)

    VNode :

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

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

    VNode 的作用:

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

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

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

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

    VNode 的类型:

    注释节点
    文本节点
    元素节点
    组件节点
    函数式节点
    克隆节点

    总结:

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

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

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

  • 相关阅读:
    spring cloud 微服务
    LeetCode --- 1417. Reformat The String 解题报告
    Cyanine5 NHS ester免疫荧光染色146368-14-1星戈瑞
    MySQL 8.2 Command Line Client打开时一闪而过闪退问题
    Win11系统启动文件夹是空的怎么解决?
    Python实践:脚本调用exe与exe输出获取的方法总结
    Lua中文语言编程源码-第二节,更改lbaselib.c基础库模块, 使Lua支持中文关键词(与操作相关的)
    EuroVis2022论文—2—FP-长论文
    19.Chain of Responsibility职责链(行为型模式)
    “超级 App”正在迎来价值重构的风暴
  • 原文地址:https://blog.csdn.net/weixin_47367099/article/details/127546411