109 lines
2.6 KiB
Vue
109 lines
2.6 KiB
Vue
<template>
|
||
<el-breadcrumb
|
||
separator="/"
|
||
style="margin: 15px 10px; font-size: 1.05rem; opacity: 0.9"
|
||
>
|
||
<el-breadcrumb-item
|
||
v-for="(item, idx) in breadcrumbs"
|
||
:key="item.path || idx"
|
||
:to="
|
||
item.path && idx !== breadcrumbs.length - 1
|
||
? { path: item.path }
|
||
: undefined
|
||
"
|
||
>
|
||
<span v-if="!item.path || idx === breadcrumbs.length - 1">{{
|
||
item.title || item.name
|
||
}}</span>
|
||
<span v-else>{{ item.title || item.name }}</span>
|
||
</el-breadcrumb-item>
|
||
</el-breadcrumb>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed } from "vue";
|
||
import { useRoute } from "vue-router";
|
||
import { menuConfig } from "../../constants/menuConfig.js";
|
||
|
||
// 更簡潔的選單查找與麵包屑組裝
|
||
function findMenuItem(route) {
|
||
for (const menu of menuConfig) {
|
||
for (const child of menu.children) {
|
||
// 靜態路由、名稱
|
||
if (child.routeName === route.name || child.path === route.path) {
|
||
return { parent: menu, item: child };
|
||
}
|
||
// 動態路由(如 /plant/:id)
|
||
if (
|
||
child.routeName === "PlantInfo" &&
|
||
route.path &&
|
||
route.path.startsWith("/plant/")
|
||
) {
|
||
return { parent: menu, item: child };
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
function buildBreadcrumb(route) {
|
||
const match = findMenuItem(route);
|
||
if (!match) return [];
|
||
const crumbs = [
|
||
{
|
||
name: match.parent.title,
|
||
title: match.parent.title,
|
||
path: null,
|
||
meta: { title: match.parent.title },
|
||
},
|
||
];
|
||
let itemTitle = match.item.title;
|
||
if (route.name === "PlantInfo" && route.params.id) {
|
||
const plantNames = {
|
||
"1": "四磺子坪",
|
||
"2": "宜蘭大清水",
|
||
"3": "宜蘭小清水",
|
||
};
|
||
itemTitle = plantNames[route.params.id] || match.item.title;
|
||
}
|
||
crumbs.push({
|
||
name: itemTitle,
|
||
title: itemTitle,
|
||
path: match.item.path,
|
||
meta: { title: itemTitle },
|
||
});
|
||
return crumbs;
|
||
}
|
||
|
||
const route = useRoute();
|
||
|
||
const breadcrumbs = computed(() => {
|
||
const menuBreadcrumbs = buildBreadcrumb(route);
|
||
if (menuBreadcrumbs.length > 0) {
|
||
return menuBreadcrumbs;
|
||
}
|
||
const matchedRoutes = route.matched.filter((r) => r.meta && r.meta.title);
|
||
if (matchedRoutes.length === 0) {
|
||
return [];
|
||
}
|
||
const currentRoute = matchedRoutes[matchedRoutes.length - 1];
|
||
if (currentRoute.meta.parentTitle) {
|
||
return [
|
||
{
|
||
title: currentRoute.meta.parentTitle,
|
||
path: null,
|
||
},
|
||
{
|
||
title: currentRoute.meta.title,
|
||
path: currentRoute.path,
|
||
},
|
||
];
|
||
}
|
||
return matchedRoutes.map((r) => ({
|
||
title: r.meta.title,
|
||
name: r.name,
|
||
path: r.path,
|
||
}));
|
||
});
|
||
</script>
|