vue手写卡片模式轮播图,无缝切换,每个card设置间距

最近有个需求,需要实现card模式轮播图,每个card大小一样且有间距,本想着用element-ui跑马灯组件Carousel做的,但是试了下达不到我要的效果,于是自己手写,下面先上效果图:
在这里插入图片描述
实现思路:
1.首先使用flex布局+transition动画定义一个简单轮播
2.在原有list基础上前后各追加2个item,比如:[4,5,1,2,3,4,5,1,2],当index=-1或index=5时进行重置处理(-1重置为4,5重置为0),视觉上感觉是无缝切换的。
完整代码:

<div class="swiper-box">
  <div class="prev-btn" @click="changeSwiper(-1)">
    <img src="@/assets/image/newIcon/market/left-icon.png" alt="">
  </div>
  <div class="next-btn" @click="changeSwiper(1)">
    <img src="@/assets/image/newIcon/market/right-icon.png" alt="">
  </div>
  <div class="swiper-list" :style="{left: swiperLeft, transition: transition}">
    <div class="swiper-item" v-for="(item, index) in swiperList" :key="index" 
      :class="{active: swiperIndex+2 == index}" :style="{'background-image': `url(${item.banner})`}">
        <h3>{{ item.name }}</h3>
        <p>{{ item.desc }}</p>
    </div>
  </div>
</div>
data() {
  return {
    tabList: [
      { name: '快速下单', value: 'check', desc: '实现客户ERP物料与平台商品的准确匹配,无需反复搜索,实现快速下单。', banner: require('../../assets/image/newIcon/market/feature-1.jpg') },
      { name: '创业团队', value: 'team', desc: '打造大众创业的服务平台;本着“客户至上”的理念,提供线下招商、销售、售后等环节的专业化服务及解决方案。', banner: require('../../assets/image/newIcon/market/feature-2.jpg') },
      { name: '数据支持', value: 'data', desc: '汇集海量日常销售数据并提供多个维度、多种形式的可视化图表分析。', banner: require('../../assets/image/newIcon/market/feature-3.jpg') },
      { name: '品类齐全', value: 'whole', desc: '覆盖钢铁行业各工序全流程,汇聚优质产品,实现钢企一站式采购。', banner: require('../../assets/image/newIcon/market/feature-4.jpg') },
      { name: '铁信支付', value: 'tx', desc: '除了传统的支付方式,我们还支持铁信支付,河钢铁信是河钢集团推出的电子交易凭证,铁信不仅可以融资、转让,还可以在超市进行备品备件和劳保办公产品购买。', banner: require('../../assets/image/newIcon/market/feature-5.jpg') },
    ],
    tabIndex: 0,
    swiperList: [],
    swiperIndex: 0,
    transition: 'all 0.3s',
  }
},
computed: {
  swiperLeft() {
    return -((this.swiperIndex+2) * (12+0.4) - 3.6) + 'rem'
  }
},
mounted () {
  const list = [
    ...this.tabList.slice(-2),
    ...this.tabList,
    ...this.tabList.slice(0, 2)
  ]
  this.swiperList = list
},
methods: {
  changeSwiper(type) {
  	// 防抖
    if(!debounce(360)){
      return
    }
    if (type === 1) {
      if (this.tabIndex == this.tabList.length - 1) {
        this.tabIndex = 0
      } else {
        this.tabIndex++
      }
      this.swiperIndex++
      if (this.swiperIndex == this.swiperList.length-4) {
        setTimeout(() => {
          this.transition = 'unset'
          this.swiperIndex = 0
        }, 301);
        setTimeout(() => {
          this.transition = 'all 0.3s'
        }, 360);
      }
    } else {
      if (this.tabIndex == 0) {
        this.tabIndex = this.tabList.length-1
      } else {
        this.tabIndex--
      }
      this.swiperIndex--
      if (this.swiperIndex == -1) {
        setTimeout(() => {
          this.transition = 'unset'
          this.swiperIndex = this.swiperList.length-5
        }, 301);
        setTimeout(() => {
          this.transition = 'all 0.3s'
        }, 360);
      }
    }
  },
}
.swiper-box{
  height: 6.88rem;
  position: relative;
  overflow: hidden;
  margin-top: 0.5rem;
  .swiper-list{
    display: flex;
    width: 9999rem;
    height: 6.88rem;
    overflow-x: auto;
    position: absolute;
    top: 0;
    left: -9rem;
    transition: all 0.3s;
    .swiper-item{
      display: flex;
      align-content: center;
      flex-wrap: wrap;
      width: 12rem;
      height: 6.88rem;
      border-radius: 0.4rem;
      margin-right: 0.4rem;
      opacity: 0.6;
      padding: 0 0.95rem;
      &:last-child{
        margin-right: 0;
      }
      &.active{
        opacity: 1;
      }
      h3{
        width: 100%;
        font-size: 0.44rem;
        font-weight: 600;
        color: #fff;
      }
      p{
        width: 4.13rem;
        font-size: 0.18rem;
        color: #fff;
        margin-top: 0.4rem;
      }
    }
  }
  .prev-btn, .next-btn{
    width: 0.8rem;
    height: 0.8rem;
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    z-index: 9;
    cursor: pointer;
    img{
      width: 100%;
      height: 100%;
    }
  }
  .next-btn{
    left: unset;
    right: 1rem;
  }
}
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值