index.vue 2.3 KB

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