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}`)}
}