antd-vue3 实现面包屑

1,147 阅读1分钟

antd-vue3 实现面包屑

面包屑应该是我们在项目中经常使用的一个功能,一般情况下它用来表示我们当前所处的站点位置,也可以帮助我们能够更快的回到上个层级。下面我将根据路由,动态的实现面包屑组件 为了获取到对于的路由信息 可以把相关信息写在路由对应的meta里 我这里用到了title 和icon

路由配置 类似这种

 {
    path: '/monitor',
    name: 'monitor',
    meta: { title: '监控中心', icon: 'video' },

    component: () => import(/* webpackChunkName: "monitor" */ '@/view/monitor/index.vue'),
    redirect: '/monitor/video',
    children: [
      {
        path: 'video',
        name: 'video',
        meta: { title: '监控中心' },

        component: () => import(/* webpackChunkName: "video" */ '@/view/monitor/Monitor.vue'),
      },
      // 视频档案的路由
      {
        path: 'video-files',
        name: 'video-files',
        meta: { title: '视频档案' },

        component: () => import(/* webpackChunkName: "video-files" */ '@/view/monitor/components/VideoFiles.vue'),
      },
  }

这里是面包屑组件完整代码

<template>
  <a-breadcrumb class="breadcrumb" separator=">" :routes="routes">
    <template #itemRender="itemRender">
      <router-link :to="itemRender.redirect ? itemRender.redirect : itemRender.route.path">
        <sdFeatherIcons
          size="18"
          v-if="itemRender.route.meta.icon && itemRender.route.meta.title !== '塔机管理'"
          class="menu-img"
          :type="itemRender.route.meta.icon"
        />
        //这里是为了icon和img混用
        <img
          class="menu-img"
          v-if="itemRender.route.meta.title === '塔机管理'"
          :src="require('../static/img/tsqzj.png')"
          alt=""
        />
        {{ itemRender.route.meta.title }}
      </router-link>
    </template>
  </a-breadcrumb>
</template>
<script>
import { defineComponent, ref, watch, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { getItem, setItem } from '@/utility/localStorageControl';
//对路由信息进行存储 防止刷新页面 参数丢失
export default defineComponent({
  setup() {
    onMounted(() => {
      if (getItem('breadcrumbList')) {
        routes.value = getItem('breadcrumbList');
      }
    });
    const routes = ref([]);
    const duplicateRemoval = Arr => {
      var hash = {};
      Arr = Arr.reduce(function (arr, current) {
        console.log(20, current);
        hash[current.meta.title] ? '' : (hash[current.meta.title] = true && arr.push(current));
        return arr;
      }, []);
      console.log(23, Arr);
      return Arr;
    };
    const getBreadcrumb = () => {
      let matched = route.matched;
      matched = duplicateRemoval(matched);
      routes.value = [];

      //如果不是首页
      matched.forEach(item => {
        item.children = [];
        if (item.path == '/' || item.meta.title == '') return;
        // if (item.children.length > 0 && item.redirect == '') return;
        routes.value.push(item);
      });
      setItem('breadcrumbList', routes.value);
    };

    const route = useRoute();
    //监听路由变化
    watch(
      () => route.path,
      () => {
        getBreadcrumb();
        console.log('watch', routes);
      },
    );
    return {
      routes,
    };
  },
});
</script>
<style scoped>
.breadcrumb {
  position: absolute;
  top: 39px;
  z-index: 2;
  padding: 10px 0 0 15px;
  font-size: 16px;
}
.breadcrumb .router-link-active {
  color: rgba(0, 0, 0, 0.45);
}
.breadcrumb span:last-child .router-link-active {
  color: rgba(0, 0, 0, 0.85) !important;
}
.menu-img {
  display: inline-block;
  width: 20px;
  height: 20px;
  vertical-align: sub;
}
</style>