2020-12-03 21:49:32 +08:00
|
|
|
<template>
|
2020-12-15 00:13:23 +08:00
|
|
|
<div :class="[prefixCls, `${prefixCls}--${theme}`]">
|
2020-12-03 21:49:32 +08:00
|
|
|
<a-breadcrumb :routes="routes">
|
|
|
|
|
<template #itemRender="{ route, routes }">
|
2020-12-15 00:13:23 +08:00
|
|
|
<Icon :icon="route.meta.icon" v-if="getShowBreadCrumbIcon && route.meta.icon" />
|
2020-12-03 21:49:32 +08:00
|
|
|
<span v-if="routes.indexOf(route) === routes.length - 1">
|
|
|
|
|
{{ t(route.meta.title) }}
|
|
|
|
|
</span>
|
|
|
|
|
<router-link v-else :to="route.path">
|
|
|
|
|
{{ t(route.meta.title) }}
|
|
|
|
|
</router-link>
|
|
|
|
|
</template>
|
|
|
|
|
</a-breadcrumb>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script lang="ts">
|
|
|
|
|
import { defineComponent, ref, toRaw, watchEffect } from 'vue';
|
|
|
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
|
|
|
|
|
|
import type { RouteLocationMatched } from 'vue-router';
|
|
|
|
|
import { useRouter } from 'vue-router';
|
|
|
|
|
import { filter } from '/@/utils/helper/treeHelper';
|
|
|
|
|
import { REDIRECT_NAME } from '/@/router/constant';
|
|
|
|
|
import Icon from '/@/components/Icon';
|
|
|
|
|
|
|
|
|
|
import { HomeOutlined } from '@ant-design/icons-vue';
|
|
|
|
|
import { PageEnum } from '/@/enums/pageEnum';
|
2020-12-15 00:13:23 +08:00
|
|
|
|
|
|
|
|
import { useDesign } from '/@/hooks/web/useDesign';
|
|
|
|
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
|
|
|
|
|
|
|
|
|
import { propTypes } from '/@/utils/propTypes';
|
|
|
|
|
|
2020-12-03 21:49:32 +08:00
|
|
|
export default defineComponent({
|
|
|
|
|
name: 'LayoutBreadcrumb',
|
|
|
|
|
components: { HomeOutlined, Icon },
|
|
|
|
|
props: {
|
2020-12-15 00:13:23 +08:00
|
|
|
theme: propTypes.oneOf(['dark', 'light']),
|
2020-12-03 21:49:32 +08:00
|
|
|
},
|
|
|
|
|
setup() {
|
|
|
|
|
const routes = ref<RouteLocationMatched[]>([]);
|
|
|
|
|
const { currentRoute } = useRouter();
|
2020-12-15 00:13:23 +08:00
|
|
|
const { prefixCls } = useDesign('layout-breadcrumb');
|
|
|
|
|
const { getShowBreadCrumbIcon } = useRootSetting();
|
2020-12-03 21:49:32 +08:00
|
|
|
|
|
|
|
|
const { t } = useI18n();
|
|
|
|
|
watchEffect(() => {
|
|
|
|
|
if (currentRoute.value.name === REDIRECT_NAME) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-12-21 23:38:16 +08:00
|
|
|
const matched = currentRoute.value?.matched;
|
2020-12-03 21:49:32 +08:00
|
|
|
if (!matched || matched.length === 0) return;
|
|
|
|
|
|
|
|
|
|
let breadcrumbList = filter(toRaw(matched), (item) => {
|
|
|
|
|
if (!item.meta) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
const { title, hideBreadcrumb } = item.meta;
|
|
|
|
|
if (!title || hideBreadcrumb) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const filterBreadcrumbList = breadcrumbList.filter(
|
|
|
|
|
(item) => item.path !== PageEnum.BASE_HOME
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (filterBreadcrumbList.length === breadcrumbList.length) {
|
2020-12-15 00:13:23 +08:00
|
|
|
filterBreadcrumbList.unshift(({
|
2020-12-03 21:49:32 +08:00
|
|
|
path: PageEnum.BASE_HOME,
|
|
|
|
|
meta: {
|
|
|
|
|
title: t('layout.header.home'),
|
|
|
|
|
},
|
2020-12-15 00:13:23 +08:00
|
|
|
} as unknown) as RouteLocationMatched);
|
2020-12-03 21:49:32 +08:00
|
|
|
}
|
2020-12-15 00:13:23 +08:00
|
|
|
routes.value = filterBreadcrumbList.length === 1 ? [] : filterBreadcrumbList;
|
2020-12-03 21:49:32 +08:00
|
|
|
});
|
|
|
|
|
|
2020-12-15 00:13:23 +08:00
|
|
|
return { routes, t, prefixCls, getShowBreadCrumbIcon };
|
2020-12-03 21:49:32 +08:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
</script>
|
2020-12-15 00:13:23 +08:00
|
|
|
<style lang="less">
|
|
|
|
|
@import (reference) '../../../../design/index.less';
|
|
|
|
|
@prefix-cls: ~'@{namespace}-layout-breadcrumb';
|
|
|
|
|
|
|
|
|
|
.@{prefix-cls} {
|
|
|
|
|
display: flex;
|
|
|
|
|
padding: 0 8px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
.ant-breadcrumb-link {
|
|
|
|
|
.anticon {
|
|
|
|
|
margin-right: 4px;
|
|
|
|
|
margin-bottom: 2px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&--light {
|
|
|
|
|
.ant-breadcrumb-link {
|
|
|
|
|
color: @breadcrumb-item-normal-color;
|
|
|
|
|
|
|
|
|
|
a {
|
2020-12-21 23:38:16 +08:00
|
|
|
color: rgba(0, 0, 0, 0.65);
|
2020-12-15 00:13:23 +08:00
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
color: @primary-color;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ant-breadcrumb-separator {
|
|
|
|
|
color: @breadcrumb-item-normal-color;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&--dark {
|
|
|
|
|
.ant-breadcrumb-link {
|
|
|
|
|
color: rgba(255, 255, 255, 0.6);
|
|
|
|
|
|
|
|
|
|
a {
|
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
color: @white;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ant-breadcrumb-separator,
|
|
|
|
|
.anticon {
|
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|