vue实现tag 标签内容过长添加左右按钮进行滑动

点击箭头,标签内容可左右移动,每次移动一个盒子的宽度,若数据长度不够则移动到最有一个(或者第一个的位置) 

<template> 中的代码

<div class="tags-list" ref="totalLists">
  <div class="arrow-icon" @click="arrowBack" v-if="showButton">
    <svg-icon
      :icon-class="'arrow-back'"
      class="icon arrow-style"
    ></svg-icon>
  </div>
  <div class="tag-style" ref="tagBox">
    <div
      class="scrollWrapper"
      ref="scrollWrapper"
      id="nav"
      :style="{ marginLeft: tabScroll }"
    >
      <el-tag
        v-for="(tag, index) in tagsList"
        :key="tag.name"
        :closable="tag.del"
        @close="handleTagsClose(tag, index)"
        @click="highTags(tag, index)"
        :class="index == currentTagIndex ? 'highStyle' : 'normalStyle'"
        type="info"
      >
        {{ tag.name }}
      </el-tag>
    </div>
  </div>
  <div class="arrow-icon" @click="arrowForward" v-if="showButton">
    <svg-icon
      :icon-class="'arrow-forward'"
      class="icon arrow-style"
    ></svg-icon>
  </div>
</div>

 data 中的数据

data() {
  return {
    tabScroll: "0px", // 移动的距离
    tagsList: [
      {
        name: "工作台",
        path: "workbench",
        del: false,
      },
      {
        name: "工作台",
        path: "workbench",
        del: false,
      },
      {
        name: "工作台",
        path: "workbench",
        del: false,
      }
    ],
    showButton: false, // 标签左右两侧箭头是否显示
    swiperScrollWidth: 0, // 盒子的宽度
    swiperScrollContentWidth: 0, // 内容的宽度
  };
}

mounted 中添加监听的代码

window.addEventListener("resize", this.checkButtonStatus);

methods 中的方法

// 标签向左切换
arrowBack() {
  let tabBoxWidth = this.$refs.tagBox.clientWidth; //盒子宽度
  let offsetLeft = Math.abs(this.$refs.scrollWrapper.offsetLeft); //移动距离
  if (offsetLeft > tabBoxWidth) {
    //移动距离大于父盒子宽度,向前移动一整个父盒子宽度
    this.tabScroll = offsetLeft + tabBoxWidth + "px";
  }else {
    this.tabScroll = "0px";// 否则移动到开始位置
  }
},
// 标签向右切换
arrowForward() {
  let tabBoxWidth = this.$refs.tagBox.clientWidth; //盒子宽度
  let scrollWidth = this.$refs.scrollWrapper.scrollWidth; //内容宽度
  // 必须要在循环的父级添加 定位样式, offsetLeft 获取元素相对带有定位父元素左边框的偏移
  let offsetLeft = Math.abs(this.$refs.scrollWrapper.offsetLeft); //移动距离
  let diffWidth = scrollWidth - tabBoxWidth; //计算内容宽度与盒子宽度的差值
  if (diffWidth - offsetLeft > tabBoxWidth) {
    //判断差值减去移动距离是否大于盒子宽度 大于则滚动已移动距离+盒子宽度
    this.tabScroll = -(offsetLeft + tabBoxWidth) + "px";
  }else {
    this.tabScroll = -diffWidth + "px"; //小于则移动差值距离
  }
},
checkButtonStatus() {
  if (!this.$refs.scrollWrapper) return;
  // 盒子的宽度
  let containerSize = this.$refs.tagBox.clientWidth;
  // 内容的宽度
  let navSize = this.$refs.scrollWrapper.scrollWidth;
  if (containerSize > navSize || containerSize == navSize) {
    this.showButton = false;
  }else {
    this.showButton = true;
  }
},

<style> 中的样式

.tags-list {
  margin: 4px 0;
  display: flex;
  align-items: center;
    .tag-style {
      display: flex;
      align-items: center;
      overflow: hidden;
      pointer-events: all;
      cursor: pointer;
      position: relative; // 必须添加该定位,offsetLeft 获取元素相对带有定位父元素左边框的偏移
      .scrollWrapper {
        display: flex;
        align-items: center;
        overflow-x: auto;
        transition:all 500ms linear
      }
      .scrollWrapper::-webkit-scrollbar {
        height: 0;
      }
      .el-tag {
        height: 32px;
        margin-right: 4px;
        cursor: pointer;
      }
      .el-tag.el-tag--info {
        background: #fff;
        color: $text-color;
      }
      .highStyle {
        color: #1890FF !important;
        font-size: 14px;
        font-weight: 400;
        padding: 0 16px;
      }
      .normalStyle {
        font-size: 14px;
        font-weight: 400;
        padding: 0 16px;
      }
    }
  .arrow-icon {
    width: 32px;
    height: 32px;
    pointer-events: all;
    cursor: pointer;
      .arrow-style {
        font-size: 16px;
        padding: 0 8px;
        position: relative;
        top: 8px;
      }
   }
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Vue卡片左右重叠并且左右滑动,可以使用CSS3的transform属性和transition属性,以及Vue的动态绑定class属性。以下是一个简单的实现思路: 1. 在组件中添加一个卡片容器,设置overflow: hidden属性和white-space: nowrap属性,使卡片可以水平滚动并且超出容器范围的部分被隐藏。 2. 使用flex布局,将卡片设置为均匀分布,并且设置卡片的z-index属性和transform属性,使卡片左右重叠。 3. 在卡片容器上添加touchstart、touchmove、touchend事件的监听函数。 4. 在touchstart事件中记录起始位置的横坐标和当前卡片的索引。 5. 在touchmove事件中计算当前位置的横坐标与起始位置的横坐标的差值,并根据差值设置卡片的transform属性。 6. 在touchend事件中判断差值是否超过一定的阈值,如果是则根据差值的正负来判断卡片是向左滑动还是向右滑动,并根据卡片的位置来设置是否切换到下一个卡片。 7. 使用Vue的动态绑定class属性来根据当前卡片的索引来设置卡片的z-index属性和transform属性,以实现左右重叠效果。 8. 使用CSS3的transition属性实现卡片的平滑过渡效果。 以下是一个简单的代码示例: ```html <template> <div class="card-container" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd"> <div class="card" :style="{ transform: `translateX(${translateX}px)`, zIndex: currentIndex }" :class="{ 'active': currentIndex === index }" v-for="(item, index) in items" :key="index"> {{ item }} </div> </div> </template> <script> export default { data() { return { items: ['Card 1', 'Card 2', 'Card 3', 'Card 4'], currentIndex: 0, startX: 0, translateX: 0 }; }, methods: { onTouchStart(event) { this.startX = event.touches[0].clientX; this.currentIndex = Math.floor(this.startX / (window.innerWidth / this.items.length)); }, onTouchMove(event) { const currentX = event.touches[0].clientX; this.translateX = currentX - this.startX; }, onTouchEnd(event) { const threshold = 50; if (Math.abs(this.translateX) > threshold) { this.currentIndex += this.translateX > 0 ? -1 : 1; if (this.currentIndex < 0) { this.currentIndex = 0; } else if (this.currentIndex >= this.items.length) { this.currentIndex = this.items.length - 1; } } this.startX = 0; this.translateX = 0; } } }; </script> <style scoped> .card-container { display: flex; overflow: hidden; white-space: nowrap; padding: 10px; } .card { flex: 0 0 80%; height: 200px; padding: 20px; background-color: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); transition: transform 0.3s ease-out, z-index 0s linear; } .card.active { flex: 0 0 100%; z-index: 2; transform: translateX(0) scale(1.1); } .card.active + .card { z-index: 1; transform: translateX(50%) scale(0.9); } .card.active + .card + .card { z-index: 0; transform: translateX(100%) scale(0.8); } </style> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值