vue 使用js实现面包屑中实现右击菜单,并通过右击菜单的命令实现关闭其他、关闭左侧和关闭右侧的功能

发布时间:2024年01月09日

实现一个面包屑导航组件。面包屑导航用于显示当前页面的路径,并提供快速跳转到上级页面的功能,且可以通过右击菜单的命令实现关闭其他、关闭左侧和关闭右侧的功能

<template>
  <div
    class="breadcrumbWrapper"
    ref="breadcrumbWrapper"
    @contextmenu.prevent="showClickAllBtn"
    @click="handlePopClose"
  >
    <el-breadcrumb class="app-levelbar" ref="appLevelbar">
      <el-breadcrumb-item
        v-for="(item, index) in levelList"
        :key="item.path"
        :class="activeIndex === index ? 'activeClass' : ''"
        ref="breadcrumbItem"
      >
        <router-link :to="item.path" @click.native.stop="handleClick(index)">{{
          item.name
        }}</router-link>
        <template>
          <i
            class="el-icon-close closeBtn"
            @click.stop="handleDeleteClick(index)"
            v-if="isShowClose"
          ></i>
        </template>
      </el-breadcrumb-item>
    </el-breadcrumb>
    <div class="clickRightClose">
      <div class="closeBtn" @click="closeCurrent">关闭当前 </div>
      <div class="closeBtn" @click="closeOther">
        关闭其他
      </div>
      <div class="closeBtn" @click="closeRight">
        关闭右侧
      </div>
      <div class="closeBtn" @click="closeLeft">
        关闭左侧
      </div>
    </div>
  </div>
</template>

<script>
import BScroll from "better-scroll";
export default {
  created() {
    this.getBreadcrumb();
  },
  data() {
    return {
      levelList: [],
      flag: false,
      activeIndex: 0,
      isShowClose: true,
      rightClickTab: "",
      rightClickTabIndex: ""
    };
  },
  methods: {
    getBreadcrumb() {
      let title = this.$route.meta.title;
      let path = this.$route.path;
      let params = this.$route.params;
      let flag = this.levelList.find(item => {
        return item.name === title;
      });
      this.flag = !flag;
      // 路由跳转,添加到面包屑中
      if (this.flag && title !== undefined) {
        this.levelList.push({
          name: title,
          path: path,
          params: params
        });
      }
      this.levelList.forEach((v, i) => {
        if (v.name === title) {
          this.activeIndex = i;
        }
      });
    },
    handleClick(i) {
      let isMenuOpen = this.$route.meta.menuPath.length <= 1 ? true : false;
      let breadCrumbActiveIndex = "";
      if (Object.keys(this.$route.params).length > 0) {
        let params = this.$route.params;
        let fullPath = this.$route.fullPath;
        let strArr = fullPath.split("/");
        strArr.pop();
        strArr.shift();
        let newStr = strArr.join("/");
        let strParams = "";
        // eslint-disable-next-line guard-for-in
        for (let key in params) {
          strParams = `${key}=${params[key]}`;
        }
        breadCrumbActiveIndex = `${newStr}?${strParams}`;
      } else {
        breadCrumbActiveIndex = this.$route.fullPath.slice(1);
      }
      // 用于选中菜单
      this.$store.commit("setbreadCrumbActiveIndex", breadCrumbActiveIndex);
      // 用于菜单展开状态
      this.$store.commit("setIsOpen", isMenuOpen);
      this.activeIndex = i;
    },
    handleDeleteClick(i) {
      if (i === 0 && this.activeIndex === 0) {
        this.levelList.splice(i, 1);
        this.activeIndex = 0;
        this.$router.push(this.levelList[0].path);
      } else if (i !== this.levelList.length - 1) {
        this.levelList.splice(i, 1);
        this.activeIndex--;
        this.$router.push(this.levelList[this.activeIndex].path);
      } else {
        this.levelList.splice(i, 1);
        this.$router.push(this.levelList[this.levelList.length - 1].path);
      }
    },
    getWidth() {
      this.$nextTick(() => {
        let allWidth = 0;
        let nodes = document.querySelectorAll(".el-breadcrumb__item");
        let appLevelbar = document.querySelector(".app-levelbar");
        let breadcrumbWrapper = document.querySelector(".breadcrumbWrapper");
        let breadcrumbWrapperWidth = parseFloat(
          window.getComputedStyle(breadcrumbWrapper, null)["width"]
        );
        nodes.forEach(v => {
          let w = parseFloat(window.getComputedStyle(v, null)["width"]);
          let r = parseFloat(window.getComputedStyle(v, null)["marginRight"]);
          let l = parseFloat(window.getComputedStyle(v, null)["marginLeft"]);
          allWidth += w + r + l;
        });
        appLevelbar.style.width = allWidth + "px";
        if (allWidth > breadcrumbWrapperWidth) {
          this.scroll = new BScroll(this.$refs.breadcrumbWrapper, {
            scrollX: true
          });
          let activeDom = document.querySelector(
            ".el-breadcrumb__item.activeClass"
          );
          this.scroll.scrollToElement(activeDom, 0, 0);
          this.scroll.refresh();
        }
      });
    },
    showClickAllBtn(e) {
      if (this.levelList.length > 1 && e.path[0].nodeName !== "DIV") {
        let closeBtn = document.querySelector(".clickRightClose");
        closeBtn.style.display = "block";
        closeBtn.style.left = e.clientX + "px";
        closeBtn.style.top = 110 + "px";
        this.rightClickTab = e.path[0].innerText;
        this.rightClickTabIndex = this.getRightClickTabIndex(
          this.rightClickTab
        );
      }
    },

    getRightClickTabIndex(arg) {
      let tabList = [];
      this.levelList &&
        this.levelList.forEach(v => {
          tabList.push(v.name);
        });
      let rightClickTabIndex = tabList.indexOf(arg);
      return rightClickTabIndex;
    },
    // 左击关闭弹框
    handlePopClose() {
      let closeBtn = document.querySelector(".clickRightClose");
      closeBtn.style.display = "none";
    },
    // 关闭当前
    closeCurrent() {
      this.levelList.splice(this.rightClickTabIndex, 1);
      this.activeIndex =
        this.rightClickTabIndex > 0 ? this.rightClickTabIndex - 1 : 0;
      let closeBtn = document.querySelector(".clickRightClose");
      closeBtn.style.display = "none";
      this.$router.push(this.levelList[this.activeIndex].path);
      this.getWidth();
    },
    // 关闭其他
    closeOther() {
      this.levelList = this.levelList.splice(this.rightClickTabIndex, 1);
      let closeBtn = document.querySelector(".clickRightClose");
      closeBtn.style.display = "none";
      this.activeIndex = 0;
      this.$router.push(this.levelList[0].path);
      this.getWidth();
    },
    // 关闭全部
    closeAll() {
      let closeBtn = document.querySelector(".clickRightClose");
      closeBtn.style.display = "none";
      this.levelList.splice(1);
      this.activeIndex = 0;
      this.$router.push(this.levelList[0].path);
      this.getWidth();
    },
    // 关闭右侧
    closeRight() {
      let closeBtn = document.querySelector(".clickRightClose");
      closeBtn.style.display = "none";
      this.levelList.splice(
        this.rightClickTabIndex + 1,
        this.levelList.length - 1
      );
      this.activeIndex = this.rightClickTabIndex;
      this.$router.push(this.levelList[this.activeIndex].path);
      this.getWidth();
    },
    // 关闭左侧
    closeLeft() {
      let closeBtn = document.querySelector(".clickRightClose");
      closeBtn.style.display = "none";
      this.levelList.splice(0, this.rightClickTabIndex);
      this.activeIndex = this.levelList.length - 1;
      this.$router.push(this.levelList[this.activeIndex].path);
      this.getWidth();
    }
  },
  watch: {
    $route() {
      this.getWidth();
      this.getBreadcrumb();
    },
    levelList: {
      handler(val) {
        // this.getWidth();
        if (val.length > 1) {
          this.isShowClose = true;
        } else {
          this.isShowClose = false;
        }
      }
    }
  }
};
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.breadcrumbWrapper {
  width: 100%;
  border-top: 1px solid #cfdfe6;
  overflow: hidden;
  box-sizing: border-box;
  height: 50px;
  .app-levelbar {
    white-space: nowrap;
    width: 2000px;
  }
  .clickRightClose {
    position: fixed;
    display: none;
    // border: 1px solid #ccc;
    // padding: 5px;
    font-size: 14px;
    z-index: 1000;
    color: #333;
    background: #fff;
    cursor: pointer;
    .closeBtn {
      padding: 10px 25px;
      &:hover {
        background: #d7eff3;
      }
    }
  }
}
.el-breadcrumb {
  line-height: 50px;
  box-sizing: border-box;
  height: 50px;
  /deep/ .el-breadcrumb__item {
    cursor: pointer;
    margin-right: 30px;
    display: inline-block;
    float: none;
    box-sizing: border-box;
    height: 46px;
    .el-breadcrumb__inner {
      display: flex;
      align-items: center;
      font-size: 16px;
      font-weight: 400;
      a {
        display: inline-block;
        padding-left: 10px;
        color: #666;
        cursor: pointer;
        font-size: 16px;
        font-weight: 400;
        &:hover {
          color: #666;
          font-size: 16px;
          font-weight: 400;
        }
      }
      .closeBtn {
        font-size: 16px;
        padding-left: 20px;
        color: #bbb;
        cursor: pointer;
      }
    }
    .el-breadcrumb__separator {
      display: none;
    }
    &.activeClass {
      color: #069dbc;
      border-bottom: 2px solid #069dbc;
      .el-breadcrumb__inner {
        a {
          color: #069dbc;
        }
        .closeBtn {
          color: #069dbc;
        }
      }
    }
  }
}
</style>

  • getBreadcrumb方法根据当前路由的信息更新面包屑导航的内容
  • handleClick方法在点击面包屑导航项时触发,根据点击的索引更新当前项的样式,并更新全局状态。
  • handleDeleteClick方法在点击关闭按钮时触发,根据关闭的索引更新面包屑导航的内容,并跳转到相应的页面。
  • getWidth方法用于计算面包屑导航的宽度,并根据需要添加滚动效果。
  • showClickAllBtn方法在右键点击面包屑导航项时触发,显示右键菜单,并记录点击的项的信息。
  • handlePopClose方法在左键点击面包屑导航以外的地方时触发,关闭右键菜单。
  • closeCurrent、closeOther、closeAll、closeRight和closeLeft方法分别对应右键菜单中的不同选项,用于关闭当前、关闭其他、关闭全部、关闭右侧和关闭左侧的面包屑导航项。
文章来源:https://blog.csdn.net/weixin_46328739/article/details/135479441
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。