index.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <template>
  2. <el-breadcrumb class="h-[70px] flex items-center">
  3. <transition-group name="breadcrumb">
  4. <el-breadcrumb-item v-for="(item, index) in breadcrumbs" :key="item.path">
  5. <span
  6. v-if="
  7. item.redirect === 'noredirect' || index === breadcrumbs.length - 1
  8. "
  9. >{{ item.meta.title }}</span
  10. >
  11. <a v-else @click.prevent="handleLink(item)">
  12. {{ item.meta.title }}
  13. </a>
  14. </el-breadcrumb-item>
  15. </transition-group>
  16. </el-breadcrumb>
  17. </template>
  18. <script setup lang="ts">
  19. import { onBeforeMount, ref, watch } from "vue";
  20. import { useRoute, RouteLocationMatched } from "vue-router";
  21. import { compile } from "path-to-regexp";
  22. import router from "@/router";
  23. const currentRoute = useRoute();
  24. const pathCompile = (path: string) => {
  25. const { params } = currentRoute;
  26. const toPath = compile(path);
  27. return toPath(params);
  28. };
  29. const breadcrumbs = ref([] as Array<RouteLocationMatched>);
  30. function getBreadcrumb() {
  31. let matched = currentRoute.matched.filter(
  32. (item) => item.meta && item.meta.title
  33. );
  34. const first = matched[0];
  35. if (!isDashboard(first)) {
  36. matched = [{ path: "/dashboard" } as any].concat(matched);
  37. }
  38. breadcrumbs.value = matched.filter((item) => {
  39. return item.meta && item.meta.title && item.meta.breadcrumb !== false;
  40. });
  41. }
  42. function isDashboard(route: RouteLocationMatched) {
  43. const name = route && route.name;
  44. if (!name) {
  45. return false;
  46. }
  47. return (
  48. name.toString().trim().toLocaleLowerCase() ===
  49. "Dashboard".toLocaleLowerCase()
  50. );
  51. }
  52. function handleLink(item: any) {
  53. const { redirect, path } = item;
  54. if (redirect) {
  55. router.push(redirect).catch((err) => {
  56. console.warn(err);
  57. });
  58. return;
  59. }
  60. router.push(pathCompile(path)).catch((err) => {
  61. console.warn(err);
  62. });
  63. }
  64. watch(
  65. () => currentRoute.path,
  66. (path) => {
  67. if (path.startsWith("/redirect/")) {
  68. return;
  69. }
  70. getBreadcrumb();
  71. }
  72. );
  73. onBeforeMount(() => {
  74. getBreadcrumb();
  75. });
  76. </script>
  77. <style lang="scss" scoped>
  78. .app-breadcrumb.el-breadcrumb {
  79. display: inline-block;
  80. margin-left: 8px;
  81. font-size: 18px;
  82. line-height: 70px;
  83. }
  84. .items-center span {
  85. font-size: 16px;
  86. }
  87. // 覆盖 element-plus 的样式
  88. .el-breadcrumb__inner,
  89. .el-breadcrumb__inner a {
  90. font-weight: 400 !important;
  91. }
  92. </style>