feat(components): 添加面包屑

This commit is contained in:
Soybean
2021-09-16 08:25:07 +08:00
parent 667282f81a
commit c1cdc3a9ed
12 changed files with 195 additions and 23 deletions

View File

@ -0,0 +1,66 @@
<template>
<n-breadcrumb class="px-12px">
<template v-for="breadcrumb in breadcrumbList" :key="breadcrumb.key">
<n-breadcrumb-item>
<n-dropdown v-if="breadcrumb.hasChildren" :options="breadcrumb.children" @select="dropdownSelect">
<span>{{ breadcrumb.label }}</span>
</n-dropdown>
<span v-else>{{ breadcrumb.label }}</span>
</n-breadcrumb-item>
</template>
</n-breadcrumb>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { NBreadcrumb, NBreadcrumbItem, NDropdown } from 'naive-ui';
import type { DropdownOption } from 'naive-ui';
import type { RouteLocationMatched } from 'vue-router';
import { EnumRoutePath } from '@/enum';
import type { RoutePathKey } from '@/interface';
type Breadcrumb = DropdownOption & {
key: string;
label: string;
disabled: boolean;
routeName: RoutePathKey;
hasChildren: boolean;
children?: Breadcrumb[];
};
const route = useRoute();
const router = useRouter();
const breadcrumbList = computed<Breadcrumb[]>(() => generateBreadcrumb());
function generateBreadcrumb() {
const { matched } = route;
return recursionBreadcrumb(matched);
}
/** 递归匹配路由获取面包屑数据 */
function recursionBreadcrumb(routeMatched: RouteLocationMatched[]) {
return routeMatched.map(item => {
const routeName = item.name as RoutePathKey;
const breadcrumItem: Breadcrumb = {
key: routeName,
label: (item.meta?.title as string) || '',
disabled: item.path === EnumRoutePath.root,
routeName,
hasChildren: false
};
if (item.children && item.children.length) {
breadcrumItem.hasChildren = true;
breadcrumItem.children = recursionBreadcrumb(item.children as RouteLocationMatched[]);
}
return breadcrumItem;
});
}
function dropdownSelect(optionKey: string) {
const key = optionKey as RoutePathKey;
router.push({ name: key });
}
</script>
<style scoped></style>

View File

@ -1,3 +1,4 @@
import GlobalBreadcrumb from './GlobalBreadcrumb.vue';
import UserAvatar from './UserAvatar.vue';
import MenuCollapse from './MenuCollapse.vue';
import FullScreen from './FullScreen.vue';
@ -5,4 +6,4 @@ import SettingDrawerButton from './SettingDrawerButton.vue';
import GihubSite from './GihubSite.vue';
import HeaderItem from './HeaderItem.vue';
export { UserAvatar, MenuCollapse, FullScreen, SettingDrawerButton, GihubSite, HeaderItem };
export { GlobalBreadcrumb, UserAvatar, MenuCollapse, FullScreen, SettingDrawerButton, GihubSite, HeaderItem };

View File

@ -5,7 +5,10 @@
<div v-if="!theme.isVerticalNav" class="menu-width h-full">
<global-logo />
</div>
<menu-collapse />
<div class="flex-y-center h-full">
<menu-collapse />
<global-breadcrumb v-if="theme.crumbsStyle.visible" />
</div>
<div class="flex-1 flex justify-end h-full">
<gihub-site />
<full-screen />
@ -20,7 +23,7 @@
import { computed } from 'vue';
import { NLayoutHeader } from 'naive-ui';
import { useThemeStore } from '@/store';
import { UserAvatar, MenuCollapse, FullScreen, GihubSite, SettingDrawerButton } from './components';
import { GlobalBreadcrumb, UserAvatar, MenuCollapse, FullScreen, GihubSite, SettingDrawerButton } from './components';
import { GlobalLogo } from '../common';
defineProps({