神级思路:navMenu侧边栏、breadcrumb面包屑、tabs按钮和地址栏路由信息,如何实现一个变化,其他三个都随之变化

 实现思路:

方法一:三个组件(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组件,这样就可以实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值