| | |
| | | <template> |
| | | <div :class="[prefixCls, `${prefixCls}--${theme}`]"> |
| | | <a-breadcrumb :routes="routes"> |
| | | <template #itemRender="{ route, routes, paths }"> |
| | | <template #itemRender="{ route, routes: routesMatched, paths }"> |
| | | <Icon :icon="getIcon(route)" v-if="getShowBreadCrumbIcon && getIcon(route)" /> |
| | | <span v-if="!hasRedirect(routes, route)"> |
| | | {{ t(route.name || route.meta.title) }} |
| | | <span v-if="!hasRedirect(routesMatched, route)"> |
| | | {{ t(route.meta.title || route.name) }} |
| | | </span> |
| | | <router-link v-else to="" @click="handleClick(route, paths, $event)"> |
| | | {{ t(route.name || route.meta.title) }} |
| | | <router-link v-else to="" @click="handleClick(route, paths, $event as Event)"> |
| | | {{ t(route.meta.title || route.name) }} |
| | | </router-link> |
| | | </template> |
| | | </a-breadcrumb> |
| | |
| | | </template> |
| | | <script lang="ts"> |
| | | import type { RouteLocationMatched } from 'vue-router'; |
| | | import type { Menu } from '/@/router/types'; |
| | | import { useRouter } from 'vue-router'; |
| | | import type { Menu } from '@/router/types'; |
| | | |
| | | import { defineComponent, ref, watchEffect } from 'vue'; |
| | | |
| | | import { Breadcrumb } from 'ant-design-vue'; |
| | | import Icon from '/@/components/Icon'; |
| | | 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 { useRouter } from 'vue-router'; |
| | | 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', |
| | |
| | | const filterMenus = menus.filter((item) => item.path === parent[0]); |
| | | const matched = getMatched(filterMenus, parent) as any; |
| | | |
| | | if (!matched || matched.length === 0) return; |
| | | if (!matched || matched.length === 0){ |
| | | routes.value = []; |
| | | return; |
| | | } |
| | | |
| | | const breadcrumbList = filterItem(matched); |
| | | |
| | |
| | | } |
| | | |
| | | function filterItem(list: RouteLocationMatched[]) { |
| | | let resultList = filter(list, (item) => { |
| | | return filter(list, (item) => { |
| | | const { meta, name } = item; |
| | | if (!meta) { |
| | | return !!name; |
| | |
| | | return false; |
| | | } |
| | | return true; |
| | | }).filter((item) => !item.meta?.hideBreadcrumb || !item.meta?.hideMenu); |
| | | |
| | | return resultList; |
| | | }).filter((item) => !item.meta?.hideBreadcrumb); |
| | | } |
| | | |
| | | function handleClick(route: RouteLocationMatched, paths: string[], e: Event) { |
| | |
| | | } |
| | | |
| | | function hasRedirect(routes: RouteLocationMatched[], route: RouteLocationMatched) { |
| | | if (routes.indexOf(route) === routes.length - 1) { |
| | | return false; |
| | | } |
| | | return true; |
| | | return routes.indexOf(route) !== routes.length - 1; |
| | | } |
| | | |
| | | function getIcon(route) { |
| | |
| | | |
| | | .@{prefix-cls} { |
| | | display: flex; |
| | | padding: 0 8px; |
| | | align-items: center; |
| | | padding: 0 8px; |
| | | |
| | | .ant-breadcrumb-link { |
| | | .anticon { |
| | |
| | | color: @breadcrumb-item-normal-color; |
| | | |
| | | a { |
| | | color: rgba(0, 0, 0, 0.65); |
| | | color: rgb(0 0 0 / 65%); |
| | | |
| | | &:hover { |
| | | color: @primary-color; |
| | |
| | | |
| | | &--dark { |
| | | .ant-breadcrumb-link { |
| | | color: rgba(255, 255, 255, 0.6); |
| | | color: rgb(255 255 255 / 60%); |
| | | |
| | | a { |
| | | color: rgba(255, 255, 255, 0.8); |
| | | color: rgb(255 255 255 / 80%); |
| | | |
| | | &:hover { |
| | | color: @white; |
| | |
| | | |
| | | .ant-breadcrumb-separator, |
| | | .anticon { |
| | | color: rgba(255, 255, 255, 0.8); |
| | | color: rgb(255 255 255 / 80%); |
| | | } |
| | | } |
| | | } |