vue轮播组件(兼容IE10+)

组件内容 

<template>
  <div class="bannerBox" :style="imgStyle" @mouseover="stopAuto" @mouseout="autoPlayFunc">
    <div class="bannerList" :style="bannerListStyle">
      <img :src="imgList[imgList.length-1]" :style="imgStyle" />
      <img v-for="imgOne in imgList" :key="imgOne" :src="imgOne" :style="imgStyle" />
      <img :src="imgList[0]" :style="imgStyle" />
    </div>
    <div class="banner-direction" v-show="show">
      <span class="banner-left" @click="toLeft"><</span>
      <span class="banner-right" @click="toRight">></span>
    </div>
    <div class="banner-dots">
      <button
        v-for="(item,index) in imgList.length"
        :key="index"
        :class="{active:index==dotsIndex}"
        @click="toDots(index)"
      ></button>
    </div>
  </div>
</template>
<script>
let interval = null,
  timeout = null;

export default {
  name: "banner",
  props: {
    width: {
      //图片的宽度
      type: Number,
      default: 500,
    },
    height: {
      //图片的高度
      type: Number,
      default: 300,
    },
    interval: {
      //自动切换时间间隔
      type: Number,
      default: 5000,
    },
    duration: {
      //滑动动画时长
      type: Number,
      default: 3000,
    },
    imgList: {
      //图片列表
      type: Array,
      default: [],
    },
    current: {
      //当前所在滑块的index
      type: Number,
      default: 0,
    },
    autoPlay: {
      //是否自动播放
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      currentDuration: this.duration,
      imgIndex: this.current,
      dotsIndex: this.current - 1,
      show: false,
    };
  },
  created() {
    if (this.autoPlay) {
      this.autoPlayFunc();
    }
  },
  computed: {
    imgStyle() {
      return {
        width: this.width + "px",
        height: this.height + "px",
      };
    },
    bannerListStyle() {
      const currentDuration = this.currentDuration;
      const currentLeft = -this.imgIndex * this.width + "px";
      console.log(currentLeft);
      return {
        width: this.width * (this.imgList.length + 2) + "px",
        height: this.height + "px",
        transition: "all " + currentDuration + "ms",
        "-moz-transition": "all " + currentDuration + "ms",
        "-webkit-transition": "all " + currentDuration + "ms",
        "-o-transition": "all " + currentDuration + "ms",
        transform: "translateX(" + currentLeft + ")",
        "-moz-transform": "translateX(" + currentLeft + ")",
        "-webkit-transform": "translateX(" + currentLeft + ")",
        "-o-transform": "translateX(" + currentLeft + ")",
      };
    },
  },
  destroyed() {
    clearInterval(interval);
    clearTimeout(timeout);
  },
  methods: {
    stopAuto() {
      clearInterval(interval);
      clearTimeout(timeout);
      this.show = true;
    },
    autoPlayFunc() {
      clearInterval(interval);
      this.show = false;
      interval = setInterval(() => {
        this.toRight();
      }, this.interval);
    },
    toRight() {
      if (this.imgIndex == this.imgList.length) {
        this.currentDuration = 0;
        this.imgIndex = 0;
        this.dotsIndex = 0;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          this.$nextTick(function () {
            this.currentDuration = this.duration;
            this.imgIndex++;
          });
        }, 30);
      } else {
        this.imgIndex++;
        this.dotsIndex++;
      }
    },
    toLeft() {
      if (this.imgIndex == 1) {
        this.currentDuration = 0;
        this.imgIndex = this.imgList.length + 1;
        this.dotsIndex = this.imgList.length - 1;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          this.$nextTick(function () {
            this.currentDuration = this.duration;
            this.imgIndex--;
          });
        }, 30);
      } else {
        this.imgIndex--;
        this.dotsIndex--;
      }
    },
    toDots(index) {
      this.dotsIndex = index;
      this.imgIndex = index + 1;
    },
  },
};
</script>
<style scoped>
.bannerBox {
  position: relative;
  overflow: hidden;
}
.bannerList {
  position: absolute;
  top: 0;
  left: 0;
  width: 1500px;
  height: 300px;
}
.bannerList img {
  float: left;
}
.banner-direction {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  -moz-transform: translateY(-50%); /* Firefox */
  -webkit-transform: translateY(-50%); /* Safari 和 Chrome */
  -o-transform: translateY(-50%); /* Opera */
  width: 100%;
}
.banner-left,
.banner-right {
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  color: #ffffff;
  background: rgba(0, 0, 0, 0.3);
}
.banner-left {
  float: left;
}
.banner-right {
  float: right;
}
.banner-dots {
  position: absolute;
  bottom: 10px;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.banner-dots button {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin: 0 5px;
  padding: 0;
  background: #ccc;
  border: none;
}
.banner-dots .active {
  background: #ff5500;
}
</style>

引用组件

<template>
  <div>
    <vue-banner :width="400" :height="200" :interval="3000" :duration="1000" :imgList=imgList :current="2"></vue-banner>
  </div>
</template>
<script>
import VueBanner from "@/components/vue-banner/banner";
export default {
  name: "banner",
  data() {
    return {
      imgList: [
        "http://lorempixel.com/640/480/nature",
        "http://lorempixel.com/640/480/technics"
      ],
    };
  },
  components: { VueBanner },
};
</script>
<style scoped>
</style>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值