Bootstrap

elmentUI el-menu+el-tabs实现菜单联动

1.菜单渲染(el-menu)

              <el-menu :default-active="String(activeNav)"
                 class="el-menu-vertical-demo"
                 @open="handleOpen"
                 background-color="#222d32"
                 text-color="#f4f5f5"
                 @close="handleClose"
                 :unique-opened="true"
                 router>
          <el-submenu v-if="item.children"
                      :index="item.path"
                      v-for="item in menuData"
                      :key="item.key">
            <template slot="title">
              <i :class="item.icon"
                 class="iconfont"></i>
              <span>{{item.name}}</span>
            </template>
            <el-menu-item :index="subItem.path"
                          v-for="subItem in item.children"
                          :key="subItem.key">
              <i :class="subItem.icon"
                 class="iconfont"></i>
              {{subItem.name}}</el-menu-item>
          </el-submenu>
          <el-menu-item v-else
                        :index="item.path"
                        :key="item.name">
            <i :class="item.icon"
               class="iconfont"></i>
            <span slot="title">{{item.name}}</span>
          </el-menu-item>
        </el-menu>

2.vuex

使用vuex存储路径数据,方便el-menu和el-tabs访问

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        openTab: [
            {
                name: 'analysis',
                title: '首页',
                closable: false
            }
        ],
        activeIndex: ''
    },
    getters: {
    },
    mutations: {
        add_tabs(state, data) {
            if (state.openTab.some(item => item.title === data.title)) return
            state.openTab.push(data);
        },
        delete_tabs(state, route) {
            let index = 0;
            for (let i of state.openTab) {
                if (i.route === route) {
                    break;
                }
                index++;
            }
            state.openTab.splice(index, 1);
        },
        set_active_tabs(state, index) {
            state.activeIndex = index;
        }
    },
    actions: {},
    modules: {}
});

3.el-tabs组件

<template>
  <!-- 自定义 动态增删 tabs 搭配 menu -->
  <div class="tab-menu">
      <el-tabs
          v-model="activeIndex"
          @tab-remove="removeTab"
          @tab-click="clickTab"
      >
          <el-tab-pane
              :key="item.name"
              v-for="item in openTab"
              :label="item.title"
              :name="item.name"
              :closable="item.closable"
          >
          <div class="tab-menu-content">
            <router-view></router-view>
          </div>
          </el-tab-pane>
      </el-tabs>
  </div>
</template>

<script>
export default {
  name: 'MenuTabs',
  data() {
      return {
          activeIndex: '/analysis',
          openTab: [
              {
                  title: '首页',
                  name: '/analysis',
                  closable: false
              }
          ]
      };
  },
  computed: {},
  watch: {
      $route(to, form) {
          var flag = false;
          // 当前页面菜单已打开
          for (let i = 0; i < this.openTab.length; i++) {
              if (to.path == this.openTab[i].name) {
                  this.activeIndex = this.openTab[i].name;
                  flag = true;
                  break;
              }
          }
          // 打开新的页面
          if (!flag) {
              if (!to.meta.title) {
                  to.meta.title = '我的日程';
              }
              console.log(to.meta);
              let obj = {
                  title: to.meta.title,
                  name: to.path,
                  closable: true
              };
              this.activeIndex = to.path;
              this.openTab.push(obj);
          }
      }
  },
  created() {
      const sessionTab = JSON.parse(window.sessionStorage.getItem('openTab')) || '';
      if (sessionTab) {
          if (sessionTab.openTab.length != 0 && sessionTab.openTabPath.length != 0) {
              for (let i = 0; i < sessionTab.openTab.length; i++) {
                  this.openTab.push({
                      title: sessionTab.openTab[i].title,
                      name: sessionTab.openTab[i].name,
                      closable: true
                  });
              }
              this.activeIndex = sessionTab.currActiveTabs;
              this.$router.push({ path: this.activeIndex });
          }
      }
  },
  mounted() {
      // 监听页面加载前
      window.addEventListener('beforeunload', e => {
          sessionStorage.setItem(
              'openTab',
              JSON.stringify({
                  openTab: this.openTab.filter(
                      item => item.name != '/analysis'
                  ),
                  openTabPath: this.openTab.filter(
                      item => item.name !== '/analysis'
                  ),
                  currActiveTabs: this.activeIndex
              })
          );
      });
  },
  methods: {
      clickTab(tab) {
          this.activeIndex = tab.paneName;
          this.$router.push({ path: this.activeIndex });
      },
      removeTab(target) {
          // 删除的是当前选中的页面
          if (this.activeIndex === target) {
              this.openTab.forEach((item, index) => {
                  if (item.name == target) {
                      let nextTab = item[index + 1] || item[index - 1];
                      if (nextTab) {
                          this.activeIndex = nextTab.name;
                      }
                  }
              });
          }
          var i = 0;
          this.openTab.forEach((item, index) => {
              if (item.name == target) {
                  // eslint-disable-next-line no-return-assign
                  return (i = index);
              }
          });
          this.openTab.splice(i, 1);

          // 更新路由
          this.$router.push({ path: this.openTab[this.openTab.length - 1].name });
      }
  }
};
</script>

<style lang="scss" scoped>
.tab-menu {
    ::v-deep .el-tabs__header {
        background: #fff;
        padding-left: 10px;
    }
    .tab-menu-content {
        padding: 10px;
    }
}
</style>
;