LayoutBreadcrumb.tsx 3.4 KB
Newer Older
陈文彬 已提交
1 2 3 4 5 6 7 8 9 10 11 12
import type { AppRouteRecordRaw } from '/@/router/types';
import type { RouteLocationMatched } from 'vue-router';

import { defineComponent, TransitionGroup, unref, watch, ref } from 'vue';
import Breadcrumb from '/@/components/Breadcrumb/Breadcrumb.vue';
import BreadcrumbItem from '/@/components/Breadcrumb/BreadcrumbItem.vue';
import { useRouter } from 'vue-router';
import router from '/@/router';
import { PageEnum } from '/@/enums/pageEnum';
import { isBoolean } from '/@/utils/is';

import { compile } from 'path-to-regexp';
Z
ZhaoBin 已提交
13
import Icon from '/@/components/Icon';
陈文彬 已提交
14 15 16

export default defineComponent({
  name: 'BasicBreadcrumb',
Z
ZhaoBin 已提交
17 18 19 20 21 22 23
  props: {
    showIcon: {
      type: Boolean,
      default: false,
    },
  },
  setup(props) {
陈文彬 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    const itemList = ref<AppRouteRecordRaw[]>([]);
    const { currentRoute, push } = useRouter();

    function getBreadcrumb() {
      const { matched } = unref(currentRoute);
      const matchedList = matched.filter((item) => item.meta && item.meta.title).slice(1);
      const firstItem = matchedList[0];
      const ret = getHomeRoute(firstItem);

      if (!isBoolean(ret)) {
        matchedList.unshift(ret);
      }
      itemList.value = ((matchedList as any) as AppRouteRecordRaw[]).filter(
        (item) => item.meta && item.meta.title && !item.meta.hideBreadcrumb
      );
    }

    function getHomeRoute(firstItem: RouteLocationMatched) {
      if (!firstItem || !firstItem.name) return false;
      const routes = router.getRoutes();
      const homeRoute = routes.find((item) => item.path === PageEnum.BASE_HOME);
      if (!homeRoute) return false;
      if (homeRoute.name === firstItem.name) return false;
      return homeRoute;
    }
    function pathCompile(path: string) {
      const { params } = unref(currentRoute);
      const toPath = compile(path);
      return toPath(params);
    }
    function handleItemClick(item: AppRouteRecordRaw) {
      const { redirect, path, meta } = item;
      if (meta.disabledRedirect) return;
      if (redirect) {
        push(redirect as string);
        return;
      }
      return push(pathCompile(path));
    }

    watch(
      () => currentRoute.value,
      () => {
        if (unref(currentRoute).name === 'Redirect') return;
        getBreadcrumb();
      },
      { immediate: true }
    );

    return () => (
      <>
V
vben 已提交
75
        <Breadcrumb class="layout-breadcrumb">
陈文彬 已提交
76 77 78 79 80 81 82 83 84 85 86 87
          {() => (
            <>
              <TransitionGroup name="breadcrumb">
                {() => {
                  return unref(itemList).map((item) => {
                    const isLink = !!item.redirect && !item.meta.disabledRedirect;
                    return (
                      <BreadcrumbItem
                        key={item.path}
                        isLink={isLink}
                        onClick={handleItemClick.bind(null, item)}
                      >
Z
ZhaoBin 已提交
88 89 90 91 92 93 94 95
                        {() => (
                          <>
                            {props.showIcon && item.meta.icon && item.meta.icon.trim() !== '' && (
                              <Icon icon={item.meta.icon} class="icon mr-1 mb-1" />
                            )}
                            {item.meta.title}
                          </>
                        )}
陈文彬 已提交
96 97 98 99 100 101 102 103 104 105 106 107
                      </BreadcrumbItem>
                    );
                  });
                }}
              </TransitionGroup>
            </>
          )}
        </Breadcrumb>
      </>
    );
  },
});