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

相关推荐
赖龙8 小时前
pnpm vs npm
前端·npm·node.js
学如逆水,不进则退9 小时前
在线免费音频剪辑:NBTools 可视化波形裁剪 MP3/WAV,本地处理免上传
前端·音视频
Mh9 小时前
虚拟滚动真的比普通滚动性能更好吗?
前端·javascript·性能优化
pe7er9 小时前
React + Ant Design 中的 IME (输入法合成)安全输入组件
前端
Super 含10 小时前
Android 启动优化(二):TTID、TTFD 与 Macrobenchmark 启动性能测量
前端
Python私教10 小时前
别急着加 llms.txt:企业官网面向 AI 搜索的工程清单
前端·人工智能·seo
东方小月10 小时前
从零开发一个 Coding Agent(十三):实现安全的 read 文件读取工具
前端·人工智能·全栈
东方小月11 小时前
从零开发一个 Coding Agent(十二):实现版本化 JSONL 与真实 CLI 入口
前端·设计模式·前端框架
FL162386312912 小时前
室内易燃物识别易燃评估室内易燃程度识别分割数据集labelme格式1015张85类别
java·服务器·前端
用户0595401744612 小时前
把 AI 长期记忆去重测试从 20 分钟压到 40 秒,重复率从 18% 干到 1.5%
前端·css