• Vue+Elementui历史导航标签实现


    需求

    • 用户在点击菜单栏时,内容组件上方会显示历史导航,用于快捷访问历史
    • 历史标签可以点击快速查看该内容组件
    • 历史组件可删除
    • 当容器宽度不足以显示多余的标签时,会隐藏,同时显示左右滚轮
    • 历史回滚:删除当前激活的标签后,会回滚到最后一次被激活的标签

    效果演示:

    请添加图片描述

    源代码

    标签组件

    Tab.vue

    <template>
      <el-tabs type="card" v-if="history&&history.length>0"
               :value="currentPath"
               @tab-click="tabClick"
               @tab-remove="tabRemove"
               closable class="content">
        <el-tab-pane v-for="item in history"
                     :key="item.path"
                     :label="item.name"
                     :name="item.path">
        </el-tab-pane>
      </el-tabs>
    </template>
    
    <script>
    
    export default {
      name: "Tab",
      computed:{
        history(){
          return this.$store.getters.history;
        },
        currentPath(){
          return this.$store.getters.currentPath;
        }
      },
      methods:{
        tabClick({name}){
          this.$store.commit('menu/addHistoryPath',name);
          if(name!==this.$route.path){
            this.$router.push(name);
          }
        },
        tabRemove(path){
          this.$store.commit('history/removeHistory',path);
          this.$store.commit('history/removeHistoryPath',path);
        }
      }
    }
    </script>
    
    <style scoped>
    .content{
      margin-top: 5px;
      height: 35px;
      user-select: none;
    }
    :deep(.el-tabs__nav-wrap){
      height: 35px !important;
      line-height: 35px !important;
    }
    :deep(.el-tabs__nav-next) , :deep(.el-tabs__nav-prev){
      line-height: 35px !important;
    }
    :deep(.el-tabs__header){
      height: 35px !important;
      margin: 0;
      border: none;
    }
    :deep(.el-tabs__item){
      height: 30px;
      margin-top: 2px;
      margin-bottom: 2px;
      border: 1px solid grey !important;
      line-height: 30px;
      padding: 0 10px 0 10px !important;
      border-radius: 2px;
    }
    
    :deep(.el-tabs__item:not(:last-child)){
      margin-right: 10px;
    }
    
    :deep(.is-active){
      border-bottom:inherit;
      background-color: lightcyan;
    }
    :deep(.el-tabs__nav){
      border: none !important;
      /*height: 35px;*/
      /*1px solid #E4E7ED*/
    }
    
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    父组件

    <el-header height="50px" class="tagsContent">
        <tab></tab>
    </el-header>
    
    • 1
    • 2
    • 3

    菜单组件

    elementui菜单标签中加入点击事件
    在这里插入图片描述

    methods:{
        openMenuItem(name,path){
          this.$store.commit('menu/addHistory',{name,path});
          this.$store.commit('menu/addHistoryPath',path);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Vuex

    src/store/modules/history.js
    
    const state={
        history:[],
        historyPath:[],
        currentPath:null
    }
    
    const mutations={
        addHistoryPath(state,path){
            let paths=state.historyPath.filter(item=>{
                return item!==path;
            })
            paths.push(path);
            state.historyPath=paths;
            state.currentPath=path;
        },
        addHistory(state,history){
            let index=-1;
            state.history.forEach((item,i)=>{
                if(item.path===history.path)
                    index=i;
            })
            if(index!==-1){
                return;
            }
            state.history.push({
                name:history.name,
                path:history.path
            })
        },
        removeHistory(state,path){
            state.history=state.history.filter(item=>{
                return item.path!==path;
            })
        },
        removeHistoryPath(state,path){
            state.historyPath=state.historyPath.filter(item=>{
                return item!==path;
            })
            if(state.historyPath.length>0)
                state.currentPath=state.historyPath[state.historyPath.length-1];
            else
                state.currentPath=null;
        }
    }
    
    export default{
        namespaced:true,
        state,
        mutations
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    src/store/getters.js
    const getters={
        history:state=>state.history.history,
        currentPath:state=>state.history.currentPath
    }
    export default getters
    
    • 1
    • 2
    • 3
    • 4
    • 5
    src/store/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    
    import getters from "./getters";
    
    import history from './moudules/history'
    
    
    
    const modules= {
        user,
        history
    }
    
    export default new Vuex.Store({
        modules,
        getters
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    [Vue3] pinia状态管理
    group by 分组【mysql数据库】
    PCB电路设计规范细节
    智能小车开发
    adapter 模式
    2022爱分析・采购数字化厂商全景报告 | 爱分析报告
    Java“牵手”微店商品列表数据,关键词搜索微店商品数据接口,微店API申请指南
    Spring Security 中重要对象汇总
    Nodejs -- Express 路由原理及设置模块化路由
    Windows进程的创建与结束
  • 原文地址:https://blog.csdn.net/qq_16525829/article/details/126805881