vue实现tabs页签切换+自适应

具体可查看我的个人博客
::: tip 功能

需封装这样一个组件:如下图所示:

要求:
1、整体宽度自适应
2、左右按钮可使展示区域内容左右切换
:::

思路

视图部分:

<div id="box" class="box">
      <div
        class="icon"
        :style="startIndex == 0 ? 'color:#CCCCCC' : 'color:#3e79fe;'"
        style="position:absolute;left:0"
        @click="tabLeft"
      >
        <i class="el-icon-arrow-left" />
      </div>
      // 用来控制div移动,并加移动效果
      <div
        class="good_city"
        :style="'transform: translateX(' + tabIndex + 'px);'"
      >
        <div class="tabsBox">
          <span
            v-for="item in tabsList"
            :id="'tab' + item.id"
            :key="item.label"
            class="tab"
            :class="tabClick == item.id ? 'tabClick' : ''"
            @click="clickTab(item)"
          >
            {{ item.value }}
          </span>
        </div>
      </div>
      <div
        class="icon"
        :style="
          endIndex == tabsList.length - 1 ? 'color:#CCCCCC' : 'color:#3e79fe;'
        "
        style="position:absolute;right:0"
        @click="tabRight"
      >
        <i class="el-icon-arrow-right" />
      </div>
    </div>

数据部分:

//后期tabslist、需要通过组件传进来
data() {
    return {
      //   tabsList: []
      tabClick: 0, // 选择的tab
      tabIndex: 0, // tab需要移动的宽
      startIndex: 0, // display展示的起始div索引
      endIndex: 0, // display展示的终止div索引
      tabsList: [
        { id: 1, label: '0', value: '人民网' },
        { id: 2, label: '1', value: '新华网' },
        { id: 3, label: '2', value: '中国日报' },
        { id: 4, label: '3', value: '华盛顿邮报' },
        { id: 5, label: '4', value: '央广网' },
        { id: 6, label: '5', value: '央广网2' },
        { id: 7, label: '6', value: '央广网3' },
        { id: 8, label: '7', value: '央广网4' }
      ]
    };
  },

功能部分:

mounted() {
    this.getTabWidth();
    this.setDisplayTab(0);
},
methods: {
// 获取每个tab的宽度,放在 tabslist 中
    getTabWidth() {
      this.tabsList.forEach((item, index) => {
        this.tabsList[index].width = document.getElementById(
          'tab' + item.id
        ).clientWidth;
      });
      console.log(this.tabsList);
    },
    setDisplayTab(inx) {
      // 参数:起始索引
      // 当前展示起始索引startIndex,box宽度,计算<box的索引endIndex,start-end展示,其他隐藏
      // 可展示区域宽度 -- 即box div宽度
      debugger;
      this.fatherWidth = document.getElementById('box').clientWidth;
      let sumWidth = 0;
      this.tabsList.forEach((item, index) => {
        if (index >= inx) {
          sumWidth = sumWidth + item.width + 12;
          // this.endIndex = index;
          if (this.fatherWidth >= sumWidth) {
            document.getElementById('tab' + item.id).style.display =
              'inline-block';
            this.endIndex = index;
          } else {
            document.getElementById('tab' + item.id).style.display = 'none';
          }
        }
      });
    },
    clickTab(it) {
      this.indexBefore = 0; // 之前选中的div
      this.indexNow = 0; // 当前选中的div
      // this.tabidnow = 0; // 需要移动的宽
      this.tabsList.forEach((item, index) => {
        if (item.id === this.tabClick) {
          this.indexBefore = index;
        }
        if (it.id === item.id) {
          this.indexNow = index;
        }
      });
      this.tabClick = it.id;
    },
    tabLeft() {
      // 移动距离tabindex=startIndex-1的宽度,调用setDisplayTab控制显隐
      // 判断是否为初始位置
      if (this.startIndex !== 0) {
        // 向左移动,起始位置-1
        this.startIndex--;
        this.setDisplayTab(this.startIndex);
        this.tabIndex += this.tabsList[this.startIndex].width + 12;
      }
    },
    tabRight() {
      if (this.endIndex < this.tabsList.length - 1) {
        const tabStartBeforeIndex = this.startIndex;
        this.startIndex++;
        this.setDisplayTab(this.startIndex);
        this.tabIndex -= this.tabsList[tabStartBeforeIndex].width + 12;
      }
    }
}

样式部分:

.box {
  width: 100%;
  padding: 0 30px;
  //   min-width: 535px;
  display: flex;
  justify-content: space-between;
  overflow: hidden;
  position: relative;
  .good_city {
    width: 9999px; //这里其实不应该写死 应该写成动态赋值 这里我就先写死
    height: 30px;
    transition: all 0.5s;
  }
  .tabsBox {
    width: 9999px;
    height: 30px;
    display: flex;
    justify-content: flex-start;
    flex-wrap: nowrap;
    overflow: hidden;
    .tab {
      height: 30px;
      //   min-width: 84px;
      padding: 0px 8px;
      margin: 0 5px;
      line-height: 30px;
      border: 1px solid #bbbbbb;
      cursor: pointer;
      text-align: center;
      float: left;
      //   flex-shrink: 1;
    }
    .tabClick {
      background: #3e79fe;
      color: #ffffff;
    }
  }
  .icon {
    text-align: center;
    line-height: 30px;
    padding: 0 8px;
    cursor: pointer;
    background-color: white;
    z-index: 10000;
  }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值