vue3+ts+vite 动态组件保姆级教程

什么是动态组件

让多个组件使用同一个挂载点,并动态切换,这就是动态组件

怎么用

第一种用法:

<template>
    <div class="tab-class">
        <div
            v-for="(item, index) in tabsList"
            @click="clickTab(item, index)"
            :class="[index == comIndex ? 'active' : '']"
        >
            {{ item.name }}
        </div>
    </div>
    <component :is="tabKey" class="tab-class" />
</template>

<script setup lang="ts">
import { reactive, ref, markRaw, shallowRef } from "vue"
import AVue from "./views/demo/A.vue"
import BVue from "./views/demo/B.vue"
import CVue from "./views/demo/C.vue"

const tabsList = reactive([
    { name: "A组件", comName: markRaw(AVue) },
    { name: "B组件", comName: markRaw(BVue) },
    { name: "C组件", comName: markRaw(CVue) },
])
const tabKey = ref(markRaw(AVue))
const comIndex = shallowRef(0)
const clickTab = (item: any, index: number) => {
    tabKey.value = item?.comName
    comIndex.value = index
}
</script>
<style scoped lang="scss">
.active {
    background-color: skyblue;
}
.tab-class {
    width: 100%;
    display: flex;
    padding: 20px;
    div {
        border: 1px solid;
        padding: 10px;
        cursor: pointer;
    }
}
</style>
注意:
1.在Vue2 的时候is 是通过组件名称切换的 在Vue3 setup 是通过组件实例切换的
2.如果你把组件实例放到Reactive Vue会给你一个警告runtime-core.esm-bundler.js:38 [Vue warn]: 
	Vue received a Component which was made a reactive object. This can lead to 
	unnecessary performance 			
	overhead, and should be avoided by marking the component with `markRaw` or
	 using `shallowRef` instead of `ref`. 
	Component that was made reactive: 
这是因为reactive 会进行proxy 代理 而我们组件代理之后毫无用处 节省性能开销 
推荐我们使用shallowRef 或者  markRaw 跳过proxy 代理

第二种用法:

<template>
    <div class="tab-class">
        <div
            v-for="(item, index) in tabsList"
            @click="clickTab(item, index)"
            :class="[index == comIndex ? 'active' : '']"
        >
            {{ item.name }}
        </div>
    </div>
    <component :is="tabKey" class="tab-class" />
</template>

<script setup lang="ts">
import { reactive, ref, shallowRef } from "vue"
const tabsList = reactive([
    { name: "A组件", comName: "AVue" },
    { name: "B组件", comName: "BVue" },
    { name: "C组件", comName: "CVue" },
])
const tabKey = ref("AVue")
const comIndex = shallowRef(0)
const clickTab = (item: any, index: number) => {
    tabKey.value = item?.comName
    comIndex.value = index
}
</script>
<script lang="ts">
import AVue from "./views/demo/A.vue"
import BVue from "./views/demo/B.vue"
import CVue from "./views/demo/C.vue"
export default {
    components: {
        AVue,
        BVue,
        CVue,
    },
}
</script>
<style scoped lang="scss">
.active {
    background-color: skyblue;
}
.tab-class {
    width: 100%;
    display: flex;
    padding: 20px;
    div {
        border: 1px solid;
        padding: 10px;
        cursor: pointer;
    }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值