Vue中的h函数和render函数是Vue中非常重要的函数,对Vue有着不可以或缺的作用,接下来让我们了解一下!
// 1. h 函数的基本使用
/**
* h 函数是 createVNode 的别名,用于创建虚拟 DOM 节点(VNode)
* h 函数参数:
* - type: 标签名/组件
* - props: 属性对象(可选)
* - children: 子节点(可选)
*/
// 1.1 创建简单元素
const vnode = h('div', { class: 'test' }, 'Hello')
// 1.2 创建带子元素的节点
const vnode2 = h('div', { class: 'parent' }, [
h('span', null, 'Child 1'),
h('span', null, 'Child 2')
])
// 1.3 创建组件
const MyComponent = {
props: ['title'],
setup(props) {
return () => h('h1', null, props.title)
}
}
const vnode3 = h(MyComponent, {
title: 'Hello',
onClick: () => console.log('clicked')
})
// 2. render 函数的使用
/**
* render 函数用于将虚拟 DOM 渲染为真实 DOM
* 参数:
* - vnode: 要渲染的虚拟节点
* - container: 容器元素
*/
// 2.1 基本用法
import { h, render } from 'vue'
const vnode = h('div', { class: 'test' }, 'Hello')
render(vnode, document.body)
// 2.2 动态渲染
function updateUI(text) {
const newVNode = h('div', null, text)
render(newVNode, document.body)
}
// 2.3 清除渲染
render(null, document.body) // 清除容器内容
// 3. 实际应用示例
// 3.1 创建消息提示组件
const createMessage = (type, content) => {
// 创建容器
const container = document.createElement('div')
document.body.appendChild(container)
// 创建消息组件的 VNode
const vnode = h('div', {
class: `message message-${type}`,
style: {
position: 'fixed',
top: '20px',
left: '50%',
transform: 'translateX(-50%)'
}
}, [
// 图标
h('i', { class: `icon-${type}` }),
// 文本内容
h('span', null, content)
])
// 渲染到容器
render(vnode, container)
// 定时清除
setTimeout(() => {
render(null, container)
container.remove()
}, 3000)
}
// 3.2 创建弹窗组件
const createModal = (options) => {
const container = document.createElement('div')
document.body.appendChild(container)
const close = () => {
render(null, container)
container.remove()
}
const vnode = h('div', {
class: 'modal-wrapper',
onClick: (e) => {
if (e.target === e.currentTarget) close()
}
}, [
h('div', { class: 'modal' }, [
// 标题
h('h2', null, options.title),
// 内容
h('div', { class: 'content' }, options.content),
// 按钮
h('div', { class: 'footer' }, [
h('button', {
onClick: () => {
options.onConfirm?.()
close()
}
}, '确定'),
h('button', {
onClick: close
}, '取消')
])
])
])
render(vnode, container)
return {
close
}
}
// 4. 高级用法
// 4.1 条件渲染
const conditionalRender = (condition) => {
return h('div', null, [
condition
? h('p', null, '条件为真')
: h('p', null, '条件为假')
])
}
// 4.2 列表渲染
const listRender = (items) => {
return h('ul', null,
items.map(item => h('li', { key: item.id }, item.text))
)
}
// 4.3 插槽的使用
const withSlots = (slots) => {
return h('div', { class: 'container' }, [
h('header', null, slots.header?.()),
h('main', null, slots.default?.()),
h('footer', null, slots.footer?.())
])
}
// 4.4 组件通信
const Parent = {
setup() {
const count = ref(0)
return () => h(Child, {
count: count.value,
onIncrement: () => count.value++
})
}
}
const Child = {
props: ['count'],
emits: ['increment'],
setup(props, { emit }) {
return () => h('button', {
onClick: () => emit('increment')
}, `Count: ${props.count}`)
}
}