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

下面是element ui 中给出的 Notification 组件(具有 HTML 片段的 Notification )。而要完成我的需求,只需在 Notification 的正文内容使用 h() 函数即可。

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

当我使用 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 的文章)

在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实例化出的对象,其唯一区别是属性不同。

关于 Vue 中 h() 函数的一些东西的更多相关文章

  1. vue中watch函数的用法

    vue中watch函数: 不仅可以判断路由变化(上篇博客有介绍),还可以判断数据的变化 (1):首先写watch函数 (2):在data里定义值 (3):在methods里写方法 (4):使用值

  2. vue中钩子函数的用法

    这么多钩子函数,我们怎么用呢,我想大家可能有这样的疑问吧,我也有,哈哈哈. beforecreate : 举个栗子:可以在这加个loading事件 created :在这结束loading,还做一些初 ...

  3. vue中find函数

    let obj = this.role.find(v => v.code === res.company.role)循环 data对象中的role数组 ,每个数组元素用v代替,code为他的键, ...

  4. vue中异步函数async和await的用法

    整理的不错,收藏一下 http://blog.sina.com.cn/s/blog_13d06fc1f0102wzfr.html

  5. 关于vue中钩子函数非常好的博客

    http://www.cnblogs.com/caimuqing/p/6728568.html

  6. 函数防抖节流的理解及在Vue中的应用

    防抖和节流的目的都是为了减少不必要的计算,不浪费资源,只在适合的时候再进行触发计算. 一.函数防抖 定义 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时:典型的案例就是输入搜索:输入 ...

  7. Vue知识整理7:vue中函数的应用

    在vue中使用函数对字符串做相应的处理: split:分割字符,将每个字符分割为一个数组值: reverse:将字符进行逆序排序: join:将字符连接: 最终输出结果.

  8. vue中简单的小插曲

    我们现在来学习一下vue中一些简单的小东西: 首先我们必须要引入vue.js文件哦! 1.有关文本框里的checkbox js代码: new Vue({ el:"#app", da ...

  9. Vue中你可能认为是bug的情况原来是这样的

    前言 我们知道Vue框架剧本双向数据绑定功能,在我们使用方便的同时,还有一些细节问题我们并不知道,接下来一起探讨一些吧 双向数据绑定 js变量改变影响页面 页面改变影响js变量 Vue2是如何做到数据 ...

随机推荐

  1. 案例复现,带你分析Priority Blocking Queue比较器异常导致的NPE问题

    摘要:本文通过完整的案例复现来演示在什么情况会触发该问题,同时给出了处理建议.希望读者在编程时加以借鉴,避免再次遇到此类问题. 本文分享自华为云社区<Priority Blocking Queu ...

  2. 4 亿用户,7W+ 作业调度难题,Bigo 基于 Apache DolphinScheduler 巧化解

    点击上方 蓝字关注我们 ✎ 编 者 按 成立于 2014 年的 Bigo,成立以来就聚焦于在全球范围内提供音视频服务.面对 4 亿多用户,Bigo 大数据团队打造的计算平台基于 Apache Dolp ...

  3. 1.5_HTML基础标签实战演练

    基本的 HTML 标签 HTML 标题 HTML 标题(Heading)是通过 <h1> - <h6> 等标签进行定义的. <h1>This is a headin ...

  4. 第七十四篇:Vue组件父子传值

    好家伙, 1.组件之间的关系 在项目开发中,组件之间的最常见关系分为如下两种: (1)父子关系 (2)兄弟关系 2.父子之间的数据共享 (1)父->子共享数据 父组件向子组件共享数据需要使用自定 ...

  5. 第三课:nodejs npm和vue

    1.安装node js 2.node js给windows提供了一个可以直接执行js的环境{node提供翻译} 3.npm是包管理器 a.npm是nodejs的组成部分 b.管 包(package) ...

  6. Neo4j入门详细教程

    Neo4j安装配置 (1)下载安装包 (2)安装jdk (3)环境变量配置 分三步,具体参考  https://www.bilibili.com/video/BV1Nz411q7bG?from=sea ...

  7. KingbaseES R6 通过脚本构建集群案例

      案例说明: KingbaseES V8R6部署一般可采用图形化方式快速部署,但在生产一线,有的服务器系统未启用图形化环境,所以对于KingbaseES V8R6的集群需采用手工字符界面方式部署,本 ...

  8. 进阶:spring-bean生命周期流程

    Bean的生成过程 主要流程图 1. 生成BeanDefinition Spring启动的时候会进行扫描,会先调用org.springframework.context.annotation.Clas ...

  9. C# 常见面试问题

    C# 常见面试问题 EntityFramework 数据持久化 C#中的委托是什么?事件是不是一种委托? C#中的委托是一种引用类型,表示具有相同方法签名的方法的引用.类似于函数指针,也就是说它们是指 ...

  10. 事件循环:微任务和宏任务在v8中实现的简单理解

    微任务 在js中,当使用promise,会将当前任务加入事件执行的微任务队列,有且只有这一种方法可以,因为当使用了promise,在JS引擎中会触发VM::queueMicrotask,会向m_mic ...