feat(breadcrumb): add breadcrumb demo #143

This commit is contained in:
vben
2020-12-24 22:02:24 +08:00
parent 930383f9ae
commit 819bcbe526
26 changed files with 313 additions and 74 deletions

View File

@@ -1,12 +1,12 @@
<template>
<div :class="[prefixCls, `${prefixCls}--${theme}`]">
<a-breadcrumb :routes="routes">
<template #itemRender="{ route, routes }">
<template #itemRender="{ route, routes, paths }">
<Icon :icon="route.meta.icon" v-if="getShowBreadCrumbIcon && route.meta.icon" />
<span v-if="routes.indexOf(route) === routes.length - 1">
<span v-if="!hasRedirect(routes, route)">
{{ t(route.meta.title) }}
</span>
<router-link v-else :to="route.path">
<router-link v-else to="" @click="handleClick(route, paths, $event)">
{{ t(route.meta.title) }}
</router-link>
</template>
@@ -30,6 +30,8 @@
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { propTypes } from '/@/utils/propTypes';
import { useGo } from '/@/hooks/web/usePage';
import { isString } from '/@/utils/is';
export default defineComponent({
name: 'LayoutBreadcrumb',
@@ -45,22 +47,12 @@
const { t } = useI18n();
watchEffect(() => {
if (currentRoute.value.name === REDIRECT_NAME) {
return;
}
if (currentRoute.value.name === REDIRECT_NAME) return;
const matched = currentRoute.value?.matched;
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;
});
let breadcrumbList = filterItem(toRaw(matched));
const filterBreadcrumbList = breadcrumbList.filter(
(item) => item.path !== PageEnum.BASE_HOME
@@ -71,13 +63,86 @@
path: PageEnum.BASE_HOME,
meta: {
title: t('layout.header.home'),
isLink: true,
},
} as unknown) as RouteLocationMatched);
}
routes.value = filterBreadcrumbList.length === 1 ? [] : filterBreadcrumbList;
if (currentRoute.value.meta?.currentActiveMenu) {
filterBreadcrumbList.push((currentRoute.value as unknown) as RouteLocationMatched);
}
// routes.value = filterBreadcrumbList.length === 1 ? [] : filterBreadcrumbList;
routes.value = filterBreadcrumbList;
});
return { routes, t, prefixCls, getShowBreadCrumbIcon };
function filterItem(list: RouteLocationMatched[]) {
let resultList = filter(list, (item) => {
const { meta } = item;
if (!meta) {
return false;
}
const { title, hideBreadcrumb, hideMenu } = meta;
if (!title || hideBreadcrumb || hideMenu) {
return false;
}
return true;
}).filter((item) => !item.meta?.hideBreadcrumb || !item.meta?.hideMenu);
resultList = resultList.filter((item) => item.path !== PageEnum.BASE_HOME);
return resultList;
}
function handleClick(route: RouteLocationMatched, paths: string[], e: Event) {
e?.preventDefault();
const {
children,
redirect,
meta,
// components
} = route;
// const isParent =
// components?.default?.name === 'DefaultLayout' || (components?.default as any)?.parentView;
if (
children?.length &&
!redirect
// && !isParent
) {
e?.stopPropagation();
return;
}
if (meta?.carryParam) {
return;
}
const go = useGo();
if (redirect && isString(redirect)) {
go(redirect);
} else {
const ps = paths.slice(1);
const lastPath = ps.pop() || '';
const parentPath = ps.pop() || '';
let path = `${parentPath}/${lastPath}`;
path = /^\//.test(path) ? path : `/${path}`;
go(path);
}
}
function hasRedirect(routes: RouteLocationMatched[], route: RouteLocationMatched) {
if (route?.meta?.isLink) {
return true;
}
if (routes.indexOf(route) === routes.length - 1) {
return false;
}
return true;
}
return { routes, t, prefixCls, getShowBreadCrumbIcon, handleClick, hasRedirect };
},
});
</script>

View File

@@ -59,7 +59,7 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf
return { menuSetting: { bgColor: value } };
case HandlerEnum.MENU_SPLIT:
return { menuSetting: { split: value, collapsedShowTitle: true } };
return { menuSetting: { split: value } };
case HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE:
return { menuSetting: { closeMixSidebarOnChange: value } };

View File

@@ -38,6 +38,7 @@
<div :class="`${prefixCls}-menu-list`" ref="sideRef" :style="getMenuStyle">
<div
v-show="openMenu"
:class="[
`${prefixCls}-menu-list__title`,
{

View File

@@ -30,6 +30,7 @@
import { Tabs } from 'ant-design-vue';
import TabContent from './components/TabContent.vue';
import type { RouteLocationNormalized } from 'vue-router';
import { useGo } from '/@/hooks/web/usePage';
@@ -43,6 +44,8 @@
import { listenerLastChangeTab } from '/@/logics/mitt/tabChange';
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
import router from '/@/router';
export default defineComponent({
name: 'MultipleTabs',
components: {
@@ -61,7 +64,9 @@
const go = useGo();
const { getShowQuick, getShowRedo } = useMultipleTabSetting();
const getTabsState = computed(() => tabStore.getTabsState);
const getTabsState = computed(() => {
return tabStore.getTabsState.filter((item) => !item.meta?.hideTab);
});
const unClose = computed(() => unref(getTabsState).length === 1);
@@ -78,13 +83,24 @@
const { name } = route;
if (name === REDIRECT_NAME || !route || !userStore.getTokenState) return;
const { path, fullPath } = route;
const p = fullPath || path;
const { path, fullPath, meta = {} } = route;
const { currentActiveMenu, hideTab } = meta;
const isHide = !hideTab ? null : currentActiveMenu;
const p = isHide || fullPath || path;
if (activeKeyRef.value !== p) {
activeKeyRef.value = p;
}
tabStore.addTabAction(unref(route));
if (isHide) {
const findParentRoute = router
.getRoutes()
.find((item) => item.path === currentActiveMenu);
findParentRoute &&
tabStore.addTabAction((findParentRoute as unknown) as RouteLocationNormalized);
} else {
tabStore.addTabAction(unref(route));
}
});
function handleChange(activeKey: any) {