天天看点

【VUE】实现自适应页面、内容不等、高度保持一致的跑马灯

遇到一个问题,在一个自适应页面中做跑马灯,因为内容高度有差异,如果采用常规的v-if 显示对应的卡片,那么跑马灯的高度会在切换过程中发生变化,所以将内容横排,使用scroll的方式,滚动卡片,这样整个卡片的高度就以内容最多的卡片为准了。

具体实现:

跑马灯组件的template如下所示,上半部分为内容展示,下半部分为切换按钮,当鼠标进入的时候卡片悬停,鼠标离开时卡片继续切换。展示内容由父组件传入。

<template>
  <div class="carousel">
    <div class="list" ref="list" @mouseenter="stop()" @mouseleave="setTimer()">
      <div v-for="(item, index) in listData" class="card" :key="index">
        <div :class="{'active': index===currentIndex,'unactive': index!==currentIndex}">
          <slot :list="item" name="item"></slot>
        </div>
      </div>
    </div>
    <div class="change">
      <div
        class="item"
        :class="{'active': currentIndex ===index }"
        v-for="(list, index) in listData"
        :key="index"
        @click="jumpTo(index)"
      ></div>
    </div>
  </div>
</template>
           

listdata通过props传入;

props: ["listData"],
           

在也页面渲染完毕后设置timer,控制页面滚动,在页面destoryed的时候切记要销毁timer。

mounted() {
    this.timer = setInterval(this.start, 2500);
  },

  destroyed() {
    clearInterval(this.timer);
  }
           

在方法中定义start,通过isHover字段是否停止切换,控制控制页面的切换过程,通过ref取得每张卡片在整个滚动页面的位置,通过设置页面滚动到特定位置实现卡片的切换,即成跑马灯。 

methods: {
    start() {
      if (this.isHover) {
        //鼠标悬浮的时候停止切换
        return;
      }
      if (this.currentIndex === this.listData.length - 1) {
        // 判断是否到达最后一个卡片,到最后一个后切换到第一个
        this.jumpTo(0);
      } else {
        //  不在最后一个卡片的话,就顺序切换
        this.jumpTo(++this.currentIndex);
      }
    },
    setTimer() {
    // 鼠标离开
      this.isHover = false;
    },
    stop() {
     // 鼠标悬停
      this.isHover = true;
    },
    setCardPosition() {
    // 横向滚动页面, 每个页面等宽,所以滚动宽度直接用 当前index*每个卡片宽度
      this.$refs.list.scrollLeft =
      this.$refs.list.clientWidth * this.currentIndex;
    },
    jumpTo(index) {
    // 通过currentIndex控制按钮的active状态
      this.currentIndex = index;
      this.setCardPosition();
    }
  },
           

附上css:

<style  scoped>
.carousel {
  .list {
    width: 100%;
    display: flex;
    overflow: hidden;
    .card {
      min-width: 100%;
      position: relative;
      cursor: pointer;
    }
    .active {
      position: relative;
      transition: left ease-in 0.5s;//设置动画效果
      left: 0;
    }
    .unactive {
      position: relative;
      left: 100%;
      opacity: 0;
    }
  }
  .change {
    display: flex;
    justify-content: center;
    margin-top: 30px;
    .item {
      width: 10px;
      height: 10px;
      cursor: pointer;
      border-radius: 50%;
      background-color: #e6e6e6;
      &:nth-last-of-type(n + 2) {
        margin-right: 14px;
      }
      &.active {
        background-color: #60c25b;
      }
    }
  }
}
</style>