From 7ec3b1286f311a4018e9eaf2b4037f511df5bbab Mon Sep 17 00:00:00 2001 From: YangYuGang <1378265336@qq.com> Date: 星期三, 05 三月 2025 10:03:47 +0800 Subject: [PATCH] 一些更改 --- src/layouts/default/header/components/Breadcrumb.vue | 282 +++++++++++++++++++++++++++++-------------------------- 1 files changed, 148 insertions(+), 134 deletions(-) diff --git a/src/layouts/default/header/components/Breadcrumb.vue b/src/layouts/default/header/components/Breadcrumb.vue index 1869d18..2a0de00 100644 --- a/src/layouts/default/header/components/Breadcrumb.vue +++ b/src/layouts/default/header/components/Breadcrumb.vue @@ -1,153 +1,167 @@ <template> <div :class="[prefixCls, `${prefixCls}--${theme}`]"> - <a-breadcrumb :routes="routes"> - <template #itemRender="{ route, routes: routesMatched, paths }"> - <Icon :icon="getIcon(route)" v-if="getShowBreadCrumbIcon && getIcon(route)" /> - <span v-if="!hasRedirect(routesMatched, route)"> - {{ t(route.name || route.meta.title) }} - </span> - <router-link v-else to="" @click="handleClick(route, paths, $event)"> - {{ t(route.name || route.meta.title) }} - </router-link> + <Breadcrumb> + <template v-for="routeItem in routes" :key="routeItem.name"> + <BreadcrumbItem> + <Icon :icon="getIcon(routeItem)" v-if="getShowBreadCrumbIcon && getIcon(routeItem)" /> + <span v-if="!hasRedirect(routes, routeItem)"> + {{ t((routeItem.meta.title || routeItem.name) as string) }} + </span> + <router-link v-else to="" @click="handleClick(routeItem)"> + {{ t((routeItem.meta.title || routeItem.name) as string) }} + </router-link> + <template v-if="routeItem.children && !routeItem.meta?.hideChildrenInMenu" #overlay> + <Menu> + <template v-for="childItem in routeItem.children" :key="childItem.name"> + <MenuItem> + <Icon + :icon="getIcon(childItem)" + v-if="getShowBreadCrumbIcon && getIcon(childItem)" + /> + <span v-if="!hasRedirect(routes, childItem)"> + {{ t((childItem.meta?.title || childItem.name) as string) }} + </span> + <router-link v-else to="" @click="handleClick(childItem)"> + {{ t((childItem.meta?.title || childItem.name) as string) }} + </router-link> + </MenuItem> + </template> + </Menu> + </template> + </BreadcrumbItem> </template> - </a-breadcrumb> + </Breadcrumb> </div> </template> -<script lang="ts"> +<script lang="ts" setup> import type { RouteLocationMatched } from 'vue-router'; import { useRouter } from 'vue-router'; - import type { Menu } from '/@/router/types'; - import { defineComponent, ref, watchEffect } from 'vue'; + import { ref, watchEffect } from 'vue'; - import { Breadcrumb } from 'ant-design-vue'; + import { Breadcrumb, BreadcrumbItem, Menu, MenuItem } from 'ant-design-vue'; import Icon from '@/components/Icon/Icon.vue'; - import { useDesign } from '/@/hooks/web/useDesign'; - import { useRootSetting } from '/@/hooks/setting/useRootSetting'; - import { useGo } from '/@/hooks/web/usePage'; - import { useI18n } from '/@/hooks/web/useI18n'; + import { useDesign } from '@/hooks/web/useDesign'; + import { useRootSetting } from '@/hooks/setting/useRootSetting'; + import { useGo } from '@/hooks/web/usePage'; + import { useI18n } from '@/hooks/web/useI18n'; - import { propTypes } from '/@/utils/propTypes'; - import { isString } from '/@/utils/is'; - import { filter } from '/@/utils/helper/treeHelper'; - import { getMenus } from '/@/router/menus'; + import { propTypes } from '@/utils/propTypes'; + import { isString } from '@/utils/is'; + import { filter } from '@/utils/helper/treeHelper'; + import { getMenus } from '@/router/menus'; - import { REDIRECT_NAME } from '/@/router/constant'; - import { getAllParentPath } from '/@/router/helper/menuHelper'; + import { REDIRECT_NAME } from '@/router/constant'; + import { getAllParentPath } from '@/router/helper/menuHelper'; - export default defineComponent({ - name: 'LayoutBreadcrumb', - components: { Icon, [Breadcrumb.name]: Breadcrumb }, - props: { - theme: propTypes.oneOf(['dark', 'light']), - }, - setup() { - const routes = ref<RouteLocationMatched[]>([]); - const { currentRoute } = useRouter(); - const { prefixCls } = useDesign('layout-breadcrumb'); - const { getShowBreadCrumbIcon } = useRootSetting(); - const go = useGo(); + defineOptions({ name: 'LayoutBreadcrumb' }); - const { t } = useI18n(); - watchEffect(async () => { - if (currentRoute.value.name === REDIRECT_NAME) return; - const menus = await getMenus(); - - const routeMatched = currentRoute.value.matched; - const cur = routeMatched?.[routeMatched.length - 1]; - let path = currentRoute.value.path; - - if (cur && cur?.meta?.currentActiveMenu) { - path = cur.meta.currentActiveMenu as string; - } - - const parent = getAllParentPath(menus, path); - const filterMenus = menus.filter((item) => item.path === parent[0]); - const matched = getMatched(filterMenus, parent) as any; - - if (!matched || matched.length === 0) return; - - const breadcrumbList = filterItem(matched); - - if (currentRoute.value.meta?.currentActiveMenu) { - breadcrumbList.push({ - ...currentRoute.value, - name: currentRoute.value.meta?.title || currentRoute.value.name, - } as unknown as RouteLocationMatched); - } - routes.value = breadcrumbList; - }); - - function getMatched(menus: Menu[], parent: string[]) { - const metched: Menu[] = []; - menus.forEach((item) => { - if (parent.includes(item.path)) { - metched.push({ - ...item, - name: item.meta?.title || item.name, - }); - } - if (item.children?.length) { - metched.push(...getMatched(item.children, parent)); - } - }); - return metched; - } - - function filterItem(list: RouteLocationMatched[]) { - return filter(list, (item) => { - const { meta, name } = item; - if (!meta) { - return !!name; - } - const { title, hideBreadcrumb, hideMenu } = meta; - if (!title || hideBreadcrumb || hideMenu) { - return false; - } - return true; - }).filter((item) => !item.meta?.hideBreadcrumb); - } - - function handleClick(route: RouteLocationMatched, paths: string[], e: Event) { - e?.preventDefault(); - const { children, redirect, meta } = route; - - if (children?.length && !redirect) { - e?.stopPropagation(); - return; - } - if (meta?.carryParam) { - return; - } - - if (redirect && isString(redirect)) { - go(redirect); - } else { - let goPath = ''; - if (paths.length === 1) { - goPath = paths[0]; - } else { - const ps = paths.slice(1); - const lastPath = ps.pop() || ''; - goPath = `${lastPath}`; - } - goPath = /^\//.test(goPath) ? goPath : `/${goPath}`; - go(goPath); - } - } - - function hasRedirect(routes: RouteLocationMatched[], route: RouteLocationMatched) { - return routes.indexOf(route) !== routes.length - 1; - } - - function getIcon(route) { - return route.icon || route.meta?.icon; - } - - return { routes, t, prefixCls, getIcon, getShowBreadCrumbIcon, handleClick, hasRedirect }; - }, + defineProps({ + theme: propTypes.oneOf(['dark', 'light']), }); + + const routes = ref<RouteLocationMatched[]>([]); + const { currentRoute } = useRouter(); + const { prefixCls } = useDesign('layout-breadcrumb'); + const { getShowBreadCrumbIcon } = useRootSetting(); + const go = useGo(); + + const { t } = useI18n(); + watchEffect(async () => { + if (currentRoute.value.name === REDIRECT_NAME) return; + const menus = await getMenus(); + + const routeMatched = currentRoute.value.matched; + const cur = routeMatched?.[routeMatched.length - 1]; + let path = currentRoute.value.path; + + if (cur && cur?.meta?.currentActiveMenu) { + path = cur.meta.currentActiveMenu as string; + } + + const parent = getAllParentPath(menus, path); + const filterMenus = menus.filter((item) => item.path === parent[0]); + const matched = getMatched(filterMenus, parent) as any; + + if (!matched || matched.length === 0) { + routes.value = []; + return; + } + + const breadcrumbList = filterItem(matched); + + if (currentRoute.value.meta?.currentActiveMenu && !currentRoute.value.meta?.hideBreadcrumb) { + breadcrumbList.push({ + ...currentRoute.value, + name: currentRoute.value.meta?.title || currentRoute.value.name, + } as unknown as RouteLocationMatched); + } + routes.value = breadcrumbList; + }); + + function getMatched(menus, parent: string[]) { + const matched: any[] = []; + menus.forEach((item) => { + if (parent.includes(item.path)) { + matched.push({ + ...item, + name: item.meta?.title || item.name, + }); + } + if (item.children?.length) { + matched.push(...getMatched(item.children, parent)); + } + }); + return matched; + } + + function filterItem(list: RouteLocationMatched[]) { + return filter(list, (item) => { + const { meta, name } = item; + if (!meta) { + return !!name; + } + const { title, hideBreadcrumb, hideMenu } = meta; + if (!title || hideBreadcrumb || hideMenu) { + return false; + } + return true; + }).filter((item) => !item.meta?.hideBreadcrumb); + } + + function handleClick(route) { + const { children, redirect, meta } = route; + + if (children?.length && !redirect) { + return; + } + if (meta?.carryParam) { + return; + } + + if (redirect && isString(redirect)) { + go(redirect); + } else { + let goPath = ''; + if (route.path) { + goPath = route.path; + } else { + const lastPath = ''; + goPath = `${lastPath}`; + } + goPath = /^\//.test(goPath) ? goPath : `/${goPath}`; + go(goPath); + } + } + + function hasRedirect(routes, route) { + return routes.indexOf(route) !== routes.length - 1; + } + + function getIcon(route) { + return route.icon || route.meta?.icon; + } </script> <style lang="less"> @prefix-cls: ~'@{namespace}-layout-breadcrumb'; -- Gitblit v1.9.3