vue多功能渲染函數(shù)h()的使用和多種應(yīng)用場景
前言
按照vue
官方的介紹,h()
渲染函數(shù)是用來創(chuàng)建虛擬 DOM
節(jié)點(diǎn) vnode
。我們?cè)?code>vue項(xiàng)目里面用HTML
標(biāo)簽構(gòu)建頁面時(shí)最終會(huì)被轉(zhuǎn)化成vnode
,而h()
是直接創(chuàng)建vnode
,因此h()
能以一種更靈活的方式在各種各樣情景下構(gòu)建組件的渲染邏輯,并且能帶來性能方式的提升。下面介紹如何使用和列出具體的應(yīng)用場景:
一、 h()渲染函數(shù)使用語法
如下所示,主要有三個(gè)參數(shù),其中第2第3個(gè)參數(shù)都是可選的
- type: 要?jiǎng)?chuàng)建的節(jié)點(diǎn)類型,可以是HTML 標(biāo)簽、組件或函數(shù)(函數(shù)式組件)。
- props(可選): 節(jié)點(diǎn)的屬性對(duì)象,傳遞的 prop。
- children(可選): 節(jié)點(diǎn)的子節(jié)點(diǎn),可以是字符串、數(shù)組或其他 vnode。
// 語法格式 function h( type: string | Component, props?: object | null, children?: Children | Slot | Slots ): VNode // 基本使用示例 h('div', { id: 'foo' }, 'Hello我是天天鴨!');
h 函數(shù)的參數(shù)詳解
(1)type 參數(shù):
- HTML 標(biāo)簽: 如果 type 是一個(gè)字符串,它會(huì)被識(shí)別解析為一個(gè) HTML 標(biāo)簽。
- 組件: 如果 type 是一個(gè)對(duì)象或函數(shù),那么會(huì)被解析為一個(gè) Vue 的組件。
- 異步組件: type 還可以是一個(gè)返回 Promise 的函數(shù), Promise 會(huì)被解析為組件。
(2)props 參數(shù):
- props是可選參數(shù),用來指定該節(jié)點(diǎn)的屬性參數(shù)。如果傳遞了 props,側(cè)應(yīng)該是傳遞一個(gè)對(duì)象,里面包含傳遞給節(jié)點(diǎn)的屬性名和值。
- 如果傳遞 props,可以傳遞 null。
(3)children 參數(shù):
- children是可選參數(shù),用于指定當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)。子節(jié)點(diǎn)同理可以是字符串、數(shù)組或 vnode 對(duì)象。
- 如果子節(jié)點(diǎn)是數(shù)組,則數(shù)組中的每個(gè)元素都是該節(jié)點(diǎn)的子節(jié)點(diǎn)。
- 如果子節(jié)點(diǎn)是一個(gè)函數(shù),則該函數(shù)會(huì)在渲染時(shí)被調(diào)用,并且其返回值將作為子節(jié)點(diǎn)。
二、具體應(yīng)用示例
只看使用語法可能不太好理解什么時(shí)候應(yīng)該使用h()
函數(shù),下面直接列舉出真實(shí)項(xiàng)目中的幾種適合使用h()
的業(yè)務(wù)場景。
(1)動(dòng)態(tài)渲染組件
如下所示,結(jié)合component
實(shí)現(xiàn)動(dòng)態(tài)組件,這種算是最常用的業(yè)務(wù)場景之一了,但很多人在這種情況并不會(huì)用h()
實(shí)現(xiàn)些功能。 其實(shí)用上h()
能避免模板編譯的開銷,在這場景下可以帶來性能上的優(yōu)化,并且處理起來也更靈活。
<template> <button @click="changeComponent">切換動(dòng)態(tài)組件</button> <component :is="createComponent()" /> </template> <script setup lang="ts"> import { ref } from 'vue'; import ComponentA from './ComponentA.vue'; import ComponentB from './ComponentB.vue'; const nowComponent = ref('ComponentA'); function changeComponent() { nowComponent.value = nowComponent.value === 'ComponentA' ? 'ComponentB' : 'ComponentA'; } const createComponent = () => { return h(nowComponent.value === 'ComponentA' ? ComponentA : ComponentB); }; </script>
(2)創(chuàng)建函數(shù)式組件
用h()
創(chuàng)建函數(shù)式組件既能獨(dú)立抽離維護(hù),又不用額外多創(chuàng)建一個(gè).vue
文件,真的不要太實(shí)用了。這種方式非常適合用于簡單的 UI
組件,可以顯著簡化代碼并且提高性能。
<template> <FunctionalComponent text="這是函數(shù)式組件" @click="handleClick" /> </template> <script setup lang="ts"> import { h, defineEmits } from 'vue'; const FunctionalComponent = (props, context) => { return h('div', null, [ h('p', null, props.text), h('button', { onClick: context.emit.bind(context, 'click') }, '點(diǎn)擊我') ]); }; const emit = defineEmits(['click']); function handleClick() { console.log('handleClick'); } </script>
如上所示,就是典型的函數(shù)式組件使用方法,其中包含了如何在父子組件中與之交互。函數(shù)式組件 FunctionalComponent
接收 props
和 context
參數(shù),并使用 h()
函數(shù)來構(gòu)建頁面。同時(shí)再通過 context.emit
方法來觸發(fā)父組件中的事件處理器。
注意: props
用于接收父組件傳遞過來的屬性。context
用于訪問組件上下文,如 slots插槽和方法事件的。
(3)渲染動(dòng)態(tài)屬性
一個(gè)組件或者一個(gè)標(biāo)簽如果需要定義一些動(dòng)態(tài)屬性,那么用h()
渲染函數(shù)就相當(dāng)方便了
<template> <button @click="myVisibility">切換組件顯示狀態(tài)</button> <component :is="componentWithProps()" /> </template> <script setup lang="ts"> import { ref } from 'vue'; const visible = ref(true); function myVisibility() { visible.value = !visible.value; } const componentWithProps = () => { return h('div', { class: { visible: visible.value } }, '我是div'); }; </script>
如上所示,h()
函數(shù)里面根據(jù) visible
的值來決定 vnode
是否具有 visible
這個(gè)類,當(dāng)點(diǎn)擊按鈕時(shí)實(shí)現(xiàn)動(dòng)態(tài)樣式。當(dāng)然了,動(dòng)態(tài)類只是一個(gè)例子,其實(shí)h()
里面的各種屬性或者說子組件都能動(dòng)態(tài),靈活性遠(yuǎn)超用HTML
實(shí)現(xiàn)。
(4)使用插槽
h()
如果結(jié)合函數(shù)式組件和插槽來傳遞內(nèi)容,能提高使用時(shí)的靈活性。
<template> <SlotComponent> <template #default> <p>我是插槽里面</p> </template> </SlotComponent> </template> <script setup lang="ts"> import { h } from 'vue'; const SlotComponent = (props, context) => { return h('div', null, [ h('p', null, '插槽里面:'), context.slots.default && context.slots.default() ]); }; </script>
如上所示,引用 SlotComponent
組件時(shí),其內(nèi)部的 <template>
標(biāo)簽中的內(nèi)容會(huì)被作為默認(rèn)插槽的內(nèi)容傳遞給 SlotComponent
組件。并且能通過 context.slots.default()
來獲取并渲染默認(rèn)插槽里面的內(nèi)容。因此當(dāng)我們封裝一個(gè)函數(shù)式組件,但里面有某一部分是動(dòng)態(tài)的時(shí)候,就特別適合這樣通過插槽去靈活使用。
注意: props
用于接收父組件傳遞過來的屬性。context
用于訪問組件上下文,如 slots插槽和方法事件的。
(5)創(chuàng)建動(dòng)態(tài)標(biāo)簽
如下代碼是 h()
函數(shù)結(jié)合動(dòng)態(tài)組件來實(shí)現(xiàn)在不同的 HTML
標(biāo)簽之間的切換。
<template> <button @click="changeTag">切換標(biāo)簽</button> <component :is="createElement()" /> </template> <script setup lang="ts"> import { ref } from 'vue'; const tag = ref('div'); function changeTag() { tag.value = tag.value === 'div' ? 'section' : 'div'; } const createElement = () => { return h(tag.value, null, '動(dòng)態(tài)標(biāo)簽'); }; </script>
如上所示,其實(shí)就是根據(jù) tag
的值來決定返回哪個(gè) HTML
標(biāo)簽的 VNode
,如果業(yè)務(wù)邏輯涉及到標(biāo)簽的動(dòng)態(tài)變化時(shí)就相當(dāng)好用,避免使用v-if
產(chǎn)生大量重復(fù)代碼。
小結(jié)
總結(jié)下來就會(huì)發(fā)現(xiàn),其實(shí)h()
渲染函數(shù)適用的應(yīng)用場景非常多并且用法相當(dāng)靈活,絕對(duì)是萬金油
函數(shù)。以上是我總結(jié)的幾種實(shí)用場景,如有哪里寫的不對(duì)或者有更好的建議歡迎大佬指點(diǎn)一二啊。
以上就是vue多功能渲染函數(shù)h()的使用和多種應(yīng)用場景的詳細(xì)內(nèi)容,更多關(guān)于vue渲染函數(shù)h()的用法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Vue開發(fā)自己的Chrome擴(kuò)展程序過程詳解
這篇文章主要介紹了使用Vue開發(fā)自己的Chrome擴(kuò)展程序過程詳解,瀏覽器擴(kuò)展程序是可以修改和增強(qiáng) Web 瀏覽器功能的小程序。它們可用于各種任務(wù),例如阻止廣告,管理密碼,組織標(biāo)簽,改變網(wǎng)頁的外觀和行為等等。,需要的朋友可以參考下2019-06-06vue webpack build資源相對(duì)路徑的問題及解決方法
這篇文章主要介紹了vue webpack build資源相對(duì)路徑的問題,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06vue+quasar使用遞歸實(shí)現(xiàn)動(dòng)態(tài)多級(jí)菜單
這篇文章主要為大家詳細(xì)介紹了vue+quasar使用遞歸實(shí)現(xiàn)動(dòng)態(tài)多級(jí)菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07vue路由跳轉(zhuǎn)打開新窗口(window.open())和關(guān)閉窗口(window.close())
這篇文章主要介紹了vue路由跳轉(zhuǎn)打開新窗口(window.open())和關(guān)閉窗口(window.close())問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04