vue3:一文理解h函数的使用

目录

[第一章 前言](#第一章 前言)

[第二章 h函数的使用](#第二章 h函数的使用)

[2.1 h函数语法](#2.1 h函数语法)

[2.2 原生标签渲染](#2.2 原生标签渲染)

[2.3 组件渲染](#2.3 组件渲染)

[2.4 渲染多个标签/组件](#2.4 渲染多个标签/组件)

[2.5 slot插槽渲染](#2.5 slot插槽渲染)

[2.6 例子](#2.6 例子)


第一章 前言

以下是官方文档下对h函数的一些说明与使用:

https://cn.vuejs.org/guide/extras/render-function.html#creating-vnodes
渲染函数 API | Vue.js

在绝大多数情况下,Vue 推荐使用模板语法来创建应用。然而在某些使用场景下,我们真的需要用到 JavaScript 完全的编程能力。这时渲染函数就派上用场了。

小编在该篇文章中主要说明一下h函数使用的场景和如何使用!

第二章 h函数的使用

2.1 h函数语法

  • 1.type: 第一个参数既可以是一个字符串 (用于原生元素) 也可以是一个 Vue 组件
  • 2.props: 要传的参数,可以理解成<div class="test" id="test" @click="handleClick" />标签上所有的属性都可以写在props里面,但是如果是事件监听器需要以 onXxx 的形式书写
  • 3.children: 子节点,可以是字符串,也可以是数组包含多个节点,也可以是对象针对于组件的插槽
  • 注意: h函数必须只有一个根节点,如果需要一次性渲染多个组件,需要在children中实现
javascript 复制代码
import { h } from 'vue'

// 完整参数
/*
    1.type: 第一个参数既可以是一个字符串 (用于原生元素) 也可以是一个 Vue 组件
    2.props: 要传的参数,可以理解成<div class="test" id="test" @click="handleClick" />标签上所有的属性都可以写在props里面,但是如果是事件监听器需要以 onXxx 的形式书写
    3.children: 子节点,可以是字符串,也可以是数组包含多个节点,也可以是对象针对于组件的插槽
*/
const VNod = h(
  type: string | Component,
  props?: object | null,
  children?: Children | Slot | Slots
)

2.2 原生标签渲染

javascript 复制代码
import { h } from 'vue'

// const vnode1 = h(
//     'div', // type
//     { id: 'foo', class: 'bar' }, // props
//     [] || '' // children
// )


const message = ref('这是一个h函数渲染的div')
const vnode2 = h(
  'div',
  {
    class: 'div-test',
    style: {
      color: 'red'
    },
    onclick: ()=> {
      console.log('点击输出');
    }
  },
  message.value
)

const vnode3 = h('div')
......

2.3 组件渲染

javascript 复制代码
// DownOutlined是antd的图标组件
h(DownOutlined, { style: { 'font-size': '12px' } })

2.4 渲染多个标签/组件

javascript 复制代码
// h函数必须只有一个根节点,如果需要一次性渲染多个组件,需要在children中实现
h(
  'div',
  {
    class: 'w-full gap-x-3 flex items-center justify-start'
  },
  [
    h('span', null)
    h('span', null, record.seqNumber)
  ]
)

2.5 slot插槽渲染

javascript 复制代码
// 这是antd的Tooltip, default为默认插槽
h(Tooltip, { title: str }, { default: () => showStr })
// 自定义组件HelloWorld,default为默认插槽,header为具名插槽
h(
    HelloWorld, 
    { 
        msg: message.value,
        onClick: (value)=> {
            console.log(value);
        },
    },
    {
        default: ()=> h('div', '我是 HelloWorld 组件的默认插槽里面的值'),
        header: ()=> h('div', '我是 HelloWorld 组件的 header 插槽里面的值'),
    }
)

2.6 例子

以下只是小编在实战中使用的一段代码:

javascript 复制代码
// 利用一段三目运算活用
// 小编这里之所以props传null是因为不传会报错,但是官网说明是可选的,具体看大家敲代码时的具体情况了
return !isSub
  ? h(
      'div',
      {
        class: 'w-full gap-x-3 flex items-center justify-start'
      },
      [
        record.childList.length
          ? expandedRowsSet.value.has(record.id)
            ? h(CaretDownOutlined, {
                onClick: () => removeExpanedRow(record.id)
              })
            : h(CaretRightOutlined, {
                onClick: () => addExpanedRow(record.id)
              })
          : h('span', null),
        h('span', null, record.seqNumber)
      ]
    )
  : h('span', null)
相关推荐
喵手几秒前
CSS3 渐变、阴影和遮罩的使用
前端·css·css3
顽强d石头2 分钟前
bug:undefined is not iterable (cannot read property Symbol(Symbol.iterator))
前端·bug
烛阴11 分钟前
模块/命名空间/全局类型如何共存?TS声明空间终极生存指南
前端·javascript·typescript
火车叼位15 分钟前
Git 精准移植代码:cherry-pick 简单说明
前端·git
江城开朗的豌豆19 分钟前
JavaScript篇:移动端点击的300ms魔咒:你以为用户手抖?其实是浏览器在搞事情!
前端·javascript·面试
华洛25 分钟前
聊聊我们公司的AI应用工程师每天都干啥?
前端·javascript·vue.js
江城开朗的豌豆25 分钟前
JavaScript篇:你以为事件循环都一样?浏览器和Node的差别让我栽了跟头!
前端·javascript·面试
技术小丁28 分钟前
使用 HTML +JavaScript 从零构建视频帧提取器
javascript·html·音视频
gyx_这个杀手不太冷静28 分钟前
Vue3 响应式系统探秘:watch 如何成为你的数据侦探
前端·vue.js·架构
晴殇i34 分钟前
🌐 CDN跨域原理深度解析:浏览器安全策略的智慧设计
前端·面试·程序员