index.vue 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <template>
  2. <el-breadcrumb class="app-breadcrumb" separator="/">
  3. <transition-group name="breadcrumb">
  4. <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
  5. <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
  6. <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
  7. </el-breadcrumb-item>
  8. </transition-group>
  9. </el-breadcrumb>
  10. </template>
  11. <script setup>
  12. import usePermissionStore from '@/store/modules/permission'
  13. const route = useRoute()
  14. const router = useRouter()
  15. const permissionStore = usePermissionStore()
  16. const levelList = ref([])
  17. function getBreadcrumb() {
  18. // only show routes with meta.title
  19. let matched = []
  20. const pathNum = findPathNum(route.path)
  21. // multi-level menu
  22. if (pathNum > 2) {
  23. const reg = /\/\w+/gi
  24. const pathList = route.path.match(reg).map((item, index) => {
  25. if (index !== 0) item = item.slice(1)
  26. return item
  27. })
  28. getMatched(pathList, permissionStore.defaultRoutes, matched)
  29. } else {
  30. matched = route.matched.filter((item) => item.meta && item.meta.title)
  31. }
  32. // 判断是否为首页
  33. if (!isDashboard(matched[0])) {
  34. matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched)
  35. }
  36. levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
  37. }
  38. function findPathNum(str, char = "/") {
  39. let index = str.indexOf(char)
  40. let num = 0
  41. while (index !== -1) {
  42. num++
  43. index = str.indexOf(char, index + 1)
  44. }
  45. return num
  46. }
  47. function getMatched(pathList, routeList, matched) {
  48. let data = routeList.find(item => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0])
  49. if (data) {
  50. matched.push(data)
  51. if (data.children && pathList.length) {
  52. pathList.shift()
  53. getMatched(pathList, data.children, matched)
  54. }
  55. }
  56. }
  57. function isDashboard(route) {
  58. const name = route && route.name
  59. if (!name) {
  60. return false
  61. }
  62. return name.trim() === 'Index'
  63. }
  64. function handleLink(item) {
  65. const { redirect, path } = item
  66. if (redirect) {
  67. router.push(redirect)
  68. return
  69. }
  70. router.push(path)
  71. }
  72. watchEffect(() => {
  73. // if you go to the redirect page, do not update the breadcrumbs
  74. if (route.path.startsWith('/redirect/')) {
  75. return
  76. }
  77. getBreadcrumb()
  78. })
  79. getBreadcrumb()
  80. </script>
  81. <style lang='scss' scoped>
  82. .app-breadcrumb.el-breadcrumb {
  83. display: inline-block;
  84. font-size: 14px;
  85. line-height: 50px;
  86. margin-left: 8px;
  87. .no-redirect {
  88. color: #97a8be;
  89. cursor: text;
  90. }
  91. }
  92. </style>