vue手把手带你撸项目系列之动态面包屑

x33g5p2x  于11个月前 转载在 Vue.js  
字(2.1k)|赞(0)|评价(0)|浏览(120)

常见方式

首先我们想到的最笨的方法就是在每个需要面包屑的页面中固定写好

<template>
	<div class="example-container">
		<el-breadcrumb separator="/">
			<el-breadcrumb-item
				v-for="(item, index) in breadList"
				:key="index"
				:to="{ path: item.path }"
			>
			{{item.name}}
			</el-breadcrumb-item>
		</el-breadcrumb>
	</div>
</template>

<script>
	export default {
		name: 'Example',
		data () {
			return {
				breadList: [
					{
						name: '首页',
						path: '/home'
					},
					{
						name: '系统设置',
						path: '/setting'
					},
					{
						name: '用户管理',
						path: '/setting/usermanage'
					}
				]
			}
		}
	}
</script>

如果按照上述方式去实行的话,虽然我们可以完成面包屑的功能,但是它不够灵活,在每个需要的页面添加,带来的维护成本是巨大的

利用 路由元信息

我们可以把路径结构配置在 Route meta 属性中

const router = new Router({
	routes: [{
		path: 'example',
		name: 'example',
		component: Example,
		meta: {
			breadList: [
				{name: '首页', path: '/home'},
				{name: '系统设置', path: 'setting'},
				{name: '用户管理', path: 'setting/usermanage'}
			]
		}
	}]
})
export default router;

然后我们直接在页面中使用计算属性获取数据

<template>
	// ...省略
</template>

<script>
	export default {
		name: 'Example',
		computed: {
			breadList () {
				return this.$route.meta.breadList || [];
			}
		}
	}
<script>

这样也能实现我要想的效果,但是这个还是显得比较冗余,路由数据已经定义好一次结构,还要加上一个专门的面包屑数据,造成代码的重复

利用路由对象 matched 属性

matched:返回一个数组,包含当前路由的所有嵌套路径片段的路由记录
可以看到当我们定义好路由结构以后,我们就可以获取到当前页面的路由记录

首先我们先创建一个面包屑的组件

// Breadcrumb.vue
<script>
	export default {
		data () {
			return {
				breadList: [] // 路由集合
			}
		},
		watch: {
			$route () {
				this.getBreadcrumb();
			}
		},
		methods: {
			isHome (route) {
				return route.name === 'home';
			}
			getBreadcrumb() {
				let matched = this.$route.matched;
				// 如果不是首页
				if (!this.isHome(matched[0])) {
					matched = [{path: '/home', meta: {title: '首页'}}].concat(matched);
				}
				this.breadList = matched;
			}
		},
		created () {
			this.getBreadcrumb();
		}
	}
</script>

创建完组件之后,在需要的地方注入即可。如果你的网页结构布局合理恰当的话只需要一处引用就可以所有网页使用啦

定义的路由信息如下:

const router = new Router({
	routes: [
		{ path: '/', redirect: '/home' },
		{ path: '/home', name: 'home', component: Home, meta: { title: '首页' }},
		{
			path: '/setting',
			name: 'setting',
			component: () => import('./views/setting/Setting.vue'),
			redirect: '/setting/user',
			meta: { title: '系统设置'},
			children: [
				{
					path: 'user',
					component: () => import('./views/setting/UserManage.vue'),
					name: 'usermanage',
					meta: { title: '用户管理' }
				}
			]
		}
	]
});
export default router;

可以看到我们非常灵活的实现出我们需要的效果。可能这个功能并没有完善,比如有些页面不需要怎么办?

其实只要我们过滤下数据就可以实现,比如利用 meta 不存在时面包屑数据置空,或者增加一个数据标示面包屑的现实隐藏

相关文章