vue使用el-tabs实现标签页(内存+vuex)

2022年6月5日10:16:17

vue使用el-tabs实现标签页(内存+vuex)
效果图:
1:
vue使用el-tabs实现标签页(内存+vuex)

2:
vue使用el-tabs实现标签页(内存+vuex)
3:内存中
vue使用el-tabs实现标签页(内存+vuex)

这是一个组件,例如:pageTabs.vue(组件是可以做到独立监听路由变化的,所以不需要外部调用什么内部的方法,所以可以抽离成为一个组件),监听路由改变进行新增标签,以及el-tabs组件的切换,删除
代码:
<template><divclass="page-tabs-index"><el-tabs v-model="activeRoute"type="card" :closable="closable" @tab-click="clickTab" @edit="handleTabsEdit"><el-tab-pane
        :key="index"
        v-for="(item, index) in tabs"
        :label="item.title"
        :name="item.route"><spanslot="label" @click.middle="removeTabByMiddle(item.route)">{{item.title}}</span></el-tab-pane></el-tabs></div></template><script>export default{data(){
        return{
          closable: false,
          activeRoute:'',
          tabs:[]}},
      methods:{
        // 增删tabs
        handleTabsEdit(targetName,action){
          // console.log('tab增删:',targetName,action);
          if(action==='remove'){
            this.methods('removeTab',targetName);
            this.methods('checkClosable');}},
        // 鼠标中键删除
        removeTabByMiddle(route){
          if(this.closable){
            this.methods('removeTab',route);
            this.methods('checkClosable');}},
        // 点击tab,item是被选中的标签的vue实例
        clickTab(item){
          if(this.$route.name=== item.name){return;}
          // console.log('tab切换:', item.name);
          this.$router.push({name:item.name})},
        // 这里需要配合keep-alive的includeAPI,设置vuex的缓存list,以实现tab关闭后vue不缓存该页面
        // 加载tabs缓存loadTabs(){
          const pageTabs= sessionStorage.getItem('page-tabs');if(pageTabs){
            this.tabs= JSON.parse(pageTabs);}
          this.$store.commit('setKeepAliveList',this.tabs.map(i=>i.route));},

        // tab切换更新updateTabs(){
          const route= this.$route.name;
          const title= route;
          if(!route|| route==='index'){
            // 这里是处理layout中第一次加载会是null,后续由监听$route更新,(index路由是引导用的,不需要)
            // 而如果是当从没有tabs的页面跳转过来时,不走下面,将不会变更当前激活return;}
          // 新增if(!this.tabs.find(i=> i.route=== route)){
            this.tabs.push({ route, title});}
          this.activeRoute= route;
          // this.$route.meta.keepAlive=true;
          // 缓存tabs
          sessionStorage.setItem('page-tabs', JSON.stringify(this.tabs));
          this.$store.commit('setKeepAliveList',this.tabs.map(i=>i.route));},

        // 移除tab
        removeTab(route){
          // 保存indexlet index= this.tabs.findIndex(i=> i.route=== route);
          this.tabs= this.tabs.filter(i=> i.route!== route);
          this.$store.commit('setKeepAliveList',this.tabs.map(i=>i.route));
          // 如果删除的是当前的routeif(this.activeRoute=== route){
            // 将当前激活route切换为刚才删除的后一个if(index> this.tabs.length-1){
              index -=1;}
            this.activeRoute= this.tabs[index].route;
            // this.$route.meta.keepAlive=false;
            this.$router.push({ name: this.activeRoute});}
          // 缓存tabs
          sessionStorage.setItem('page-tabs', JSON.stringify(this.tabs));},

        // 检查是否可以继续删除checkClosable(){
          this.closable= this.tabs.length>1;}},created(){
          // this.lists= this.$store.state.other.houseList;},mounted(){
        this.loadTabs()
        this.updateTabs()
        this.checkClosable()},
      watch:{
        $route(){
          this.loadTabs()
          this.updateTabs()
          this.checkClosable()}}}</script><style scopedlang="scss">
// 组件高度$tabLineHeight:30px;
// 边框颜色$borderColor:#488ba0;
// 未激活的以及tab本身的背景$background:#09142e;
// 激活的标签的背景$background-active:#488ba0;
// 未激活标签的字体颜色$fontColor:#30c0cd;
.page-tabs-index{
  height:$tabLineHeight;
  ::v-deep .el-tabs{}
  // 底部横线
  ::v-deep .el-tabs__header{
    height:$tabLineHeight;
    background:$background;
    box-sizing: border-box;
    border-bottom: 1px solid$borderColor;}
  // 左右滚动按钮
  ::v-deep .el-tabs__nav-prev{
    height:$tabLineHeight;
    line-height:$tabLineHeight;}
  ::v-deep .el-tabs__nav-next{
    height:$tabLineHeight;
    line-height:$tabLineHeight;}
  ::v-deep .el-tabs__nav{
    border-radius:0;
    border-left: none;
    border-right: none;
    border-top: none;}

  ::v-deep .el-tabs__item{
    height:$tabLineHeight;
    line-height:$tabLineHeight;
    border-color:$borderColor;
    color:#fff;
    border-right: 1px solid$borderColor;
    //border-radius: 3px 3px00;}

  // 左侧第一个
  ::v-deep .el-tabs__item.is-active:first-child{
    border-left: none;}

  ::v-deep .el-tabs__item:not(.is-disabled){
    color:$fontColor;
    border-left: none;
    border-top: 2px solid transparent;}

  ::v-deep .el-tabs__item.is-active{
    border-bottom: 1px solid$background-active;
    border-top: 2px solid$borderColor;
    border-right: 1px solid$borderColor;
    background:$background-active;
    color:#fff;}}</style>
然后还需要创建一个vuex
export default{
  name:'pageTabs',
  state:{
      keepAliveList:[],},
  mutations:{
    setKeepAliveList(state, list){
      state.keepAliveList= list}}}
然后就去入口页面引入使用即可,例如App.vue
<template><divid="app"class="biggbox"><pageTabs></pageTabs><!-- 中部 --><transition><router-view></router-view></transition></div></template>
还可以用keepAlive
<keep-alive :include="keepAliveList"><router-view></router-view></keep-alive>
  • 作者:_小郑有点困了
  • 原文链接:https://blog.csdn.net/qq_44706619/article/details/116598879
    更新时间:2022年6月5日10:16:17 ,共 4045 字。