index.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <template>
  2. <el-breadcrumb class="h-[50px] flex items-center">
  3. <transition-group name="breadcrumb-transition">
  4. <el-breadcrumb-item v-for="(item, index) in breadcrumbs" :key="item.path">
  5. <span v-if="item.redirect === 'noredirect' || index === breadcrumbs.length - 1" class="text-[var(--el-disabled-text-color)]">
  6. {{ translateRouteTitle(item.meta.title) }}
  7. </span>
  8. <a v-else @click.prevent="handleLink(item)">
  9. {{ translateRouteTitle(item.meta.title) }}
  10. </a>
  11. </el-breadcrumb-item>
  12. </transition-group>
  13. </el-breadcrumb>
  14. </template>
  15. <script setup>
  16. import { get } from 'lodash-es'
  17. import { onBeforeMount, ref, watch } from 'vue'
  18. import { useRoute } from 'vue-router'
  19. import { compile } from 'path-to-regexp'
  20. import { translateRouteTitle } from '@/utils/i18n'
  21. import router from '@/router'
  22. import { UserStore } from '@/store/user'
  23. const userStore = UserStore()
  24. const menus = computed(() => userStore.menus)
  25. const currentRoute = useRoute()
  26. const pathCompile = (path) => {
  27. const { params } = currentRoute
  28. const toPath = compile(path)
  29. return toPath(params)
  30. }
  31. const breadcrumbs = ref([])
  32. function getBreadcrumb() {
  33. let matched = currentRoute.matched.filter((item) => item.meta && item.meta.title)
  34. let menus = matched.map((i) => getMenu(i))
  35. const first = menus[0]
  36. if (!isDashboard(first)) {
  37. menus = [{ path: '/', meta: { title: '首页' } }].concat(matched)
  38. }
  39. breadcrumbs.value = menus.filter((item) => {
  40. return item.meta && item.meta.title && item.meta.breadcrumb !== false
  41. })
  42. }
  43. const getMenu = (route) => {
  44. const menu = menus.value.find((f) => f.path === route.path)
  45. if (menu) route.meta.title = get(menu, 'name')
  46. return route
  47. }
  48. function isDashboard(route) {
  49. return route.path === '/'
  50. }
  51. function handleLink(item) {
  52. const { redirect, path, meta } = item
  53. if (meta.type == '0') return
  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: 14px;
  82. line-height: 50px;
  83. }
  84. // 覆盖 element-plus 的样式
  85. .el-breadcrumb__inner,
  86. .el-breadcrumb__inner a {
  87. font-weight: 400 !important;
  88. }
  89. </style>