|
|
@@ -0,0 +1,65 @@
|
|
|
+<template>
|
|
|
+ <!-- 创建一个面包屑导向组件,设置分隔符为 /, 并添加一些样式 -->
|
|
|
+ <el-breadcrumb separator="/" class="breadcrumb">
|
|
|
+ <el-breadcrumb-item v-for="(route, index) in list" :key="route.path">
|
|
|
+ <span v-if="list.length - 1 === index"> {{ route.meta?.title }}</span>
|
|
|
+ <a v-else @click="handleLink(route)">{{ route.meta?.title }}</a>
|
|
|
+ </el-breadcrumb-item>
|
|
|
+ </el-breadcrumb>
|
|
|
+</template>
|
|
|
+<script lang="ts" setup>
|
|
|
+import router from "@/router";
|
|
|
+import type { RouteLocationMatched } from "vue-router";
|
|
|
+import { compile } from "path-to-regexp";
|
|
|
+// 定义 PartialRouteLocationMatched 类型,只取 RouteLocationMatched 的部分属性
|
|
|
+type PartialRouteLocationMatched = Partial<RouteLocationMatched>;
|
|
|
+// 获取当前路由
|
|
|
+const currentRoute = useRoute();
|
|
|
+// 定义响应式变量 List,用于存储面包屑导航列表
|
|
|
+const list = ref<PartialRouteLocationMatched[]>([]);
|
|
|
+// 定义获取面包屑导航列表的函数
|
|
|
+const getBreadCrumb = () => {
|
|
|
+ // 过虑出有 meta.title 属性的路由匹配
|
|
|
+ let matched = currentRoute.matched.filter(
|
|
|
+ (item) => item.meta.title
|
|
|
+ ) as PartialRouteLocationMatched[];
|
|
|
+ // 如果当前访问的不是首页,在面包屑列表开头添加首页项
|
|
|
+ if (matched[0]?.path !== "/dashboard") {
|
|
|
+ matched = [
|
|
|
+ {
|
|
|
+ path: "/dashboard",
|
|
|
+ meta: {
|
|
|
+ title: "dashboard"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ...matched
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ // 过滤掉 meta.breadcrumb 为 false 的路由匹配项
|
|
|
+ list.value = matched.filter((item) => item.meta?.breadcrumb !== false);
|
|
|
+};
|
|
|
+
|
|
|
+// 监听路由路由路径变化,当路径变化时调用 getBreadCrumb 函数
|
|
|
+watch(() => currentRoute.path, getBreadCrumb, { immediate: true });
|
|
|
+
|
|
|
+// 定义编译路径的函数,根据路径模板和当前路由参数生成完整路径
|
|
|
+function compilePath(path: string) {
|
|
|
+ const params = currentRoute.params; // 当前路由参数
|
|
|
+ const regex = compile(path); // 编译路径模板为正则表达式
|
|
|
+ return regex(params); // 根据当前路由参数替换路径模板中的参数
|
|
|
+}
|
|
|
+// 定义处理面包屑项点击事件的函数
|
|
|
+function handleLink(route: PartialRouteLocationMatched) {
|
|
|
+ const { path, redirect } = route;
|
|
|
+ if (redirect) {
|
|
|
+ router.push(redirect as string);
|
|
|
+ } else {
|
|
|
+ router.push(compilePath(path!));
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.breadcrumb {
|
|
|
+ @apply leading-50px text-lg ml-30px inline-block;
|
|
|
+}
|
|
|
+</style>
|