1. 程式人生 > >vue實現點選多個tab標籤開啟關閉多個頁面

vue實現點選多個tab標籤開啟關閉多個頁面

需求:現將頁面分為Header LeftSideBar Main三大模組 左側LeftSideBar為menu選單,點選選單每一項,在Main中出現上部為tag標籤,下部為內容 可開啟多個tag標籤 ,可內容切換 ,可關閉

效果圖

1.router.js中(在LeftSideBar元件中現在有兩個選單項icons和tabs)

{
      path:'/addtab',
      redirect:'/addtab/index',//重定向 輸入/addtab 地址會變為/addtab/index
      component: Main,
      children:[
        {
          path:'index',//當addtab/index匹配成功時 TabContent會被渲染在Main中的router-view中
          name:'TabContent',
          component:()=>import("@/components/TabContent")
        }
      ]
},
{
      path:'/addicon',
      redirect:'/addicon/index',
      component: Main,
      children:[
        {
          path:'index',
          name:'IconContent',
          component:()=>import("@/components/IconContent")
        }
      ]
}

2.this.$router.push({name:"TabContent",params:{}})  實現點選左側tab  開啟元件main  

3.在main中

<template>
  <div>
    <TagsView/>
    <router-view></router-view>
  </div>
</template>

4.在TagsView中

<template>
  <div class="tags-view-wrapper">
    <router-link class="tags-view-item" :to="item" :key="item.path" :class="isActive(item)?'active':''" v-for="(item) in Array.from(visitedViews)">
      {{item.params.name}}
      <span class='el-icon-close' @click.prevent.stop='closeSelectedTag(item)'></span>
    </router-link>
  </div>
</template>

a.新增標籤的方法

visitedViews是存放路由資訊的陣列


addTags(){
     const route=this.$route;//獲取位址列路由
     this.$store.commit({
     type:'addTags',
     route
 })
}
在store.js中
addTags(state, payload) {
      let flag = state.visitedTags.some(
        item => item.path === payload.route.path
      );//開啟標籤後,判斷陣列中是否已經存在該路由
      if (!flag) {
        state.visitedTags.push(
          Object.assign(
            {},
            {
              path: payload.route.path,
              name: payload.route.name,
              params: payload.route.params
            }
          )
        );
      } //陣列中路由存在不push ,單擊左側路由變化,點選標籤路由變化均觸發
    } //新增標籤

第一次點選是在mountd中觸發addTags方法,後來的每次點選路由均會變化 ,使用watch監聽觸發

 watch:{
      $route(){
        this.addTags();
      }//位址列變化了就觸發這個新增方法
    }

b.關閉標籤

 在store.js中   
 closeTags(state, payload) {
      for (const [key, item] of state.visitedTags.entries()) {
        if (item.path === payload.view.path) {
          state.visitedTags.splice(key, 1);
          break;
        }
      }
    } //如果要關閉的標籤在路由中存在則刪除     
 在tagviews中
     isActive(route) {
        return route.path === this.$route.path
      },//當前位址列路徑是否與渲染的路徑相同 樣式匹配
      closeSelectedTag(view){
         this.$store.dispatch({
           type:"closeTags",
           view
         }).then((views)=>{
            此時的views是指的被刪除後的visitedViews陣列中存在的元素
           if (this.isActive(view)) {
            當前關閉的標籤是否是被選中的標籤
             const latestView = views.slice(-1)[0];
             if (latestView) {
               this.$router.push(latestView);//如果陣列不為空則讓選中的標籤為緊鄰關閉標籤的那一個
             } else {
               this.$router.push('/') ;//如果為空則頁面跳轉到/
             }
           }
         })
      }

說一下思路:點選左側的每一項都會開啟一個元件(對應一個路由)  第一次點選時將路由資訊push到visitedViews中 後來的每次點選都是通過watch $route執行新增標籤方法 

刪除時要考慮是否是對啟用項進行關閉 若是則先刪除陣列中要關閉的標籤的那個路由,然後獲取剩餘visitedViews中的路由,讓最後一個路由作為啟用項