实现思路:
方法一:三个组件(navMenu组件、breadcrumb组件、tabs按钮)都用watch监听地址栏的路由信息变化,只要路由信息变了,其他三者就变化,
navMenu组件代码:
<template>
<div id="aside">
<el-menu
:default-active="activeMenu"
class="el-menu-vertical-demo"
:collapse="collapse"
:collapse-transition="false"
text-color="black"
active-text-color="#ffd04b"
>
<el-menu-item
:index="v.name"
v-for="v in noChildren"
:key="v.name"
@click="clickMenu(v)"
>
<i :class="`el-icon-${v.icon}`"></i>
<span slot="title">{{ v.label }}</span>
</el-menu-item>
<el-submenu :index="v.name" v-for="v in hasChildren" :key="v.name">
<template slot="title">
<i :class="`el-icon-${v.icon}`"></i>
<span slot="title">{{ v.label }}</span>
</template>
<el-menu-item-group
v-for="value in v.children"
:key="value.name"
>
<el-menu-item :index="value.name" @click="clickMenu(value)"
>
<i :class="`el-icon-${value.icon}`"></i>
{{ value.label }}
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</div>
</template>
<script>
export default {
name: 'App',
props: {
collapse: {
type: Boolean,
default: true,
},
},
data() {
return {
menu: [
{
path: '/home',
name: 'home',
label: '首页',
icon: 's-home',
url: 'Home.vue',
},
{
path: '/mall',
name: 'mall',
label: '商品管理',
icon: 'video-play',
url: 'Mall.vue',
},
{
path: '/user',
name: 'user',
label: '用户管理',
icon: 'user',
url: 'User.vue',
},
{
label: '其他',
icon: 'location',
name:'other',
children: [
{
path: '/page1',
name: 'page1',
label: '页面1',
icon: 'edit',
url: 'Other/PageOne',
},
{
path: '/page2',
name: 'page2',
label: '页面2',
icon: 'share',
url: 'Other/pageTwo',
},
],
},
],
activeMenu: '',
}
},
methods: {
clickMenu(item) {
if (
this.$route.path !== item.path &&
!(this.$route.path === '/home' && item.path === '/')
) {
// 同页面的路由进行跳转
this.$router.push(item.path)
// this.activeMenu=item.label
}
},
},
mounted() {},
computed: {
hasChildren() {
return this.menu.filter((item) => item.children)
},
noChildren() {
return this.menu.filter((item) => !item.children)
},
},
watch: {
$route: {
handler: function (to) {
this.activeMenu=to.name
},
deep: true,
},
},
}
</script>
<style lang="less">
.el-menu-vertical-demo > li:first-child {
border-right: 3px solid red;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 100vh;
}
</style>
breadcrumb面包屑组件:
<template>
<!-- 面包屑 -->
<el-breadcrumb separator="/" class="breadcrumb">
<el-breadcrumb-item
v-for="(item, index) in breadcrumb"
:key="index"
>
{{ item.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
data() {
return {
breadcrumb: [],
}
},
created() {
this.generateBreadcrumb(this.$route)
},
watch: {
$route(to) {
this.generateBreadcrumb(to)
},
},
methods: {
generateBreadcrumb(route) {
// console.log("route", route)
const matched = route.matched
this.breadcrumb = matched
},
},
}
</script>
<style lang="less">
.breadcrumb {
font-size: 16px;
display: flex;
line-height: 63px;
margin-left: -14px;
.el-breadcrumb__item:last-child .el-breadcrumb__inner {
color: white;
}
}
</style>
tabs按钮组件:
<template>
<div class="tabMenu_div">
<el-tabs
v-model="activeTab"
type="card"
@tab-click="handleTabClick"
@tab-remove="handleTabClose"
>
<el-tab-pane
:key="item.name"
v-for="(item, index) in tabs"
:label="item.label"
:name="item.name"
:closable="tabs.length !== 1"
>
<!-- {{ item.label }} -->
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
export default {
data() {
return {
activeTab: '',
tabs: [{
label: '首页',
name: 'home',
// path: '/home',
}],
tabIndex: 2,
}
},
created() {
// this.$bus.$on('addTab', (menuItem) => {
// this.handleMenuClick(menuItem)
// })
},
methods: {
handleMenuClick(menuItem) {
// console.log(menuItem,'this.menuItem')
let existingTab = this.tabs.find(
(tab) => tab.name === menuItem.name
)
if (existingTab) {
// console.log(existingTab,'this.activeTab')
this.activeTab = existingTab.name // 切换到已存在的tab
} else {
this.tabs.push({
label: menuItem.meta.title,
name: menuItem.name,
path: menuItem.path,
// content: menuItem.name,
})
this.activeTab = menuItem.name // 设置新添加的tab为当前激活的tab
}
// }
},
handleTabClose(tabName) {
// console.log(tabName,'this.tabName')
// console.log(this.$route,'this.$route')
// console.log(this.tabs,'this.tabs')
this.tabs = this.tabs.filter((tab) => tab.name !== tabName)
// 点击删除当下路由的tab按钮时,路由自动跳转到首页
if(this.$route.name===tabName){
this.$router.push({ name: this.tabs[0].name })
// console.log(this.$route,'this.$route')
this.activeTab = this.$route.name
// console.log(this.activeTab,'activeTab')
}
},
handleTabClick(tab) {
if (
this.$route.name !== tab.name &&
!(this.$route.path === '/home' && tab.name === 'home')
) {
this.$router.push({ name: tab._props.name })
}
// this.$bus.$emit('menu-select', tab) // 通知兄弟组件更新navMenu的选中状态
},
},
watch: {
$route: {
handler: function (to) {
this.handleMenuClick(to)
},
deep: true,
},
},
}
</script>
<style scoped lang="less"></style>
方法二:通过自定义事件,在点击navMenu侧边栏菜单,将点击的信息传到其他两个组件,同样在点击tabs按钮时,将点击信息传到navMenu组件,这样就可以实现