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

文章展示了如何在Vue.js应用中创建一个标签列表,用户可以通过点击箭头使标签左右移动。移动距离基于盒子和内容的宽度计算,当达到边界时会自动切换到第一或最后一个标签。此外,还使用了事件监听来处理标签的显示和隐藏状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

<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;
      }
   }
}

### Vue3 实现左右自动轮播效果 在 Vue3 中实现左右自动轮播效果可以通过创建一个自定义组件来完成。该组件能够控制是否自动轮播,并且可以在鼠标悬停时暂停轮播,点击左右按钮或分页指示器也可以切换图片。 #### 组件结构设计 首先定义组件的基础结构,在 `Carousel.vue` 文件中编写如下代码: ```html <template> <div class="carousel"> <!-- 左箭头 --> <button @click="prevSlide" :class="{ hidden: !showArrows }"><</button> <!-- 图片展示区 --> <transition-group tag="ul" name="slide-transition"> <li v-for="(image, index) in images" :key="index" v-show="index === currentIndex"> <img :src="image.src" alt="滑动图片"/> </li> </transition-group> <!-- 右箭头 --> <button @click="nextSlide" :class="{ hidden: !showArrows }">></button> <!-- 分页指示器 --> <div class="pagination"> <span v-for="(item, i) in images" :key="i" :class="{ active: i === currentIndex }" @mouseover="currentIndex = i"></span> </div> </div> </template> ``` #### JavaScript逻辑处理 接着配置脚本部分,管理状态变化以及定时任务: ```javascript <script setup> import { ref, onMounted, onUnmounted } from 'vue'; const props = defineProps({ showArrows: { type: Boolean, default: true }, autoPlay: { type: Boolean, default: false } }); let intervalId; const images = [ { src: '/path/to/image1.jpg' }, { src: '/path/to/image2.jpg' }, { src: '/path/to/image3.jpg' } ]; const currentIndex = ref(0); // 定义方法用于改变当前显示索引 function setIndex(index) { clearInterval(intervalId); currentIndex.value = index; if (props.autoPlay && props.showArrows !== undefined) startAutoPlay(); } // 上一张/下一张幻灯片函数 function prevSlide() { setIndex((currentIndex.value + images.length - 1) % images.length); } function nextSlide() { setIndex((currentIndex.value + 1) % images.length); } // 开始自动播放 function startAutoPlay() { stopAutoPlay(); intervalId = setInterval(() => nextSlide(), 3000); } // 停止自动播放 function stopAutoPlay() { clearInterval(intervalId); } onMounted(() => { if (props.autoPlay) startAutoPlay(); }); onUnmounted(() => { stopAutoPlay(); }); </script> ``` 此段代码实现了基本的轮播图功能,包括自动轮播、手动切换等功能[^1]。 #### 样式美化 最后添加一些简单的样式使轮播更加美观: ```css <style scoped> .carousel { position: relative; } .hidden { display: none; } .pagination span { margin-right: 8px; cursor: pointer; } .active { background-color: red; } .slide-transition-enter-active, .slide-transition-leave-active { transition: all .5s ease-out; } .slide-transition-enter-from, .slide-transition-leave-to { opacity: 0; transform: translateX(-10%); } </style> ``` 这样就完成了基于Vue3框架下的简单轮播图插件开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值