html
<el-container>
<el-aside width="200px">
<el-menu :default-active="activeTab" @select="handleMenuSelect">
<el-menu-item index="/dashboard">仪表盘</el-menu-item>
<el-menu-item index="/system">系统管理</el-menu-item>
</el-menu>
</el-aside>
<el-container>
<el-header>
<el-tabs v-model="activeTab" @tab-click="handleTabClick" closable @tab-remove="removeTab">
<el-tab-pane
v-for="tab in openedTabs"
:key="tab.path"
:label="tab.title"
:name="tab.path"
/>
</el-tabs>
</el-header>
<el-main>
<router-view />
</el-main>
</el-container>
</el-container>
typescript
const activeTab = ref(route.path)
// 已打开的 Tabs
const openedTabs = ref([
{ path: '/dashboard', title: '仪表盘' }
])
// 菜单标题映射(可从路由 meta 获取)
const getTitle = (path) => {
const map = { '/dashboard': '仪表盘', '/system': '系统管理' }
return map[path] || path
}
// 监听路由变化
watch(
() => route.path,
(newPath) => {
activeTab.value = newPath
if (!openedTabs.value.find(t => t.path === newPath)) {
openedTabs.value.push({ path: newPath, title: getTitle(newPath) })
}
},
{ immediate: true }
)
// 菜单点击
const handleMenuSelect = (path) => {
router.push(path)
}
// Tab 点击
const handleTabClick = (tab) => {
router.push(tab.props.name)
}
// 关闭 Tab
const removeTab = (path) => {
const index = openedTabs.value.findIndex(t => t.path === path)
if (index === -1) return
openedTabs.value.splice(index, 1)
if (path === activeTab.value && openedTabs.value.length > 0) {
router.push(openedTabs.value[openedTabs.value.length - 1].path)
}
}