开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
前言
面包屑效果如下
以上效果可以使用两种方法实现
- 静态面包屑
- 动态面包屑
静态面包屑指在每个页面中写死对应值,如此的话每个页面都需要写一遍,如果新增页面,还需要手动更改面包屑的值,过程繁琐且不好维护
使用动态面包屑,就可以根据当前路由的变化动态生成当前的面包屑,再也不需要手动添加。
实现
基本结构
首先先写固定的值实现面包屑的基本样式
components/Breadcrumb/index
<template>
<el-breadcrumb class="breadcrumb" separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<!-- 面包屑的最后一项 -->
<el-breadcrumb-item>
<span class="no-redirect">人员列表</span>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
数据处理
要实现动态渲染,需要获取动态数据,我们可以用数组保存动态数据,动态面包屑的每一项为数组的一个值
components/Breadcrumb/index
<script setup>
import { ref } from 'vue'
// 面包屑数据
const breadcrumbData = ref([])
</script>
我们希望根据路由的变化,生成不同的面包屑数据,所以可以监听路由的变化,之后去获取路由变化后的面包屑数据,getBreadcrumbData为获取面包屑数据的方法
components/Breadcrumb/index
<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
// 监听路由变化时触发
watch(
route,
() => {
getBreadcrumbData()
},
{
immediate: true
}
)
</script>
接下来去完成getBreadcrumbData方法的处理
处理数据时需要用的route.matched()
route.matched
1: 一个数组,包含当前路由的所有嵌套路径片段的路由记录
2: 一个路由匹配到的所有路由记录会暴露为 route 对象 (还有在导航守卫中的路由对象) 的 route.matched 数组
如当前地址为http://localhost:8080/#/user/role
在控制台打印route.matched
就可以拿到每一项的路由元信息,其中保存有title值
接下来处理getBreadcrumbData方法
const getBreadcrumbData = () => {
// 筛选出存在title的路由
breadcrumbData.value = route.matched.filter(
(item) => item.meta && item.meta.title
)
}
渲染
遍历breadcrumbData渲染,注意数组最后一项有不同的样式,用v-if判断是否是最后一项,使用不同的类名渲染不同的样式,每一项的值为路由元信息中的title
<template>
<el-breadcrumb separator="/" class="breadcrumb">
// 动画
<transition-group name="breadcrumb">
<el-breadcrumb-item
v-for="(item, index) in breadcrumbData"
:key="item.path"
>
<!-- 不可点击 -->
<span class="no-redirect" v-if="index === breadcrumbData.length - 1">{{
generateTitle(item.meta.title)
}}</span>
<!-- 可点击 -->
<span class="redirect" v-else @click="onLinkClick(item)">{{
generateTitle(item.meta.title)
}}</span>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
补充一下generateTitle方法为处理国际化
import i18n from '@/i18n'
export function generateTitle(title) {
return i18n.global.t('msg.route.' + title)
}