h
h 是 "hyperscript" 的缩写,意思是 "能生成 HTML 结构的 JavaScript"。它用于创建虚拟节点(VNode)。
简单来说:h() 就是一个工厂函数,它接收一些参数,然后产出一个描述 DOM 结构的纯 JavaScript 对象(虚拟节点)。

》》》children 参数的类型
typescript
1. 字符串(文本节点)
// 渲染: <div>Hello World</div>
h('div', null, 'Hello World')
2. 数字(自动转为字符串)
// 渲染: <span>42</span>
h('span', null, 42)
3. 数组(多个子节点)
// 渲染: <div>
<h1>标题</h1>
<p>内容</p>
</div>
h('div', null, [
h('h1', null, '标题'),
h('p', null, '内容')
])
4. 单个 VNode(虚拟节点)
// 渲染: <div><span>只有一个子元素</span></div>
const childVNode = h('span', null, '只有一个子元素')
h('div', null, childVNode)
5. 对象(插槽对象) - 用于组件
这是特殊情况,只有当第一个参数是组件时,第三个参数才能是对象,用于定义插槽。
import MyComponent from './MyComponent.vue'
// 为组件定义插槽内容
h(MyComponent, null, {
// 默认插槽
default: () => h('span', '默认插槽内容'),
// 具名插槽
header: () => h('h1', '头部内容'),
footer: () => h('p', '底部内容')
})
typescript
// 可以混合文本、元素、组件等
h('div', { class: 'container' }, [
'纯文本节点', // 字符串
h('span', null, '元素节点'), // VNode
123, // 数字
h(MyComponent, { prop: 'value' }) // 组件
])
//渲染结果
<div class="container">
纯文本节点
<span>元素节点</span>
123
<!-- MyComponent 的渲染结果 -->
</div>
h('div', null, [
'开始',
[
h('p', null, '段落1'), // 嵌套数组
h('p', null, '段落2')
],
'结束'
])
//渲染结果
<div>
开始
<p>段落1</p>
<p>段落2</p>
结束
</div>

示例 1:创建原生 HTML 元素
typescript
// 模板写法
<template>
<div id="app" class="container">
<h1>标题</h1>
<p class="content">内容</p>
</div>
</template>
typescript
//函数写法
import { h } from 'vue'
const vnode = h(
'div',
{
id: 'app',
class: 'container'
},
[
h('h1', null, '标题'),
h('p', { class: 'content' }, '内容')
]
)
示例 2:创建组件
typescript
// 模板写法
<template>
<MyComponent :count="count" @change="handleChange">
<span>插槽内容</span>
</MyComponent>
</template>
typescript
//函数写法
import { h } from 'vue'
import MyComponent from './MyComponent.vue'
const vnode = h(
MyComponent, // 直接传入组件定义
{
count: this.count,
onChange: this.handleChange
},
{
// 定义插槽
default: () => h('span', '插槽内容')
}
)