vue 类似tab标题滚动 标签左右滚动

这个示例展示了如何在固定宽度的容器中动态显示不固定数量的标签,每个标签的字数可能不同。通过左右按钮实现滚动查看超出可视区域的标签,使用Vue.js的数据绑定和事件处理来实现滚动逻辑。代码中定义了数据属性和方法来处理标签的显示位置和滚动操作,确保所有标签都能在需要时被访问到。
摘要由CSDN通过智能技术生成

在固定的宽度内,展示不固定标签列表,且每个标签的字数不确定。
在这里插入图片描述

<template>
  <div class="tag-box">
    <div class="tag-list">
      <ul ref="tagList" :style="{left: -nowLeft + 'px'}">
        <li v-for="(item, index) in list" :key="index" :ref="'li'+ index">
          <span
            class="tag"
            :class="{'tag-active': id === item.id}">
            {{ item.tag_name }}
          </span>
        </li>
      </ul>
    </div>
    <a-icon type="left" class="icon-lf" v-show="showLf" @click="handleLeft" />
    <a-icon type="right" class="icon-rt" v-show="showRt" @click="handleRight" />
  </div>
</template>

<script>
export default {
  data () {
    return {
   	  list:[
         { id: 0, tag_name: '全部' },
         { id: 1, tag_name: '其他1' },
         { id: 2, tag_name: '其他2其他2' },
         { id: 9, tag_name: '其他' },
         { id: 3, tag_name: '其他3其他3' },
         { id: 4, tag_name: '其他4其' },
         { id: 5, tag_name: '其他5' },
         { id: 6, tag_name: '其他6其他3' },
         { id: 7, tag_name: '其他7' },
         { id: 8, tag_name: '其他8' }
      ],
      id: 0,
      nowNum: 0, // 滚动了几次
      showLf: false, // 左侧按钮 显隐
      showRt: false, // 右侧按钮 显隐
      allWidth: 0, // 内容总宽
      nowLeft: 0,
      nowIndex: 0 // 显示部分的第一个index
    }
  },
  methods: {
    handleLeft () {
      if (this.nowLeft > 0) {
        this.nowNum--
        this.showRt = true
        if (this.nowNum > 0) {
          let nw = 0
          for (let j = this.list.length; j >= 0; j--) {
            if (j < this.nowIndex) {
              nw += this.$refs['li' + j][0].offsetWidth
              if (nw >= 220) {
                nw -= this.$refs['li' + j][0].offsetWidth
                this.nowLeft -= nw
                this.nowIndex = j + 1
                break
              }
            }
          }
        } else {
          this.nowLeft = 0
          this.nowIndex = 0
          this.showLf = false
        }
      }
    },
    handleRight () {
      if (this.nowLeft + 220 < this.allWidth) {
        this.nowNum++
        this.showLf = true
        let nw = 0
        for (let i = 0; i < this.list.length; i++) {
          if (i >= this.nowIndex) {
            nw += this.$refs['li' + i][0].offsetWidth
            if (nw > 220) {
              nw -= this.$refs['li' + i][0].offsetWidth
              this.nowLeft += nw
              this.nowIndex = i
              break
            }
          }
        }
        if (this.nowLeft + 220 >= this.allWidth) {
          this.showRt = false
        }
      }
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.allWidth = this.$refs.tagList.offsetWidth
      if (this.allWidth > 220) { // 220为固定宽度
        this.showRt = true
      }
    })
  }
}
</script>

<style lang="less" scoped>
  .tag-box{
    width: 260px;
    padding: 0 20px;
    height: 28px;
    position: relative;
    .tag-list{
      width: 220px;
      height: 100%;
      overflow: hidden;
      position: relative;
      ul{
        transition-duration: 0.3s;
        position: absolute;
        top: 0px;
        left: 0px;
        margin: 0;
        padding: 0;
        display: flex;
        flex-wrap: nowrap;
        li{
          white-space: nowrap;
          display: inline-block;
          white-space: nowrap;
          padding: 0 10px;
        }
        li:first-child{
          padding-left: 0;
        }
        li:last-child{
          padding-right: 0;
        }
      }
      .tag{
        cursor: pointer;
        display: inline-block;
        height: 28px;
        line-height: 28px;
        transition: border-color .2s;
        &:hover{
          color: #e72521;
        }
      }
      .tag-active{
        color: #e72521;
      }
    }
    .icon-lf{
      cursor: pointer;
      line-height: 28px;
      position: absolute;
      left: 5px;
      top: 2px;
    }
    .icon-rt{
      line-height: 28px;
      cursor: pointer;
      position: absolute;
      right: 5px;
      top: 2px;
    }
  }
</style>

获取动态ref
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值