最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue如何點擊多個tab標簽打開關(guān)閉多個頁面

 更新時間:2022年09月15日 17:00:39   作者:cyyy1223  
這篇文章主要介紹了vue如何點擊多個tab標簽打開關(guān)閉多個頁面,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

點擊多個tab標簽打開關(guān)閉多個頁面

需求

現(xiàn)將頁面分為Header LeftSideBar Main三大模塊 左側(cè)LeftSideBar為menu菜單,點擊菜單每一項,在Main中出現(xiàn)上部為tag標簽,下部為內(nèi)容 可打開多個tag標簽 ,可內(nèi)容切換 ,可關(guān)閉

效果圖

1.router.js中(在LeftSideBar組件中現(xiàn)在有兩個菜單項icons和tabs)

{
      path:'/addtab',
      redirect:'/addtab/index',//重定向 輸入/addtab 地址會變?yōu)?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")
        }
      ]
}

請戳--動態(tài)組件嵌套路由

2.this.$router.push({name:"TabContent",params:{}})  實現(xiàn)點擊左側(cè)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是存放路由信息的數(shù)組

 
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
      );//打開標簽后,判斷數(shù)組中是否已經(jīng)存在該路由
      if (!flag) {
        state.visitedTags.push(
          Object.assign(
            {},
            {
              path: payload.route.path,
              name: payload.route.name,
              params: payload.route.params
            }
          )
        );
      } //數(shù)組中路由存在不push ,單擊左側(cè)路由變化,點擊標簽路由變化均觸發(fā)
    } //添加標簽

第一次點擊是在mountd中觸發(fā)addTags方法,后來的每次點擊路由均會變化 ,使用watch監(jiān)聽觸發(fā)

 watch:{
      $route(){
        this.addTags();
      }//地址欄變化了就觸發(fā)這個添加方法
    }

b.關(guān)閉標簽

 在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;
? ? ? ? }
? ? ? }
? ? } //如果要關(guān)閉的標簽在路由中存在則刪除 ? ??

 在tagviews中

? ? ?isActive(route) {
? ? ? ? return route.path === this.$route.path
? ? ? },//當前地址欄路徑是否與渲染的路徑相同 樣式匹配
? ? ? closeSelectedTag(view){
? ? ? ? ?this.$store.dispatch({
? ? ? ? ? ?type:"closeTags",
? ? ? ? ? ?view
? ? ? ? ?}).then((views)=>{
? ? ? ? ? ? 此時的views是指的被刪除后的visitedViews數(shù)組中存在的元素
? ? ? ? ? ?if (this.isActive(view)) {
? ? ? ? ? ? 當前關(guān)閉的標簽是否是被選中的標簽
? ? ? ? ? ? ?const latestView = views.slice(-1)[0];
? ? ? ? ? ? ?if (latestView) {
? ? ? ? ? ? ? ?this.$router.push(latestView);//如果數(shù)組不為空則讓選中的標簽為緊鄰關(guān)閉標簽的那一個
? ? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?this.$router.push('/') ;//如果為空則頁面跳轉(zhuǎn)到/
? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ? ?})
? ? ? }

說一下思路

點擊左側(cè)的每一項都會打開一個組件(對應一個路由)  第一次點擊時將路由信息push到visitedViews中 后來的每次點擊都是通過watch $route執(zhí)行添加標簽方法 

刪除時要考慮是否是對激活項進行關(guān)閉 若是則先刪除數(shù)組中要關(guān)閉的標簽的那個路由,然后獲取剩余visitedViews中的路由,讓最后一個路由作為激活項

vue tab頁多頁面切換

實現(xiàn)路由發(fā)生變化時,新增一個tab標簽頁,點擊其他標簽時切換到對應的頁面,刷新網(wǎng)頁同時保留狀態(tài)

在這里插入圖片描述

這里就直接說它實現(xiàn)的代碼就OK!??!

VueX記錄下每次新增后的tab標簽頁路由

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    // 路由導航start
    // 緩存組件頁面
    catch_components: [],
    // 當前選中的菜單 - 默認選擇首頁
    activePath: '/index',
    // 菜單項 - 默認需要展示的頁面()
    tabList: [{
      path: '/index',
      label: '首頁',
      name: 'index',
      fullPath: "/index"
    }],
    // 路由導航end
  },
  // 更改vuex的store中狀態(tài)的唯一方法 - 同步操作
  mutations: {
    // 路由導航start
    //清空vuex數(shù)據(jù)
    clearVUEX(state) {
      state.catch_components = []
      state.activePath = 'index'
      state.tabList = [{
        path: '/idnex',
        label: '首頁',
        name: 'index',
        fullPath: "/index"
      }]
    },
    // 跳轉(zhuǎn)頁面執(zhí)行
    selectMenu(state, submenu) {
      // 首頁就是 wellcome   也就是 home
      if (submenu.name === 'index') {
        submenu.name = 'index'
        label.path = '首頁'
        submenu.path = '/index'
        submenu.fullPath= '/index'
      }
      // 當前選中菜單
      var activePath = submenu.name
      // 歷史已選中菜單列表
      var oldTabList = state.tabList
      // 將菜單信息添加到tablist - 添加時判斷是否已有該路由標簽
      var result = oldTabList.some(item => {
        if (item.name === activePath) {
          // console.log('--------', item.fullPath != submenu.fullPath)
          // 有該路由標簽是否為多次點擊(相當于查看同路由下的詳情,該過程只改變了參數(shù))
          if (!item.fullPath != submenu.fullPath) {
            item.fullPath = submenu.fullPath
          }
          return true
        }
      })
      // 如果不包含該對象,則添加
      if (!result) {
        oldTabList.push({
          path: submenu.name,
          name: submenu.name,
          label: submenu.label,
          fullPath: submenu.fullPath
        })
      }
      // 重新賦值標簽路由和當前選中菜單
      state.activePath = activePath
      state.tabList = oldTabList
    },
    // 添加keepalive緩存
    addKeepAliveCache(state, val) {
      // 如果是首頁不緩存
      if (val === 'index') {
        return
      }
      // console.log(state.catch_components)
      // 添加時判斷,如果該組件已存在,便不添加
      if (state.catch_components.indexOf(val) === -1) {
        // 不存在,緩存頁面
        state.catch_components.push(val)
      }
    },
    // 刪除keepalive緩存
    removeKeepAliveCache(state, val) {
      let cache = state.catch_components
      for (let i = 0; i < cache.length; i++) {
        if (cache[i] === val) {
          cache.splice(i, 1);
        }
      }
      state.catch_components = cache
    },
    //關(guān)閉菜單
    closeTab(state, val) {
      // 重新賦值
      state.activePath = val.activePath
      state.tabList = val.tabList
    },
    // 點擊標簽選擇菜單
    changeMenu(state, val) {
      state.activePath = val
    },
    // 路由導航end
  },
  actions: {
  }
})

根據(jù)自己的需求定義一個展示路由標簽組件vue文件

BScroll :當路由標簽過多時,用于橫向滾動標簽頁

 <!-- crumbs.vue -->
<template>
  <div class="tags">
    <div class="horizontal-container">
      <div class="scroll-wrapper" ref="scroll">
        <div class="scroll-content">
          <el-tag size="medium" v-for="(tab, index) in tabList" :key="tab.path" @close="handleClose(tab, index)"
            @click="changeMenu(tab)" :closable="tab.name !== 'index'"
            :effect="activePath === tab.name ? 'dark' : 'plain'">
            {{tab.label}}
          </el-tag>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  import {
    mapState
  } from 'vuex';
  import BScroll from '@better-scroll/core'
  export default {
    data() {
      return {
        //菜單列表
        menuList: [],
      }
    },
    computed: {
      ...mapState({ // 從 state 中的到的計算屬性
        activePath: state => state.activePath, // 已選中菜單
        tabList: state => state.tabList, // tags菜單列表
        catch_components: state => state.catch_components, // keepalive緩存
      })
    },
    mounted() {
      // this.handleCommand()
      this.init()
    },
    methods: {
      init() {
        this.bs = new BScroll(this.$refs.scroll, {
          scrollX: true,
          probeType: 3 // listening scroll event
        })
      },
      // 清空當前vuex數(shù)據(jù)
      handleCommand() {
        this.$store.commit('clearVUEX')
      },
      // 點擊菜單 - 傳入name,添加到keepalive緩存頁面
      selectMenu(item) {
        // console.log(item.name)
        // 加入keepalive緩存
        this.$store.commit('addKeepAliveCache', item.name)
        //添加tags標簽
        //訪問wellcome 就代表home
        var name = item.name === 'index' ? 'index' : item.name
        var submenu = {
          path: item.path,
          name: name,
          label: item.meta.title,
          fullPath: item.fullPath
        }
        // console.log(submenu)
        //更新選中菜單
        this.$store.commit('selectMenu', submenu)
        console.log(this.$store.state.tabList)
      },
      // 點擊標簽跳轉(zhuǎn)路由
      changeMenu(item) {
        // 歷史選中菜單
        var oldActivePath = this.$store.state.activePath
        // 首先判斷點擊的是否是自己,如果是自己則return
        if (oldActivePath === item.name) {
          return
        }
        // 存儲菜單
        this.$store.commit('changeMenu', item.name)
        // 頁面跳轉(zhuǎn)
        this.$router.push({
          path: item.fullPath
        })
      },
      // 關(guān)閉tab標簽
      handleClose(tab, index) {
        // 歷史選中菜單
        var oldActivePath = this.$store.state.activePath
        // 歷史已選中菜單列表
        var oldTabList = this.$store.state.tabList
        // 計算標簽個數(shù)
        let length = oldTabList.length - 1
        // 刪除tabList中的該對象
        for (let i = 0; i < oldTabList.length; i++) {
          let item = oldTabList[i]
          if (item.name === tab.name) {
            oldTabList.splice(i, 1);
          }
        }
        // 刪除keepAlive緩存
        this.$store.commit('removeKeepAliveCache', tab.name)
        // 如果關(guān)閉的標簽不是當前路由的話,就不跳轉(zhuǎn)
        if (tab.name !== oldActivePath) {
          return
        }
        // 如果length為1,必然只剩下首頁標簽,此時關(guān)閉后,更新到首頁
        if (length === 1) {
          // 同時存儲菜單
          this.$store.commit('closeTab', {
            activePath: 'home',
            tabList: oldTabList
          })
          // tab頁向左跳轉(zhuǎn)
          this.$router.push({
            name: oldTabList[index - 1].name
          })
          // 不再向下執(zhí)行
          return
        }
        // 關(guān)閉的標簽是最右邊的話,往左邊跳轉(zhuǎn)一個
        if (index === length) {
          // 同時更新路徑
          oldActivePath = oldTabList[index - 1].name
          // 同時存儲菜單
          this.$store.commit('closeTab', {
            activePath: oldActivePath,
            tabList: oldTabList
          })
          // tab頁向左跳轉(zhuǎn)
          this.$router.push({
            name: oldTabList[index - 1].name
          })
        } else {
          // 同時更新路徑
          oldActivePath = oldTabList[index].name
          // 同時存儲菜單
          this.$store.commit('closeTab', {
            activePath: oldActivePath,
            tabList: oldTabList
          })
          // tab頁向右跳轉(zhuǎn)
          this.$router.push({
            name: oldTabList[index].name
          })
        }
      },
    },
    watch: {
      // 路由發(fā)生變化時調(diào)用更新tab標簽數(shù)據(jù)
      '$route': {
        handler(newValue) {
          // console.log(newValue, oldValue)
          this.selectMenu(newValue);
        },
        immediate: true
      }
    },
  }
</script>
<style lang="less" scoped="scoped">
  /deep/ .el-tag--medium {
    margin-right: 10px;
  }
  .horizontal-container {
    .scroll-wrapper {
      position: relative;
      width: 100%;
      // margin: 80px auto;
      margin: 0 auto;
      white-space: nowrap;
      // border: 3px solid #42b983;
      border-radius: 5px;
      overflow: hidden;
      .scroll-content {
        display: inline-block;
      }
      .scroll-item {
        height: 40px;
        line-height: 40px;
        // font-size: 24px;
        display: inline-block;
        text-align: center;
        padding: 0 10px;
      }
    }
  }
  /deep/.el-tabs__nav-scroll {
    background: #fff;
  }
  .el-tag {
    cursor: pointer;
    margin-left: 10px;
    border-radius: 2px;
    font-size: 12px;
    color: #1890FF;
    border-color: #1890FF;
  }
  .el-tag--dark {
    color: #fff;
    background-color: #1890FF;
  }
  .el-dropdown-link {
    cursor: pointer;
  }
  .el-icon-arrow-down {
    font-size: 12px;
  }
  .submit-row {
    display: flex;
    flex-direction: row;
    justify-content: flex-end;
    align-items: center;
  }
</style>

若F5或者強刷新頁面時需要保留當前tab路由數(shù)據(jù),在App.vue中插入代碼

    created() {
      //在頁面刷新時將vuex里的信息保存到sessionStorage里
      window.addEventListener("beforeunload", () => {
        sessionStorage.setItem("store", JSON.stringify(this.$store.state))
      })
    
    },

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

固阳县| 内黄县| 普宁市| 富顺县| 濉溪县| 榆林市| 青浦区| 南投市| 中西区| 普陀区| 蒙自县| 富裕县| 武山县| 夏邑县| 怀仁县| 东丰县| 隆回县| 封丘县| 泗水县| 抚宁县| 元朗区| 台东市| 兴安盟| 成安县| 泽普县| 和硕县| 朝阳市| 曲麻莱县| 尼勒克县| 江西省| 郎溪县| 云和县| 黄骅市| 清新县| 游戏| 鲁山县| 兴业县| 武穴市| 韩城市| 克东县| 绥滨县|