Vue3中的動(dòng)態(tài)組件詳解
Vue3動(dòng)態(tài)組件
動(dòng)態(tài)組件的基本使用
動(dòng)態(tài)組件(Dynamic Components)是一種在 Vue 中根據(jù)條件或用戶輸入來(lái)動(dòng)態(tài)渲染不同組件的技術(shù)。
在 Vue 中使用動(dòng)態(tài)組件,可以使用 <component>
元素,并通過(guò) is 特性綁定一個(gè)組件的名稱或組件對(duì)象。通過(guò)在父組件中改變 is 特性的值,可以動(dòng)態(tài)切換渲染的組件。
第一種寫法
- A.vue
<template> <div> A component </div> </template> <script setup lang="ts"> </script> <style scoped></style>
B.vue, C.vue 同理
- APP.vue
<template> <div style="display: flex;"> <!-- class可以寫兩個(gè),一個(gè)靜態(tài),一個(gè)動(dòng)態(tài) --> <div @click="switchCom(item, index)" :class="[active == index ? 'active' : '']" class="tabs" v-for="(item, index) in data"> <div>{{ item.name }}</div> </div> </div> <component :is="comId"></component> </template> <script setup lang="ts"> import { ref, reactive } from 'vue'; import AVue from './components/A.vue' import BVue from './components/B.vue' import CVue from './components/C.vue' // 這里不需要將對(duì)象中所有數(shù)據(jù)變?yōu)轫憫?yīng)式,可以使用ref const comId = ref(AVue) const active = ref(0) const switchCom = (item, index) => { comId.value = item.com active.value = index } const data = reactive([ { name: 'A', com: AVue }, { name: 'B', com: BVue }, { name: 'C', com: CVue } ]) </script> <style lang="scss" scoped> .active { background: blueviolet; } .tabs { border: 1px solid #ccc; padding: 5px 10px; margin: 5px; cursor: pointer; } </style>
第二種寫法
- APP.vue
<template> <div style="display: flex;"> <!-- class可以寫兩個(gè),一個(gè)靜態(tài),一個(gè)動(dòng)態(tài) --> <div @click="switchCom(item, index)" :class="[active == index ? 'active' : '']" class="tabs" v-for="(item, index) in data"> <div>{{ item.name }}</div> </div> </div> <component :is="comId"></component> </template> <script setup lang="ts"> // markRaw:作用:標(biāo)記一個(gè)對(duì)象,使其永遠(yuǎn)不會(huì)再成為響應(yīng)式對(duì)象。 import { ref, reactive, markRaw, shallowRef } from 'vue'; // 這里不需要將對(duì)象中所有數(shù)據(jù)變?yōu)轫憫?yīng)式,可以使用ref const comId = shallowRef('AVue') const active = ref(0) const switchCom = (item, index) => { comId.value = item.com console.log(comId.value); active.value = index } const data = reactive([ { name: 'A', com:'AVue' }, { name: 'B', com:'BVue' }, { name: 'C', com:'CVue' } ]) </script> <script lang="ts"> import AVue from './components/A.vue' import BVue from './components/B.vue' import CVue from './components/C.vue' export default { components: { AVue, BVue, CVue } } </script> <style lang="scss" scoped> .active { background: blueviolet; } .tabs { border: 1px solid #ccc; padding: 5px 10px; margin: 5px; cursor: pointer; } </style>
性能優(yōu)化
上述第一種寫法代碼會(huì)出現(xiàn)警告
輸出 comId 的值,出現(xiàn) comId 的屬性被劫持,出現(xiàn)性能浪費(fèi)
解決方法
使用markRaw
和shallowRef
這兩個(gè)API
- App.vue
<template> <div style="display: flex;"> <!-- class可以寫兩個(gè),一個(gè)靜態(tài),一個(gè)動(dòng)態(tài) --> <div @click="switchCom(item, index)" :class="[active == index ? 'active' : '']" class="tabs" v-for="(item, index) in data"> <div>{{ item.name }}</div> </div> </div> <component :is="comId"></component> </template> <script setup lang="ts"> // markRaw:作用:標(biāo)記一個(gè)對(duì)象,使其永遠(yuǎn)不會(huì)再成為響應(yīng)式對(duì)象。 import { ref, reactive, markRaw, shallowRef } from 'vue'; import AVue from './components/A.vue' import BVue from './components/B.vue' import CVue from './components/C.vue' // 這里不需要將對(duì)象中所有數(shù)據(jù)變?yōu)轫憫?yīng)式,可以使用ref const comId = shallowRef(AVue) const active = ref(0) const switchCom = (item, index) => { comId.value = item.com console.log(comId.value); active.value = index } const data = reactive([ { name: 'A', com: markRaw(AVue) }, { name: 'B', com: markRaw(BVue) }, { name: 'C', com: markRaw(CVue) } ]) </script> <style lang="scss" scoped> .active { background: blueviolet; } .tabs { border: 1px solid #ccc; padding: 5px 10px; margin: 5px; cursor: pointer; } </style>
再次輸出 comId 的值,解決性能浪費(fèi)的問(wèn)題
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
第一次使用webstrom簡(jiǎn)單創(chuàng)建vue項(xiàng)目的一些報(bào)錯(cuò)實(shí)戰(zhàn)記錄
在使用webstorm新建vue項(xiàng)目時(shí)常會(huì)遇到一些報(bào)錯(cuò),特別是新手第一次運(yùn)行項(xiàng)目,這篇文章主要給大家介紹了關(guān)于第一次使用webstrom簡(jiǎn)單創(chuàng)建vue項(xiàng)目的一些報(bào)錯(cuò)實(shí)戰(zhàn)記錄,需要的朋友可以參考下2023-02-02詳解vue-cli項(xiàng)目中怎么使用mock數(shù)據(jù)
這篇文章主要介紹了vue-cli項(xiàng)目中怎么使用mock數(shù)據(jù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05vue項(xiàng)目中如何將當(dāng)前頁(yè)面生成圖片
這篇文章主要介紹了vue項(xiàng)目中如何將當(dāng)前頁(yè)面生成圖片問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10關(guān)于VUE點(diǎn)擊父組件按鈕跳轉(zhuǎn)到子組件的問(wèn)題及解決方案
本文主要介紹了在Vue框架中,如何通過(guò)父組件的點(diǎn)擊事件打開(kāi)子組件中的彈窗并展示表格內(nèi)容,主要步驟包括在父組件中定義數(shù)據(jù)屬性,創(chuàng)建并定義子組件的彈窗和表格內(nèi)容,通過(guò)props屬性和自定義事件實(shí)現(xiàn)父子組件間的數(shù)據(jù)傳遞和方法調(diào)用2024-10-10Vue實(shí)現(xiàn)tab切換的兩種方法示例詳解
這篇文章主要介紹了Vue實(shí)現(xiàn)tab切換的兩種方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-11-11VUE 單頁(yè)面使用 echart 窗口變化時(shí)的用法
這篇文章主要介紹了VUE 單頁(yè)面使用 echart 窗口變化時(shí)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07詳解vue-cli 3.0 build包太大導(dǎo)致首屏過(guò)長(zhǎng)的解決方案
這篇文章主要介紹了詳解vue-cli 3.0 build包太大導(dǎo)致首屏過(guò)長(zhǎng)的解決方案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11基于Vue3實(shí)現(xiàn)前端埋點(diǎn)上報(bào)插件并打包發(fā)布到npm的詳細(xì)過(guò)程
這篇文章主要介紹了基于Vue3實(shí)現(xiàn)一個(gè)前端埋點(diǎn)上報(bào)插件并打包發(fā)布到npm,本項(xiàng)目采用pnpm進(jìn)行Monorepo環(huán)境搭建,因?yàn)槲磥?lái)這個(gè)項(xiàng)目可能會(huì)加入更多的工具包,需要的朋友可以參考下2022-10-10