Industrial-image-management.../src/components/Breadcrumb/index.vue

98 lines
2.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-breadcrumb>
<transition-group name="breadcrumb">
<div v-for="(item, index) in breadcrumbList" :key="item.meta.title">
<a-breadcrumb-item v-bind="attrs">
<span
v-if="item.redirect === 'noRedirect' || item.redirect === '' || index === breadcrumbList.length - 1"
class="gi_line_1"
>{{ item.meta.title }}</span>
<span v-else class="gi_line_1 breadcrumb-item-title" @click="handleLink(item)">{{ item.meta.title }}</span>
<icon-right v-if="index !== breadcrumbList.length - 1" />
</a-breadcrumb-item>
</div>
</transition-group>
</a-breadcrumb>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { RouteLocationMatched } from 'vue-router'
import { findTree } from 'xe-utils'
import { useRouteStore } from '@/stores'
const route = useRoute()
const router = useRouter()
const { routes } = useRouteStore()
const attrs = useAttrs()
// 缓存home路由
const home = computed(() => {
const cloneRoutes = JSON.parse(JSON.stringify(routes)) as RouteLocationMatched[]
const obj = findTree(cloneRoutes, (i) => i.path === '/dashboard/workplace')
return obj?.item || null
})
// 使用computed计算面包屑列表避免重复计算
const breadcrumbList = computed(() => {
// 跳过重定向路由
if (route.path.startsWith('/redirect/')) {
return []
}
const cloneRoutes = JSON.parse(JSON.stringify(routes)) as RouteLocationMatched[]
const obj = findTree(cloneRoutes, (i) => i.path === route.path)
// 获取当前节点的所有上级节点集合,包含当前节点
const arr = obj ? obj.nodes.filter((item) => item.meta && item.meta.title && item.meta.breadcrumb !== false) : []
// 如果有home路由且不是重复的则添加到开头
if (home.value && !arr.some(item => item.path === home.value?.path)) {
return [home.value, ...arr]
}
return arr
})
// 路由跳转
function handleLink(item: RouteLocationMatched) {
const { redirect, path } = item
if (redirect) {
return router.push(redirect as string)
}
router.push(path)
}
</script>
<style scoped lang="scss">
/** breadcrumb-transform 面包屑动画 */
.breadcrumb-enter-active {
transition: all 0.2s;
}
.breadcrumb-enter-from,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(10px);
}
:deep(.arco-breadcrumb-item) {
padding: 0;
display: flex;
align-items: center;
.arco-icon-right {
margin: 0 4px;
}
}
.breadcrumb-item-title {
transition: all 0.3s;
cursor: pointer;
&:hover {
color: $color-theme;
font-weight: 600;
}
}
</style>