Files
vueadmin/src/layouts/components/breadcrumb.vue
2026-01-26 10:01:26 +08:00

96 lines
1.8 KiB
Vue

<template><el-breadcrumb separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item, index) in breadcrumbs" :key="item.path">
<span v-if="index === breadcrumbs.length - 1" class="no-redirect">
{{ item.meta?.title }}
</span>
<a v-else class="redirect" @click.prevent="handleLink(item)">
{{ item.meta?.title }}
</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb></template>
<script setup>
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useI18n } from '@/hooks/useI18n'
defineOptions({
name: 'LayoutBreadcrumb',
})
const route = useRoute()
const router = useRouter()
const { t } = useI18n()
// 面包屑列表
const breadcrumbs = computed(() => {
const matched = route.matched.filter((item) => item.meta && item.meta.title)
const first = matched[0]
if (!first || !first.meta?.title) {
return []
}
// 如果第一个不是首页,添加首页
if (first.path !== '/') {
matched.unshift({
path: '/',
meta: { title: t('menu.home') || '首页' },
})
}
return matched
})
// 处理点击
const handleLink = (item) => {
const { redirect, path } = item
if (redirect) {
router.push(redirect)
return
}
router.push(path)
}
</script>
<style lang="scss" scoped>
.el-breadcrumb {
display: inline-block;
line-height: 60px;
font-size: 14px;
.no-redirect {
color: var(--el-text-color-regular);
cursor: text;
}
.redirect {
color: var(--el-text-color-primary);
cursor: pointer;
transition: color 0.3s;
&:hover {
color: var(--el-color-primary);
}
}
}
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all 0.3s;
}
.breadcrumb-enter-from,
.breadcrumb-leave-to {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-leave-active {
position: absolute;
}
</style>