完整代码
<script setup>
import ComponentA from './components/ComponentA.vue'
import ComponentB from './components/ComponentB.vue'
import ComponentC from './components/ComponentC.vue'
import ComponentD from './components/ComponentD.vue'
import { ref, computed } from 'vue'
// 动态组件映射
const componentMap = {
ComponentA,
ComponentB,
ComponentC,
ComponentD
}
const tabs = [
{
name: 'ComponentA,
label: '组件A'
},
{
name: 'ComponentB',
label: '组件B'
},
{
name: 'ComponentC',
label: '组件C'
},
{
name: 'ComponentD',
label: '组件D'
}
]
const currentComponent = ref('ComponentA')
const dynamicMessage = ref('Hello from Parent Component!')
// 计算属性,返回当前的组件对象
const CurrentComponent = computed(() => componentMap[currentComponent.value])
const onChange = (name) => {
currentComponent.value = name
}
</script>
<template>
<div class="detail-view">
<div class="header">
<div
v-for="(item, index) in tabs"
:key="index"
class="tab"
:class="{ active: item.name === currentComponent }"
@click="onChange(item.name)"
>
<div class="icon"></div>
<div class="text">{{ item.label }}</div>
</div>
</div>
<keep-alive>
<component :is="CurrentComponent" :message="dynamicMessage" class="container" />
</keep-alive>
</div>
</template>
<style lang="scss" scoped>
.detail-view {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border-bottom: 1px solid rgba(187, 187, 187, 0.19);
.tab {
width: 48px;
height: 24px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: bold;
border: 1px solid #f2f0f7;
border-radius: 24px;
background-color: #f9f8fe;
&.active {
color: #fff;
background-color: #9965f7;
}
}
}
.container {
flex: 1;
}
</style>