Vue中的 h 作用和使用方法介绍

在 Vue(特别是 Vue 3)中,h 函数是 创建虚拟 DOM 节点(VNode) 的核心工具。它的名字来源于 "hyperscript" ------ 一种用 JavaScript 编写 HTML 结构的编程范式。


一、h 函数的作用

  • 创建 VNode(虚拟节点):描述一个 DOM 元素或组件的结构、属性和子内容。
  • 替代模板语法 :当你无法使用 <template>(如动态生成 UI、高阶组件、函数式组件等),可用 h() 编程式构建 UI。
  • 底层渲染机制 :Vue 的模板最终会被编译成 h() 调用,因此 h 是 Vue 渲染系统的基石。

✅ 简单说:h('div', { class: 'foo' }, 'Hello')<div class="foo">Hello</div>


二、基本语法

ts 复制代码
h(type, props?, children?)

参数说明:

参数 类型 说明
type `string Component`
props `object null`(可选)
children `string number

⚠️ 注意:props 可省略。若第二个参数是数组或字符串,Vue 会自动将其视为 childrenprops 设为 null


三、常见使用示例

1. 创建原生 HTML 元素

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

// 最简形式
h('div')

// 带属性
h('div', { id: 'app', class: 'container' })

// 带子节点
h('div', { class: 'title' }, 'Hello World')

// 子节点为数组
h('ul', [
  h('li', 'Item 1'),
  h('li', 'Item 2')
])

2. 创建组件

js 复制代码
import MyComponent from './MyComponent.vue'

// 传递 prop
h(MyComponent, { message: 'Hi!' })

// 传递默认插槽
h(MyComponent, () => 'Default slot content')

// 传递具名插槽(注意:需显式传 null 作为 props)
h(MyComponent, null, {
  default: () => 'Default',
  header: () => h('h1', 'Header')
})

3. 事件与样式

js 复制代码
h('button', {
  class: ['btn', { primary: true }],
  style: { color: 'red', fontSize: '16px' },
  onClick: () => alert('Clicked!')
}, 'Click me')

4. 在 setup() 中返回渲染函数(组合式 API)

js 复制代码
import { h, ref } from 'vue'
import ChildComp from './Child.vue'

export default {
  setup() {
    const count = ref(0)
    const increment = () => count.value++

    // 返回一个渲染函数
    return () => h('div', [
      h('p', `Count: ${count.value}`),
      h('button', { onClick: increment }, '+1'),
      h(ChildComp)
    ])
  }
}

🔔 在 <script setup> 中,通常通过 <component :is="renderFn" /> 使用。


四、高级特性

✅ 自动归一化(Normalization)

  • class / style 支持对象、数组格式(如 { active: true }['a', 'b']
  • 事件监听器以 onXxx 形式书写(如 onClickclick 事件)
  • children 自动扁平化嵌套数组,并过滤 null/undefined

✅ 多参数灵活调用

js 复制代码
h('div', 'text')                     // type + children
h('div', { id: 'x' })                // type + props
h('div', { id: 'x' }, 'text')        // type + props + children
h('div', {}, 'a', 'b')               // children 合并为 ['a', 'b']

五、与模板的关系

Vue 模板是语法糖,最终会被编译为 h() 调用:

html 复制代码
<!-- 模板 -->
<div class="box" @click="handle">{{ msg }}</div>

⬇️ 编译后 ≈

js 复制代码
h('div', {
  class: 'box',
  onClick: handle
}, ctx.msg)

六、何时使用 h()

场景 说明
✅ 动态标签 如根据 level 渲染 <h1> ~ <h6>
✅ 高阶组件 / 函数式组件 包装或增强其他组件
✅ 复杂条件渲染 模板中 v-if 嵌套过深时
✅ 表格/列表自定义渲染 如 Naive UI / Element Plus 的 render-cell
❌ 简单 UI 优先用 <template>,更易读维护

总结

  • h 是 Vue 3 中创建 VNode 的标准方式。
  • 它提供比模板更强的程序控制力 ,适合动态性高、逻辑复杂的场景。
  • 虽然灵活,但不推荐滥用------简单 UI 仍应使用模板。

📌 记住:模板 → 编译 → **h()** → VNode → 真实 DOM

如需深入,可查看 Vue 官方文档:渲染函数 - Vue.js

相关推荐
晴天丨1 小时前
Element Plus 组件库实战技巧与踩坑记录
前端·vue.js
胡志辉1 小时前
m3u8 视频怎么下载?为什么 B 站只给你一个 blob:把 HLS、DASH、MSE 这条前端链路讲透
前端
yhole2 小时前
SpringBoot + vue 管理系统
vue.js·spring boot·后端
落魄江湖行2 小时前
进阶篇五 Nuxt4 部署方案:从开发到生产
前端·vue.js·typescript·nuxt4
懂懂tty2 小时前
Rspack简介
前端
开心码农1号2 小时前
Go关于切边变量本身地址和内部指向地址
前端·算法
一个打工仔的笔记2 小时前
vue3 elementui plus 可编辑表格 完整例子
前端·vue.js·elementui
IT_陈寒2 小时前
SpringBoot自动配置把我坑惨了,原来它偷偷干了这么多事
前端·人工智能·后端
nodcloud2 小时前
Chrome 142 更新导致点可云报表助手打印异常:启动服务仍提示启动的解决方案
前端·数据库·chrome