美文网首页
vue实现tab标签切换页面

vue实现tab标签切换页面

作者: 刘其瑞 | 来源:发表于2019-08-28 10:25 被阅读0次

    将标签存放在Tags.vue,使用组件传值进行切换。增加keep-alive缓存机制


    首先展示效果图如下:

    效果如上

    在home或主页面注册tabs组件

          <el-main style="background-color:#eaedf1">
            <!-- 标签组件 -->
            <tabs></tabs>
            <router-view></router-view>
            <!-- 增加keep-alive缓存机制 -->
            <keep-alive :include="tagsList">
                <router-view></router-view>
            </keep-alive>
          </el-main>
    

    在home或主页面进行传值

    <script>
    import Tabs from '@/components/common/Tags.vue'  // 引入Tags组件
    import bus from '@/components/common/bus.js'  // 组件传值使用的bus
    export default {
      created() {
        // 用于keep-alive缓存,只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。
        bus.$on('tags', msg => {
          let arr = []
          for (let i = 0, len = msg.length; i < len; i++) {
            msg[i].name && arr.push(msg[i].name)
          }
          this.tagsList = arr
        })
      },
      components: {
        tabs: Tabs,   // 注册tabs组件
        bus,    // 注册bus组件传值公共文件 
      },
      data() {
        return {
          tagsList: [],
        }
      },
      methods: {},
    }
    </script>
    

    新建一个bus.js文件,通用bus.js组件传值

    import Vue from 'vue';
    export default new Vue()
    

    Tags.vue组件

    <template>
      <div class="tags" v-if="showTags">
        <!-- 标签列表 -->
        <ul>
          <li
            class="tags-li"
            v-for="(item,index) in tagsList"
            :class="{'active': isActive(item.path)}"
            :key="index"
          >
            <router-link :to="item.path" class="tags-li-title">{{item.title}}</router-link>
            <span class="tags-li-icon" @click="closeTags(index)">
              <i class="el-icon-close"></i>
            </span>
          </li>
        </ul>
        <div class="tags-close-box">
          <!-- elementUi下拉菜单 -->
          <el-dropdown @command="handleTags">
            <el-button size="mini" type="primary">
              标签选项
              <i class="el-icon-arrow-down el-icon--right"></i>
            </el-button>
            <el-dropdown-menu size="small" slot="dropdown">
              <el-dropdown-item command="other">关闭其他</el-dropdown-item>
              <el-dropdown-item command="all">关闭所有</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
      </div>
    </template>
    
    <script>
    import bus from "./bus";  // 引入通用组件传值组件
    export default {
      data() {
        return {
          tagsList: [], // 存放所有标签
        };
      },
      methods: {
        // 当前选中标签
        isActive(path) {
          return path === this.$route.fullPath;
        },
        // 关闭单个标签
        closeTags(index) {
          const delItem = this.tagsList.splice(index, 1)[0];
          const item = this.tagsList[index]
            ? this.tagsList[index]
            : this.tagsList[index - 1];
          if (item) {
            delItem.path === this.$route.fullPath && this.$router.push(item.path);
          } else {
            this.$router.push("/");
          }
        },
        // 关闭全部标签
        closeAll() {
          this.tagsList = [];
          this.$router.push("/");
        },
        // 关闭其他标签
        closeOther() {
          const curItem = this.tagsList.filter(item => {
            return item.path === this.$route.fullPath;
          });
          this.tagsList = curItem;
        },
        // 设置标签
        setTags(route) {
          const isExist = this.tagsList.some(item => {
            return item.path === route.fullPath;
          });
          if (!isExist) {
            if (this.tagsList.length >= 8) {
              this.tagsList.shift();
            }
            this.tagsList.push({
              title: route.meta.title,
              path: route.fullPath,
              name: route.matched[1].components.default.name
            });
          }
          bus.$emit("tags", this.tagsList); // 组件传值
        },
        // 点击标签下拉选项(关闭其他或者关闭所有)
        handleTags(command) {
          command === "other" ? this.closeOther() : this.closeAll();
        }
      },
      computed: {
        // 大于0则显示标签组件
        showTags() {
          return this.tagsList.length > 0;
        }
      },
      watch: {
        // 当$route发生变化重新赋值
        $route(newValue, oldValue) {
          this.setTags(newValue);
        }
      },
      created() {
        this.setTags(this.$route);
      }
    };
    </script>
    
    
    <style>
    .tags {
      position: relative;
      height: 30px;
      overflow: hidden;
      background: #fff;
      padding-right: 120px;
      box-shadow: 0 5px 10px #ddd;
    }
    
    .tags ul {
      box-sizing: border-box;
      width: 100%;
      height: 100%;
    }
    
    .tags-li {
      float: left;
      margin: 3px 5px 2px 3px;
      border-radius: 3px;
      font-size: 12px;
      overflow: hidden;
      cursor: pointer;
      height: 23px;
      line-height: 23px;
      border: 1px solid #e9eaec;
      background: #fff;
      padding: 0 5px 0 12px;
      vertical-align: middle;
      color: #666;
      -webkit-transition: all 0.3s ease-in;
      -moz-transition: all 0.3s ease-in;
      transition: all 0.3s ease-in;
    }
    
    .tags-li:not(.active):hover {
      background: #f8f8f8;
    }
    
    .tags-li.active {
      color: #fff;
    }
    
    .tags-li-title {
      float: left;
      max-width: 80px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      margin-right: 5px;
      color: #666;
    }
    
    .tags-li.active .tags-li-title {
      color: #fff;
    }
    .tags-li.active {
        border: 1px solid #409EFF;
        background-color: #409EFF;
    }
    a {
        text-decoration: none;
    }
    .tags-close-box {
      position: absolute;
      right: 0;
      top: 0;
      box-sizing: border-box;
      padding-top: 1px;
      text-align: center;
      width: 110px;
      height: 30px;
      background: #fff;
      box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
      z-index: 10;
    }
    </style>
    
    

    相关文章

      网友评论

          本文标题:vue实现tab标签切换页面

          本文链接:https://www.haomeiwen.com/subject/szdyectx.html