1. 程式人生 > 實用技巧 >elementui tab標籤管理路由頁面

elementui tab標籤管理路由頁面

文章目錄

樣式

準備

  • 搭建好的vue腳手架(elementui,router,vuex)
  • elementui(NavMenu 導航選單,Tabs 標籤頁)

思路

  • 將開啟的所有路由放到一個棧裡(openTab:[]),tabs顯示遍歷openTab

  • 初始狀態,將首頁推入棧,並設定啟用狀態

  • 當切換路由時(監聽路由變化),判斷棧裡是否存在這個路由,
    若存在,只改變啟用狀態;若不存在,則推入棧,並改變啟用狀態。

  • tabs 切換,呼叫@tab-click='tabClick’方法,跳轉路由,(路由變化,走上一步中“若存在,只改變啟用狀態”)

  • tabs 移除,呼叫@tab-remove=‘tabRemove’ 方法,移除棧(openTab)中對應的路由,若移除的路由是啟用狀態,那麼跳轉路由到棧中最後一個(路由變化);若移除的路由非啟用狀態,不做修改
    涉及到的內容

vuex state:路由棧、啟用狀態 mutations: 新增、移除、修改啟用狀態
watch
mounted
tab 切換、移除兩個方法

搭建

搭建頁面框架

slider元件

<template>
      <el-menu
        :default-active="$route.path"
        class
="slider" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" router > <el-menu-item index="/main" > <i class="el-icon-menu"></i> <span slot="title">首頁</span> </el-menu-item> <el-submenu v-for
="(item,index) in menuList" :key="index" :index='item.id'> <template slot="title"> <i :class="item.icon"></i> <span>{{item.title}}</span> </template> <el-menu-item-group > <el-menu-item v-for="child in item.children" :key="child.id" :index='child.index'>{{child.childtitle}}</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </template> <script> export default { name: 'Slider', data(){ return { menuList:[ { id:'1', title: '導航1', icon:'el-icon-location', children:[ { index:'/page1', childtitle:'導航1page1' }, { index:'/page2', childtitle:'導航1page2' }, ] }, { id:'2', title: '導航2', icon:'el-icon-location', children:[ { index:'/page3', childtitle:'導航2page3' }, { index:'/page4', childtitle:'導航2page4' }, ] } ] } }, } </script> <style scoped> .slider{ height: 100vh; } </style>

home頁

<template>
  <div class="home">
    <el-row>
      <el-col :span="4">
        <!-- 左側導航欄 -->
        <slider></slider>
      </el-col>
      <el-col :span='20'>
        <!-- header -->
        <nav-top></nav-top>
        <!-- 內容區 -->
        <div class="app-wrap">
           <!-- 此處放置el-tabs程式碼 -->
            <div >
              <el-tabs
                v-model="activeIndex"
                type="border-card"
                closable
                v-if="openTab.length"
                 @tab-click='tabClick'
                  @tab-remove='tabRemove'
                >
                <el-tab-pane
                  :key="item.name"
                  v-for="(item, index) in openTab"
                  :label="item.name"
                  :name="item.route"
                 >
                </el-tab-pane>
              </el-tabs>
            </div>
            <div class="content-wrap">
              <router-view/>
            </div>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

通過路由配置,使頁面可以正常的跳轉

準備狀態管理

state: {
    openTab:[],//所有開啟的路由
    activeIndex:'/main' //啟用狀態
  },
  mutations: {
    // 新增tabs
    add_tabs (state, data) {
      this.state.openTab.push(data);
    },
    // 刪除tabs
    delete_tabs (state, route) {
      let index = 0;
      for (let option of state.openTab) {
        if (option.route === route) {
          break;
        }
        index++;
      }
      this.state.openTab.splice(index, 1);
    },
    // 設定當前啟用的tab
    set_active_index (state, index) {
      this.state.activeIndex = index;
    },
  },

在home頁 ,或者silder頁 , 初始的路由狀態

mounted () {
    // 重新整理時以當前路由做為tab加入tabs
    // 當前路由不是首頁時,新增首頁以及另一頁到store裡,並設定啟用狀態
    // 噹噹前路由是首頁時,新增首頁到store,並設定啟用狀態
   if (this.$route.path !== '/' && this.$route.path !== '/main') {
      console.log('1');
      this.$store.commit('add_tabs', {route: '/main' , name: 'main'});
      this.$store.commit('add_tabs', {route: this.$route.path , name: this.$route.name });
      this.$store.commit('set_active_index', this.$route.path);
    } else {
      console.log('2');
      this.$store.commit('add_tabs', {route: '/main', name: 'main'});
      this.$store.commit('set_active_index', '/main');
      this.$router.push('/');
    }
  },

注意這裡 如果你重新整理 只想保留首頁,那麼 mounted 中 ,你只需寫else中的程式碼。
如果重新整理想,保留首頁和當前路由頁,if else都要寫()

監聽路由變化

 watch:{
    '$route'(to,from){
        //判斷路由是否已經開啟
        //已經開啟的 ,將其置為active
        //未開啟的,將其放入佇列裡
        let flag = false;
        for(let item of this.openTab){
          console.log("item.name",item.name)
          console.log("t0.name",to.name)

          if(item.name === to.name){
            console.log('to.path',to.path);
            this.$store.commit('set_active_index',to.path)
            flag = true;
            break;
          }
        }

        if(!flag){
          console.log('to.path',to.path);
          this.$store.commit('add_tabs', {route: to.path, name: to.name});
          this.$store.commit('set_active_index', to.path);
        }

    }
  }

tab方法

//tab標籤點選時,切換相應的路由
    tabClick(tab){
      console.log("tab",tab);
      console.log('active',this.activeIndex);
      this.$router.push({path: this.activeIndex});
    },
    //移除tab標籤
    tabRemove(targetName){
      console.log("tabRemove",targetName);
      //首頁不刪
      if(targetName == '/'){
        return
      }
      this.$store.commit('delete_tabs', targetName);
      if (this.activeIndex === targetName) {
        // 設定當前啟用的路由
        if (this.openTab && this.openTab.length >= 1) {
          console.log('=============',this.openTab[this.openTab.length-1].route)
          this.$store.commit('set_active_index', this.openTab[this.openTab.length-1].route);
          this.$router.push({path: this.activeIndex});
        } else {
          this.$router.push({path: '/'});
        }
      }
    }

GitHub程式碼地址
線上演示地址


更新

登入 與 退出登入


做登入與退出時 ,需要清空路由

退出登入方法或者登入成功方法呼叫

this.$store.state.openTab = [];
this.$store.state.activeIndex = '/main';

//tab標籤點選時,切換相應的路由tabClick(tab){ console.log("tab",tab); console.log('active',this.activeIndex);this.$router.push({path:this.activeIndex});},//移除tab標籤tabRemove(targetName){ console.log("tabRemove",targetName);//首頁不刪if(targetName =='/'){return}this.$store.commit('delete_tabs', targetName);if(this.activeIndex === targetName){// 設定當前啟用的路由if(this.openTab &&this.openTab.length >=1){ console.log('=============',this.openTab[this.openTab.length-1].route)this.$store.commit('set_active_index',this.openTab[this.openTab.length-1].route);this.$router.push({path:this.activeIndex});}else{this.$router.push({path:'/'});}}}