第十七节:面包屑导航组件(适配多级嵌套路由)
🎯本节目标
实现页面顶部面包屑,自动跟随当前路由变化;支持多级路由自动生成层级;路由切换自动更新;和 layout 布局融合。
文件路径:src/layout/components/Breadcrumb.vue
步骤 1:新建面包屑组件 Breadcrumb.vue
<template>
<div class="breadcrumb-wrap">
<!-- element-plus面包屑组件 -->
<el-breadcrumb separator="/">
<!-- 遍历面包屑数组 -->
<el-breadcrumb-item
v-for="item in breadcrumbList"
:key="item.path"
:to="{ path: item.path }"
>
{{ item.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
/**
* 计算属性:生成面包屑数组
* route.matched 路由匹配数组,包含当前路由所有父级路由
*/
const breadcrumbList = computed(() => {
// matched:匹配到的完整路由链,从根到当前页面
return route.matched.filter(item => {
// 过滤掉没有meta.title的路由,不渲染
return item.meta && item.meta.title
}).map(item => {
return {
path: item.path,
title: item.meta.title
}
})
})
</script>
<style scoped>
.breadcrumb-wrap {
padding: 0 15px;
height: 50px;
display: flex;
align-items: center;
background: #fff;
}
</style>
核心原理:
$route.matched,路由自带属性,会拿到当前页面全部父级路由,不用自己递归处理菜单数据,路由跳转自动更新。
步骤 2:在布局主文件 layout/index.vue 引入面包屑
打开 src/layout/index.vue
<template>
<div class="layout-container">
<!-- 侧边栏 -->
<Sidebar class="sidebar" />
<div class="main-wrapper">
<!-- 顶部导航栏 -->
<div class="navbar">
<!-- ✅引入面包屑组件 -->
<Breadcrumb />
<div class="navbar-right">
<!-- 折叠按钮、用户头像、退出登录原有代码保留 -->
</div>
</div>
<!-- 主内容区域 -->
<main class="app-main">
<router-view v-slot="{ Component }">
<component :is="Component" />
</router-view>
</main>
</div>
</div>
</template>
<script setup>
import Sidebar from './components/SidebarMenu.vue'
import Breadcrumb from './components/Breadcrumb.vue'
// ...其余原有导入代码全部保留
</script>
<style>
/* 原有layout样式不变 */
</style>
步骤 3:测试效果
- 保存全部文件,重启
pnpm dev,重新登录 - 进入工作台:面包屑显示
/ 工作台 - 打开系统管理 → 用户列表:面包屑自动生成
/系统管理 /用户列表 - 切换菜单,面包屑实时跟随变化;点击面包屑可以跳转到对应父页面。
常见坑
- 路由必须配置
meta:{ title:'xxx' },没有 title 的路由不会出现在面包屑; - Layout 布局路由不需要写 title,子路由写 title 即可;
- 如果面包屑不更新:确认组件使用
computed监听route.matched,不要写死固定数组。
拓展:和标签页(TagsView)联动小说明
下一节我们就做标签页组件,点击菜单自动新增标签页,支持关闭标签。
