BreadCrumbs.vue 4.58 KB
<template>
	<div class="breadcrumb-container">
		<!--<span class="current-position">当前位置:</span>-->
		<!--面包屑,1-->
		<el-breadcrumb :separator-class="separatorClass" :separator="separator">
			<template v-for="(item,index) in data">
				<el-breadcrumb-item v-if="item.isLeaf" :key="item.name+index" :replace="item.replace" :to="{path:item.uri}">{{item.name}}</el-breadcrumb-item>
				<el-breadcrumb-item v-else :key="item.name+index" :replace="item.replace">{{item.name}}</el-breadcrumb-item>
			</template>
		</el-breadcrumb>
		<!--面包屑,1-->
	</div>
</template>
<script type="text/javascript">
import { Breadcrumb, BreadcrumbItem } from "element-ui";
export default {
  name: "BreadCrumbs",
  props: {
    separator: String,
    separatorClass: String,
    data: {
      type: Array,
      default: () => []
    }
  },
  components: {
    "el-breadcrumb": Breadcrumb,
    "el-breadcrumb-item": BreadcrumbItem
	},
  methods: {
    // 将路由数据转换成面包屑需要的格式
    translateToCrumb(item) {
      let name = item.name ? item.name : "首页";
      const newItem = {
        name: item.meta
          ? item.meta.title
            ? typeof item.meta.title === "function" &&
              item.fullPath == this.$route.fullPath
              ? item.meta.title(this.$route)
              : item.meta.title
            : name
          : name,
        uri: item.fullPath ? item.fullPath : item.path,
        replace: item.meta
          ? (typeof item.meta.isLeaf === "boolean" && item.meta.isLeaf) ||
            item.meta.isLeaf === "true"
          : false,
        isLeaf: item.meta
          ? (typeof item.meta.isLeaf === "boolean" && item.meta.isLeaf) ||
            item.meta.isLeaf === "true"
          : false
      };
      return newItem;
    },
    getBreadcrumbInMenu(path,menuData) {
      let breadcrumb = [];
      const idIndex = menuData.find(item => item.routePath === path)
        .idIndex;
      if (typeof idIndex === "string" && idIndex.indexOf("-") > -1) {
        const idIndexArr = idIndex.split("-");
        let idIndexTemp = "";
        idIndexArr.forEach((item, index) => {
          if (0 === index) {
            idIndexTemp = item;
          } else {
            idIndexTemp = idIndexTemp + "-" + item;
          }
          breadcrumb.push(
            this.translateToCrumb(
              menuData.find(mitem => mitem.idIndex === idIndexTemp)
            )
          );
        });
      }
      return breadcrumb;
    },
    getBreadcrumb(menuData) {
      const fullPath = this.$route.fullPath;
      let breadcrumb = [];
      // 注意:菜单数据中的path不可重复!否则,一个点击出现页签后,另一个点击无效,且面包屑展示的为菜单数组中最前的一个的
			let isRouteExistInMenu = menuData.some(item => item.routePath === fullPath)
      if (isRouteExistInMenu) {
        breadcrumb = this.getBreadcrumbInMenu(fullPath,menuData);
      } else {
        const matched = this.$route.matched.filter(item => item.path);
        const matchedLength = matched.length;
        matched.forEach((el, index) => {
          let mitem = matched[index];
          if (index + 1 === matchedLength) {
            mitem.fullPath = fullPath;
          }
        });
        if (matched.length === 1) {
          breadcrumb.push(this.translateToCrumb(this.$route));
        } else {
          // 查找matched中各项的path,如果该路由的path在菜单数据上存在,拼接出菜单中存在的部分
          let matchedIndex = matched.findIndex(mitem => {
            return menuData.some(item => item.routePath === mitem.path);
          });
          if (matchedIndex != -1) {
            breadcrumb = this.getBreadcrumbInMenu(matched[matchedIndex].path,menuData);
          }
          // 再把matched后面的部分拼接到面包屑数据中
          let matchedRemainder = matched.slice(matchedIndex + 1);
          matchedRemainder.forEach((el, index) => {
            if (el.name !== "index") {
              if (index + 1 === matchedLength) {
                el.fullPath = this.$route.fullPath;
							}
							breadcrumb.push(this.translateToCrumb(el));
            }
          });
        }
      }
      return breadcrumb;
    }
  }
};
</script>
<style lang="less" scoped>
.breadcrumb-container {
  width: 100%;
	padding: 12px 0 16px;
	line-height: 24px;
  .current-position {
    font-size: 14px;
    margin-right: 8px;
	}
	/deep/ .el-breadcrumb{
  .el-breadcrumb__item {
    float: none;

    &:last-child .el-breadcrumb__inner {
      cursor: pointer;
			color:var(--primary-color);
      &:hover {
        cursor: pointer;
      }
    }
	}
	}
}
</style>