vue实现点击头部标签页走缓存,点击左侧导航正常调接口

 这里直接拆成组件就可以,用到仓库是因为新增功能是新页面点击保存需要把新增的这个标签页去掉    首先需要注意的是keep-alive缓存的话多层路由不支持,需要处理路由,缓存主要是keep-alive的include属性 

tabs.vue

<template>
<div class="elp_tab_box">
   <el-tabs
    v-model="activeTab"
    :value='$route.path'
    type="card"
    @tab-click="tabClick"
    @tab-remove='tabRemove'
    id="elp_tab"
  >
    <el-tab-pane
    closable
      v-for="item in $store.state.editableTabs"
      :key="item.route"
      :label="item.name"
      :name="item.route"
    />
  </el-tabs>
  <el-dropdown >
    <i id="elp_dropdown" class="el-icon-arrow-down"></i>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item @click.native="closeRightTabs">关闭左侧</el-dropdown-item>
      <el-dropdown-item @click.native="closeLeftTabs">关闭右侧</el-dropdown-item>
      <el-dropdown-item @click.native="closeOtherTabs">关闭其他</el-dropdown-item>
      <el-dropdown-item @click.native="closeAllTabs">关闭全部</el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
</div>
 
</template>

<script>
export default {
  data() {
    return {
      currentRouterName: "",
      currentRouter: "",
      activeTab: "",
      editableTabs: [],
    };
  },
  watch: {
    $route: {
      handler(to, form) {
        this.activeTab = to.path
        this.controlTabs(to);
        if (to.query.type !== "0") {
         let list = this.$store.state.editableTabs.map((item)=>item.title);
          list.forEach((item, index) => {
            if (item === to.name) {
              list.splice(index, 1);
            }
          });
          // this.alive=list.join(',')
          this.$store.dispatch("setList", list);
        }
        else if(to.query.type === "0"){
           let list = this.$store.state.editableTabs.map((item)=>item.title);
          // this.alive=list.join(',')
          this.$store.dispatch("setList", list);
        }
        this.$nextTick(()=>{
           let list = this.$store.state.editableTabs.map((item)=>item.title);
           this.$store.dispatch("setList", list);
        })
        console.log(this.$store.state.tabsList, "000000000000000");
      },
      immediate: true,
      deep: true,
    },
  },
  methods: {
    controlTabs(route) {
      var flag = false;
      this.currentRouterName = route.meta.title;
      this.currentRouter = route.path;
      for (let item of this.editableTabs) {
        if (item.route === route.path) {
          this.activeTable = route.path;
          flag = true;
          break;
        }
      }
      if (!flag) {
        let names = route.meta.title;
        if (names.indexOf("/", 1) != -1) {
          names = names.substring(names.indexOf("/" + 1));
        }
        let param = {
          route: route.path,
          name: names,
          title:route.name
        };
        this.editableTabs.push(param);
        this.$store.dispatch('setEdit',this.editableTabs)
       var arr= this.editableTabs.map((item)=>{
        return item.title
       })
        this.$store.dispatch('setList',arr)
        this.activeTab = route.path;
      }
    },
    tabClick() {
      this.$router.push({ path: this.activeTab, query:{type:'0'}  });
    },
    tabRemove(targetName) {
      if (this.activeTab === targetName) {
        this.editableTabs.forEach((tab, index) => {
          if (tab.route === targetName) {
            let nextTab =
              this.editableTabs[index + 1] || this.editableTabs[index - 1];
            if (nextTab) {
              this.$router.push({ path: nextTab.route ,query:{type:'0'}});
              this.editableTabs.splice(index, 1);
              this.$store.dispatch('setEdit',this.editableTabs)
             var arr= this.editableTabs.map((item)=>{
        return item.title
       })
        this.$store.dispatch('setList',arr)
            }
          }
        });
      } else {
        this.editableTabs = this.editableTabs.filter((item) => {
          if (item.route != targetName) {
            return item;
          }
        });
        this.$store.dispatch('setEdit',this.editableTabs)
        var arr= this.editableTabs.map((item)=>{
        return item.title
       })
        this.$store.dispatch('setList',arr)
      }
    },
    closeRightTabs(){
      const index=this.editableTabs.findIndex(item=>item.route==this.activeTab)
      if(index!==-1){
        this.editableTabs.splice(0,index)
        this.$store.dispatch('setEdit',this.editableTabs)
        var arr= this.editableTabs.map((item)=>{
        return item.title
       })
        this.$store.dispatch('setList',arr)
      }
    },
    closeLeftTabs(){
      const index=this.editableTabs.findIndex(item=>item.route==this.activeTab)
      if(index!==-1){
        this.editableTabs.splice(index+1)
        this.$store.dispatch('setEdit',this.editableTabs)
        var arr= this.editableTabs.map((item)=>{
        return item.title
       })
        this.$store.dispatch('setList',arr)
      }
    },
    closeOtherTabs(){
      this.editableTabs=this.editableTabs.filter(item=>item.route===this.activeTab)
      this.$store.dispatch('setEdit',this.editableTabs)
      var arr= this.editableTabs.map((item)=>{
        return item.title
       })
        this.$store.dispatch('setList',arr)
    },
    closeAllTabs(){
      this.activeTab=this.editableTabs[0].route
      this.currentRouter=this.editableTabs[0].route
      this.editableTabs=[this.editableTabs[0]]
      this.$store.dispatch('setEdit',this.editableTabs)
      var arr= this.editableTabs.map((item)=>{
        return item.title
       })
        this.$store.dispatch('setList',arr)
      this.$router.push({path:this.currentRouter,query:{type:'0'}})
      console.log(this.editableTabs)
    }
  },
};
</script>

<style>
#elp_tab>.el-tabs__header .el-tabs__item .el-icon-close{
  width: 12px !important; 
}
#elp_tab>.el-tabs__header .el-tabs__item{
  background: #fff !important;
  margin: 8px 0 0 8px;
  border-radius: 6px;
  border: none;
}
#elp_tab .el-tabs__nav{
  border: none !important;
  /* margin-left: 8px; */
}
#elp_tab .el-tabs__header{
  border-bottom: none !important;
}
#elp_tab .el-tabs__nav-prev{
  margin-left: 8px;
  line-height: 55px;
    font-size: 16px;
}
#elp_tab{
  width: 97%;
  
}
#elp_tab .el-tabs__nav-next{
  margin-right: 8px;
  margin-left: 20px;
  line-height: 55px;
    font-size: 16px;
}
#elp_tab .el-tabs__nav-scroll{
  width: 99%;
  margin-left: 8px;
} 
#elp_dropdown{
  display: inline-block;
  padding: 5px;
  background: #fff;
  margin-right: 20px;
}
.elp_tab_box .el-dropdown{
  line-height: 54px;
  font-size: 21px;
}
.elp_tab_box{
  display: flex;
  justify-content: space-between;
}
</style>

 index.vue

调用组件

<template>
      <el-main class="elp-main">
        <Tabs/>
        <transition name="fade" mode="out-in">
          <keep-alive :include="tabsList">
          <router-view :key="$route.path"></router-view>
          </keep-alive>
        </transition>
    </el-main>
</template>

<script>
 import Tabs from '@/components/tabPane'
export default{
 computed: {
    tabsList(){
      return this.$store.state.tabsList
    },
  },
}
</script>

仓库里的内容

import Vuex from 'vuex'

Vue.use(Vuex)


export default new Vuex.Store({
  state: {
    editableTabs: [],
    aliveList:[],
    tabsList:'',
  },
  actions:{
    setList({commit},payload){
      commit('setTableList',payload)
    },
    setEdit({commit},payload){
      commit('setEdittableTabs',payload)
    }
  },
  mutations: {
    setEdittableTabs(state,payload){
      state.editableTabs=payload
    },
    setTableList(state,payload){
        // this.dispatch('setList',payload)
      state.aliveList=payload.map((item)=>{
        return item
      })
      state.tabsList=state.aliveList.join(',')
    
    }
  },
})

router.js

这是路由的内容,需要注意name需要和.vue文件里的name一致,要不缓存不生效,title是你在缓存的标签页展示的内容

 const routes=[ {
        path: "/dataManagement",
        name: "DataManagement",
        component: () => import("../views/dataManagement/index.vue"),
        children: [
            {
                path: 'storeManagement',
                name: 'StoreManagement',
                component: () => import("../views/dataManagement/storeManagement/index.vue"),
                meta: {
                    title: '仓库管理'
                },
                // redirect: function() {
                //     return {name: 'mdmStore'}
                // },
                children: [
                    {
                        path: 'mdmStore',
                        name: 'mdmStore',
                        meta: {
                            title: 'MDM仓库管理'
                        },
                        component: () => import('../views/dataManagement/storeManagement/mdmStore/index.vue')
                    },
                    {
                        path: 'storeList',
                        name: 'storeList',
                        meta: {
                            title: '仓库管理'
                        },
                        component: () => import('../views/dataManagement/storeManagement/storeList')
                    },
                    // 新增仓库
                    {
                        path: 'storeList/addList',
                        name: 'addList',
                        component: () => import('../views/dataManagement/storeManagement/storeList/components/addList.vue')
                    },
                ]
            }
}]
function handleKeepAlive(to) {
    if (to.matched && to.matched.length > 2) {
        for (let i = 0; i < to.matched.length; i++) {
            const element = to.matched[i]
            if (element.components.default.name === 'StoreManagement') {
                to.matched.splice(i, 1)
            }
        }
    }
}
    //路由守卫
    router.beforeEach((to, from, next) => {
        handleKeepAlive(to)
        next();
    });

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值