vue实现左右滑动tab

4 篇文章 0 订阅

1.两个div,一个outer,一个inner,inner设置absolute,滑动时改变inner的left值

<div class="system-tabs">
      <i
        class="el-icon-arrow-left"
        style="left: 13%"
        @click="arrowClick('pre')"
      ></i>
      <i
        class="el-icon-arrow-right"
        style="right: 13%"
        @click="arrowClick('next')"
      ></i>
      <div class="scroll-outer" ref="scrollOuter">
        <div
          ref="scrollBody"
          class="scroll-body"
          :style="{ left: scrollLeft + 'px' }"
        >
          <span
            :class="{ item, active: tabIndex === index }"
            v-for="(item, index) in sysTabs"
            :key="index"
            @click="tabClick(index)"
          >
            {{ item.name}}
          </span>
        </div>
      </div>
    </div>

样式

&-tabs {
 height: 60px;
 background-color: #333333;
 box-sizing: border-box;
 position: relative;
 i {
   color: #999999;
   font-size: 28px;
   position: absolute;
   height: 60px;
   line-height: 60px;
 }
 .scroll-outer {
   position: absolute;
   left: 15%;
   right: 15%;
   top: 0;
   bottom: 0;
   overflow: hidden;
 }
 .scroll-body {
   height: 100%;
   position: absolute;
   overflow: visible;
   white-space: nowrap;
   -webkit-transition: left 0.3s ease;
   transition: left 0.3s ease;
 }

2.点击左右按钮时事件

arrowClick(type) {
      // 不需要滑动
      if (this.sysTabs.length <= 5) return;
      let outerWidth = this.$refs.scrollOuter.offsetWidth;
      let innerWidth = this.$refs.scrollBody.offsetWidth;
      if (type === "pre") {
        // 往前滑,滑动距离>0说明到最左
        if (this.scrollLeft >= 0) return;
        if (this.scrollLeft + parseInt(innerWidth / 10) > 0) {
          this.scrollLeft = 0;
        } else {
          this.scrollLeft += parseInt(innerWidth / 10);
        }
        this.tabIndex--;
      }
      if (type === "next") {
        // 往后滑,滑动距离>内部scroll宽度-外部scroll宽度,说明到最右
        if (this.tabIndex === this.sysTabs.length) return;
        if (-this.scrollLeft > innerWidth - outerWidth) return;
        if (
          -(this.scrollLeft - parseInt(innerWidth / 10)) >
          innerWidth - outerWidth
        ) {
          this.scrollLeft = -(innerWidth - outerWidth);
        } else {
          this.scrollLeft -= parseInt(innerWidth / 10);
        }
        this.tabIndex++;
      }
      this.getSysInfo();
    },

3.点击tab页时事件

tabClick(id) {
    if (id === this.tabIndex) return;
    let innerWidth = this.$refs.scrollBody.offsetWidth;
    let outerWidth = this.$refs.scrollOuter.offsetWidth;
    // 计算本次滑动距离
    let scrollWidth =
      parseInt(innerWidth / 10) * Math.abs(id - this.tabIndex);
    if (id > this.tabIndex) {
      // 往后滑
      if (this.scrollLeft - scrollWidth < innerWidth - outerWidth) {
        // 到最右边
        this.scrollLeft = -(innerWidth - outerWidth);
      } else {
        this.scrollLeft -= scrollWidth;
      }
    } else {
      // 往左滑
      if (this.scrollLeft + scrollWidth > 0) {
        // 到最左边
        this.scrollLeft = 0;
      } else {
        this.scrollLeft += scrollWidth;
      }
    }
    this.tabIndex = id;
    this.getSysInfo();
  }
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。首先,你需要在html中创建tab标签和箭头按钮的结构,然后使用Vue编写相应的逻辑。 以下是一个简单的实现示例: HTML结构: ``` <div id="app"> <div class="tab-container"> <div class="tab-scroll"> <ul class="tab-list" :style="{ width: tabWidth + 'px' }"> <li v-for="(tab, index) in tabs" :key="index" :class="{ active: index === currentTab }" @click="selectTab(index)">{{ tab }}</li> </ul> <div class="arrow prev" @click="scrollTabs('prev')" v-if="showPrev"></div> <div class="arrow next" @click="scrollTabs('next')" v-if="showNext"></div> </div> </div> </div> ``` CSS样式: ``` .tab-container { position: relative; overflow: hidden; } .tab-scroll { position: relative; white-space: nowrap; } .tab-list { display: inline-block; padding: 0; margin: 0; list-style: none; } .tab-list li { display: inline-block; padding: 10px; cursor: pointer; } .tab-list li.active { background: #f2f2f2; color: #333; } .arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 30px; height: 30px; background: #ccc; cursor: pointer; } .arrow.prev { left: 0; } .arrow.next { right: 0; } ``` Vue逻辑: ``` new Vue({ el: '#app', data: { tabs: ['Tab 1', 'Tab 2', 'Tab 3', 'Tab 4', 'Tab 5', 'Tab 6', 'Tab 7', 'Tab 8', 'Tab 9', 'Tab 10'], tabWidth: 0, currentTab: 0, showPrev: false, showNext: false }, mounted() { this.calculateTabWidth(); this.checkArrows(); }, methods: { calculateTabWidth() { let tabList = this.$el.querySelector('.tab-list'); let tabs = this.$el.querySelectorAll('.tab-list li'); let tabWidth = 0; tabs.forEach(tab => { tabWidth += tab.offsetWidth; }); this.tabWidth = tabWidth; }, checkArrows() { let tabContainer = this.$el.querySelector('.tab-container'); let tabList = this.$el.querySelector('.tab-list'); if (tabList.offsetWidth > tabContainer.offsetWidth) { this.showNext = true; } else { this.showNext = false; } if (tabList.offsetWidth - tabList.scrollLeft > tabContainer.offsetWidth) { this.showPrev = true; } else { this.showPrev = false; } }, scrollTabs(dir) { let tabContainer = this.$el.querySelector('.tab-container'); let tabList = this.$el.querySelector('.tab-list'); let containerWidth = tabContainer.offsetWidth; let scrollLeft = tabList.scrollLeft; if (dir === 'prev') { this.currentTab--; } else { this.currentTab++; } if (this.currentTab < 0) { this.currentTab = 0; } else if (this.currentTab >= this.tabs.length) { this.currentTab = this.tabs.length - 1; } let tabPos = this.$el.querySelectorAll('.tab-list li')[this.currentTab].offsetLeft; if (tabPos < 0 || tabPos + this.$el.querySelectorAll('.tab-list li')[this.currentTab].offsetWidth > containerWidth) { if (dir === 'prev') { tabList.scrollTo({ left: scrollLeft - this.$el.querySelectorAll('.tab-list li')[this.currentTab].offsetWidth, behavior: 'smooth' }); } else { tabList.scrollTo({ left: scrollLeft + this.$el.querySelectorAll('.tab-list li')[this.currentTab].offsetWidth, behavior: 'smooth' }); } } this.checkArrows(); }, selectTab(index) { this.currentTab = index; this.checkArrows(); } } }); ``` 在这个示例中,我们使用了一个包含所有tab标签的ul元素和两个箭头按钮的div元素。我们使用CSS使这些元素在父容器中水平居中,并将tab标签的列表项设置为inline-block以便它们可以在同一行上排列。 我们使用Vue的数据绑定将tab标签数组、tab列表的宽度、当前选中的标签和箭头按钮的显示状态添加到Vue实例中。我们使用mounted钩子函数计算tab列表的宽度,并检查箭头按钮的显示状态。 我们添加了三个方法:calculateTabWidth用于计算tab列表的宽度,checkArrows用于检查箭头按钮的显示状态,scrollTabs用于滚动到下一个或前一个tab标签。在scrollTabs函数中,我们首先根据箭头按钮的方向滚动到下一个或前一个标签,并将currentTab变量更新为相应的标签。然后,我们计算新的tab标签位置,并检查它是否在容器中可见。如果不是,则使用scrollTo方法滚动到新标签。最后,我们调用checkArrows方法来检查箭头按钮的显示状态。 我们还添加了selectTab方法,用于在单击tab标签时更新currentTab变量,并调用checkArrows方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值