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

相关推荐
Old Uncle Tom1 小时前
银行用户画像 -- 金融目标与需求意图
前端·人工智能·金融
IT_陈寒1 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
东方小月1 小时前
从0开发一个 Coding Agent(一):前言
前端·人工智能·typescript
恋猫de小郭1 小时前
Flutter 全新真 3D 实现,用 flutter_scene 能开发一个「我的世界」
android·前端·flutter
ji_shuke1 小时前
远程排查 Web 系统问题:如何导出 HAR 文件协助定位
前端·问题排查
程序员爱钓鱼2 小时前
Rust String 与 &str 详解:字符串所有权、借用与转换
前端·后端·rust
码农学院2 小时前
GEO与SEO协同:从传统搜索到生成式搜索的平滑迁移路径
服务器·前端·python
咩咩啃树皮10 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny10 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端