實現el-tabs標簽與el-menu之間的聯動。


實現功能:點擊mean的子菜單,tabs顯示子菜單名稱。並且可以進行刪除,刷新之后,停留在刷新前的界面。

使用到的組件el-menu el-tabs

使用到的工具:vue-routervuex

實現效果:

 

項目目錄:

 

App.vue

<template>
  <div id="app">
    <el-container>
      <el-aside width="300px">
        <Home></Home>
        <!-- 我是側邊欄 -->
      </el-aside>
      <el-container>
        <el-main>
          <tabs></tabs>
          <!-- 我是tabs組件 -->
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import Home from '../src/views/Home'
import tabs from '../src/views/tabs'
export default {
  components:{
    Home,
    tabs
  }
}
</script>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* text-align: center; */
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

tabs.vue

<template>
  <div class>
    <el-tabs
      v-model="editableTabsValue"
      type="card"
      closable
      @tab-remove="removeTab"
      @tab-click="tabClick($event)"
    >
      <el-tab-pane
        :key="item.name"
        v-for="item in editableTabs"
        :label="item.title"
        :name="item.name"
      ></el-tab-pane>
    </el-tabs>
    <router-view />
  </div>
</template>

<script>
export default {
  name: "",
  components: {},
  data() {
    return {};
  },
  mounted() {
    //刷新加載sessionStorage存着地址
    if (sessionStorage.getItem("tabsPage")) {
      this.$store.state.tabsPage = JSON.parse(
        sessionStorage.getItem("tabsPage")
      );
      var TabsValue = sessionStorage.getItem("TabsValue");
      this.$store.state.TabsValue = TabsValue;
      if (sessionStorage.getItem("tabsPage") === "[]") {
        this.$router.push({ name: "Home" });
      } else {
        this.$router.push({ name: TabsValue });
      }
    }
  },
  computed: {
    // 監聽vuex保存的數據
    editableTabs: {
      get() {
        return this.$store.state.tabsPage;
      },
      set(val) {
        this.$store.state.tabsPage = val;
      },
    },
    editableTabsValue: {
      get() {
        return this.$store.state.TabsValue;
      },
      set(val) {
        this.$store.state.TabsValue = val;
      },
    },
  },
  methods: {
    removeTab(targetName) {
      let tabs = this.editableTabs;
      let activeName = this.editableTabsValue;
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            let nextTab = tabs[index + 1] || tabs[index - 1];
            console.log(nextTab);
            if (nextTab) {
              activeName = nextTab.name;
            }
          }
        });
      }
      this.editableTabsValue = activeName;
      this.editableTabs = tabs.filter((tab) => tab.name !== targetName);
      this.$store.state.tabsPage = this.editableTabs;
      window.sessionStorage.tabsPage = JSON.stringify(this.editableTabs);
      //解決刷新消失
      window.sessionStorage.setItem("TabsValue", activeName);
      // 刪除時跳轉不在停留被刪除頁
      if (sessionStorage.getItem("tabsPage") === "[]") {
        this.$router.push({ name: "home" });
      } else {
        this.$router.push({ name: activeName });
      }
    },
    tabClick(event) {
      //寫一個點擊tabs跳轉
      this.$router.push({ name: event.name });
    },
  },
};
</script>

Home.vue

<style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
  min-height: 97.3vh;
  width: 14rem;
}
.el-menu {
  padding-top: 2.7vh;
}
.el-submenu__title i,
.el-menu-item i {
  color: #909399;
  position: relative;
  right: 0.4rem;
  font-size: 12px;
}
.el-menu-item {
  min-width: auto !important;
}
.el-submenu /deep/ .el-submenu__title .el-submenu__icon-arrow {
  position: absolute;
  right: 2rem;
}
</style>
<template>
  <div class="height:100%">
      <!--
        :default-active="$route.name" 
        獲取router路由的name 對應menu-item內的index
        為了對應 tabs 的跳轉點擊 做選中
      -->
      <el-menu
        :default-active="$route.name"
        class="el-menu-vertical-demo"
        background-color="#545c64"
        text-color="white"
        active-text-color="#ffd04b"
      >
        <!-- 循環數據格式 -->
        <el-submenu :index="`${index}`" v-for="(menu,index) in menuList" :key="index">
          <template slot="title">
            <i :class="menu.icont"></i>
            <span>{{menu.name}}</span>
          </template>
          <el-menu-item-group>
            <el-menu-item
              :index="item.routeName"
              v-for="item in menu.menuItem"
              :key="item.index"
              @click="handleOpen2(item)"
            >{{item.name}}</el-menu-item>
          </el-menu-item-group>
        </el-submenu>
      </el-menu>
    </div>
</template>

<script>
import { mapActions } from "vuex";
export default {
  name: "zgz-admin-index-aside",
  components: {},
  data() {
    return {
      // 將所需submenu,menu和tabs所需參數寫成數據格式
      menuList: [
        {
          icont: "el-icon-s-tools",
          name: "子菜單",
          menuItem: [
            {
              title: "子菜單1",
              routeName: "Setting",
              name: "子菜單1",
            },
            {
              title: "子菜單2",
              routeName: "WxAd",
              name: "子菜單2",
            },
          ],
        },
        {
          icont: "el-icon-s-tools",
          name: "子菜單呀",
          menuItem: [
            {
              title: "子菜單呀1",
              routeName: "Setting",
              name: "子菜單呀1",
            },
            {
              title: "子菜單呀2",
              routeName: "WxAd",
              name: "子菜單呀2",
            },
          ],
        },
        {
          icont: "el-icon-s-order",
          name: "子菜單啊呀",
          menuItem: [
            {
              title: "子菜單啊呀1",
              routeName: "orderList",
              name: "子菜單啊呀1",
            },
            {
              title: "子菜單啊呀2",
              routeName: "orderList",
              name: "子菜單啊呀2",
            },
          ],
        },
      ],
    };
  },
  created() {},
  mounted() {},
  methods: {
    // 調用 注冊vuex內注冊的editableTabs方法
    ...mapActions({
      handleOpen2: "editableTabs",
    }),
  },
};
</script>

store中的index.js

import Vue from 'vue';
import Vuex from 'vuex';
// 引入 router 在vuex內使用router跳轉
import router from '../router';

Vue.use(Vuex);
Vue.use(router);

export default new Vuex.Store({
  state: { // 定義tabs 所需參數
    tabsPage: [],
    TabsValue: ''
  },
  mutations: {
    editableTabs: (state, obj) => {
      // 淺拷貝 state.tabsPage
      const arr = Array.from(state.tabsPage)
      // 判斷數組內是否為空
      if (arr.length !== 0) {
        // 使用 Array.some 去判斷是否存在對象信息
        var even = function (obj) {
          return arr.some(item => {
            return item.name === obj.routeName
          })
        }
        // even方法 如果對象存在返回true,不存在則返回flase
        // 加!觸發 true 代碼塊
        if (!even(obj)/* 如果不存在將對象push進數組內bing */) {
          // 將tabs所需參數push進arr數組
          arr.push({ title: obj.name, name: obj.routeName })
          // 賦值給tabsPage參數
          state.tabsPage = arr
          // 存儲sessionStorage -- 解決刷新消失
          window.sessionStorage.setItem('tabsPage', JSON.stringify(arr))
          window.sessionStorage.setItem('TabsValue', obj.routeName)
          // 賦值給TabsValue參數
          state.TabsValue = obj.routeName
          // 跳轉
          router.push({ name: obj.routeName })
        } else { // 如果存在 只做跳轉選中
          // 賦值給TabsValue參數
          state.TabsValue = obj.routeName
          window.sessionStorage.setItem('TabsValue', obj.routeName)
          // 跳轉
          router.push({ name: obj.routeName })
        }
      } else { // 如果為0
        // 將tabs所需參數push進arr數組
        arr.push({
          title: obj.name, name: obj.routeName
        })
        // 賦值給tabsPage參數
        state.tabsPage = arr
        // 賦值給TabsValue參數
        state.TabsValue = obj.routeName
        // 跳轉
        router.push({ name: obj.routeName })
      }
    }
  },
  actions: {
    // 注冊方法
    editableTabs(context, obj) {
      context.commit('editableTabs', obj)
    }
  }
})

router中的index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Setting from '../views/Setting.vue'
import WxAd from '../views/WxAd.vue'
import orderList from '../views/orderList.vue'


Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function (location, onResolve, onReject) {
  if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
  return originalPush.call(this, location).catch(err => err)
}

const routes = [
  {
    path: '/home',
    name: 'Home',
  },
  {
    path: '/Setting',
    name: 'Setting',
    component: Setting
  },
  {
    path: '/WxAd',
    name: 'WxAd',
    component: WxAd
  },
  {
    path: '/orderList',
    name: 'orderList',
    component: orderList
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM