LayoutBreadcrumb.tsx 3.2 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
    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;
    }
49

陈文彬 已提交
50 51 52 53 54
    function pathCompile(path: string) {
      const { params } = unref(currentRoute);
      const toPath = compile(path);
      return toPath(params);
    }
55

陈文彬 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
    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 () => (
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
      <Breadcrumb class="layout-breadcrumb">
        {() => (
          <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)}
                  >
                    {() => (
                      <>
                        {props.showIcon && item.meta.icon && item.meta.icon.trim() !== '' && (
                          <Icon icon={item.meta.icon} class="icon mr-1 mb-1" />
Z
ZhaoBin 已提交
92
                        )}
93 94 95 96 97 98 99 100 101 102
                        {item.meta.title}
                      </>
                    )}
                  </BreadcrumbItem>
                );
              });
            }}
          </TransitionGroup>
        )}
      </Breadcrumb>
陈文彬 已提交
103 104 105
    );
  },
});