Breadcrumb.vue 1.36 KB
<script setup lang="ts">
import { HOME_PATH } from '@/config'
import { usePermissionStore } from '@/store'

/**
 * 面包屑
 *
 * 优先用后端菜单的 path→title 映射(中文名更准),回退到路由 meta.title。
 * 只展示路由 matched 中带 meta.title 的层级,避免把 Layout 容器也渲染出来。
 */
const route = useRoute()
const permissionStore = usePermissionStore()

const crumbs = computed(() => {
  const matched = (route.matched || []).filter((r) => r.meta?.title)
  const list = matched.map((r) => ({
    path: r.path,
    title: permissionStore.menuTitleMap[r.path] || (r.meta.title as string)
  }))
  // 首页永远在最前
  if (route.path !== HOME_PATH) {
    list.unshift({ path: HOME_PATH, title: '首页' })
  }
  return list
})
</script>

<template>
  <el-breadcrumb separator="/" class="breadcrumb">
    <el-breadcrumb-item v-for="(item, index) in crumbs" :key="item.path">
      <span v-if="index === crumbs.length - 1" class="current">{{ item.title }}</span>
      <router-link v-else :to="item.path" class="link">{{ item.title }}</router-link>
    </el-breadcrumb-item>
  </el-breadcrumb>
</template>

<style scoped lang="scss">
.breadcrumb {
  font-size: 13px;
  line-height: 1;
}

.link {
  color: $text-color-secondary;

  &:hover {
    color: $primary-color;
  }
}

.current {
  color: $text-color-primary;
  font-weight: 500;
}
</style>