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)// 创建消息组件的 VNodeconst 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}`)}
}