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)
相关推荐
程序员小寒1 小时前
JavaScript设计模式(八):命令模式实现与应用
前端·javascript·设计模式·ecmascript·命令模式
wgod1 小时前
new AbortController()
前端
UXbot1 小时前
UXbot 是什么?一句指令生成完整应用的 AI 工具
前端·ai·交互·个人开发·ai编程·原型模式·ux
棒棒的唐2 小时前
WSL2用npm安装的openclaw,无法正常使用openclaw gateway start启动服务的问题
前端·npm·gateway
哔哩哔哩技术2 小时前
使用Compose Navigation3进行屏幕适配
前端
Z_Wonderful3 小时前
在 Next.js 中,使用 [id] 或 public 作为文件夹或文件名是两种完全不同的概念,分别对应 动态路由 和 静态资源托管
javascript·网络·chrome
咬人喵喵3 小时前
E2.COOL 平台深度解析:从特效分类到实战操作指南
前端·编辑器·svg
RisunJan3 小时前
Linux命令-named-checkzone
linux·前端
小陈工3 小时前
Python Web开发入门(十):数据库迁移与版本管理——让数据库变更可控可回滚
前端·数据库·人工智能·python·sql·云原生·架构
吹晚风吧4 小时前
解决vite打包,base配置前缀,nginx的dist包找不到资源
服务器·前端·nginx