vue官方文档地址:cn.vuejs.org/api/render-…
<template>
<div class="app-wrapper">
<h1 style="text-align: center; color: #303133">
Vue 3 渲染函数 (h() API) 学习示例
</h1>
<AppComponent />
</div>
</template>
<script setup>
import AppComponent from './app.js'
</script>
<style scoped>
.app-wrapper {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
:deep(.app-container) {
padding: 20px;
}
:deep(.btn) {
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s;
}
:deep(.btn-primary) {
background-color: #409eff;
color: white;
}
:deep(.btn-primary:hover) {
background-color: #66b1ff;
}
:deep(.btn-danger) {
background-color: #f56c6c;
color: white;
}
:deep(.btn-danger:hover) {
background-color: #f78989;
}
:deep(.btn-active) {
background-color: #67c23a;
color: white;
}
</style>
import { defineComponent, h, ref, computed } from 'vue'
/**
* 使用 h() 函数创建虚拟 DOM 节点的示例组件
* h() 是 Vue 3 的渲染函数 API,用于创建虚拟 DOM 节点 (vnode)
*/
export default defineComponent({
name: 'AppComponent',
setup() {
// 响应式数据
const count = ref(0)
const message = ref('Hello Vue 3 Render Function!')
const items = ref(['Item 1', 'Item 2', 'Item 3'])
const isActive = ref(true)
// 计算属性
const doubleCount = computed(() => count.value * 2)
// 方法
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
const toggleActive = () => {
isActive.value = !isActive.value
}
// 返回渲染函数
return () => {
// h() 函数的基本语法:
// h(tag, props, children)
// - tag: 标签名、组件或异步组件
// - props: 属性对象(可选)
// - children: 子节点(可选)
return h('div', { class: 'app-container' }, [
// 1. 创建简单的 HTML 元素
h(
'h1',
{
class: 'title',
style: { color: '#409eff', marginBottom: '20px' },
},
message.value
),
// 2. 创建带事件处理的按钮
h('div', { class: 'button-group' }, [
h(
'button',
{
onClick: increment,
class: 'btn btn-primary',
style: { marginRight: '10px', padding: '8px 16px' },
},
'增加 (+1)'
),
h(
'button',
{
onClick: decrement,
class: 'btn btn-danger',
style: { marginRight: '10px', padding: '8px 16px' },
},
'减少 (-1)'
),
h(
'button',
{
onClick: toggleActive,
class: ['btn', { 'btn-active': isActive.value }],
style: { padding: '8px 16px' },
},
isActive.value ? '禁用' : '启用'
),
]),
// 3. 显示响应式数据
h('div', { class: 'counter-section', style: { marginTop: '20px' } }, [
h(
'p',
{ style: { fontSize: '18px', fontWeight: 'bold' } },
`计数: ${count.value}`
),
h(
'p',
{ style: { color: '#67c23a' } },
`双倍计数: ${doubleCount.value}`
),
]),
// 4. 条件渲染
h('div', { class: 'status-section', style: { marginTop: '20px' } }, [
isActive.value
? h(
'p',
{
style: { color: '#67c23a', fontSize: '16px' },
},
'✅ 状态: 激活'
)
: h(
'p',
{
style: { color: '#f56c6c', fontSize: '16px' },
},
'❌ 状态: 禁用'
),
]),
// 5. 列表渲染
h('div', { class: 'list-section', style: { marginTop: '20px' } }, [
h(
'h2',
{ style: { fontSize: '20px', marginBottom: '10px' } },
'列表项:'
),
h(
'ul',
{
style: { listStyle: 'none', padding: 0 },
},
items.value.map((item, index) =>
h(
'li',
{
key: index,
style: {
padding: '8px',
margin: '4px 0',
backgroundColor: '#f0f2f5',
borderRadius: '4px',
},
},
`${index + 1}. ${item}`
)
)
),
]),
// 6. 嵌套组件结构
h(
'div',
{
class: 'card',
style: {
marginTop: '20px',
padding: '20px',
border: '1px solid #dcdfe6',
borderRadius: '4px',
backgroundColor: '#fff',
},
},
[
h('h3', { style: { marginTop: 0 } }, '卡片标题'),
h(
'p',
{ style: { color: '#606266' } },
'这是一个使用 h() 函数创建的卡片组件示例'
),
]
),
// 7. 使用插槽(通过函数传递子节点)
h(
'div',
{
class: 'footer',
style: { marginTop: '20px', color: '#909399' },
},
'使用 Vue 3 h() API 创建的虚拟 DOM'
),
])
}
},
})