效果
A.vue
<template>
<div class="com">
你说不会在爱情里犯错
</div>
</template>
<script lang="ts" setup>
</script>
<style lang="less" scoped>
.com {
height: 300px;
border: 2px solid #CCC;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
}
</style>
B
<template>
<div class="com">
也说过会永远的爱我
</div>
</template>
<script lang="ts" setup>
</script>
<style lang="less" scoped>
.com{
height: 300px;
border:2px solid #CCC;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
}
</style>
C
<template>
<div class="com">
才发现只剩下虚伪的承诺
</div>
</template>
<script lang="ts" setup>
</script>
<style lang="less" scoped>
.com{
height: 300px;
border:2px solid #CCC;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
}
</style>
App
<template>
<div style="display: flex">
<div :class="[active === index?'active':'']" class="tabs" v-for="(item,index) in data"
:key="item.name"
@click="switchCom(item,index)">
{{ item.name }}
</div>
</div>
<component :is="comId"></component>
</template>
<style scoped>
#app, html, body {
height: 100%;
}
* {
padding: 0;
margin: 0;
}
.tabs {
border: 1px solid #CCC;
padding: 5px 10px;
margin: 10px;
cursor: pointer;
}
.active {
background: skyblue;
}
</style>
<script setup lang="ts">
import AVue from "./components/A.vue";
import BVue from "./components/B.vue";
import CVue from "./components/C.vue";
import {reactive, ref} from "vue";
const data = reactive([
{
name: "A组件",
com: AVue
},
{
name: "B组件",
com: BVue
},
{
name: "C组件",
com: CVue
}
])
const comId = ref(AVue)
const active = ref(0)
const switchCom = (item: any, index: number) => {
comId.value = item.com
console.log( comId.value)
active.value = index
}
</script>
这里控制台会报错
runtime-core.esm-bundler.js:40 [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: {__hmrId: '65097ce7', __scopeId: 'data-v-65097ce7', __file: 'H:/develop/project/web/learn/vite-demo/src/components/A.vue', render: ƒ}
at <App>
不过没关系 我们可以按照建议使用 markRaw 和 shallowRef 来避免报错 来正确应用这些组件
最后代码
<template>
<div style="display: flex">
<div :class="[active === index?'active':'']" class="tabs" v-for="(item,index) in data"
:key="item.name"
@click="switchCom(item,index)">
{{ item.name }}
</div>
</div>
<component :is="comId"></component>
</template>
<style scoped>
#app, html, body {
height: 100%;
}
* {
padding: 0;
margin: 0;
}
.tabs {
border: 1px solid #CCC;
padding: 5px 10px;
margin: 10px;
cursor: pointer;
}
.active {
background: skyblue;
}
</style>
<script setup lang="ts">
import AVue from "./components/A.vue";
import BVue from "./components/B.vue";
import CVue from "./components/C.vue";
import {markRaw, reactive, ref, shallowRef} from "vue";
const data = reactive([
{
name: "A组件",
com: markRaw(AVue)
},
{
name: "B组件",
com: markRaw(BVue)
},
{
name: "C组件",
com: markRaw(CVue)
}
])
const comId = shallowRef(AVue)
const active = ref(0)
const switchCom = (item: any, index: number) => {
comId.value = item.com
console.log(comId.value)
active.value = index
}
</script>
还有一种比较类似vue2的写法。先引入组件再使用字符串就行啦
<template>
<div style="display: flex">
<div :class="[active === index?'active':'']" class="tabs" v-for="(item,index) in data"
:key="item.name"
@click="switchCom(item,index)">
{{ item.name }}
</div>
</div>
<component :is="comId"></component>
</template>
<style scoped>
#app, html, body {
height: 100%;
}
* {
padding: 0;
margin: 0;
}
.tabs {
border: 1px solid #CCC;
padding: 5px 10px;
margin: 10px;
cursor: pointer;
}
.active {
background: skyblue;
}
</style>
<script setup lang="ts">
import {markRaw, reactive, ref, shallowRef} from "vue";
const data = reactive([
{
name: "A组件",
com: 'AVue'
},
{
name: "B组件",
com: 'BVue'
},
{
name: "C组件",
com: 'CVue'
}
])
const comId = shallowRef("AVue")
const active = ref(0)
const switchCom = (item: any, index: number) => {
comId.value = item.com
console.log(comId.value)
active.value = index
}
</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>