slider.vue组件的模板部分
<template> <div class="slider" ref="slider"> <div class="slider-group" ref="sliderGroup"> //要注意slot插槽里面的数据要先渲染出来 <slot> </slot> </div> <div class="dots"> <span class="dot" :class="{active: currentPageIndex === index }" v-for="(item, index) in dots" :key="index"></span> </div> </div> </template>
<script> import {addClass} from '../../common/js/dom.js' import BScroll from 'better-scroll' export default{ data() { return { dots:[], currentPageIndex: 0 } }, props: { loop: { type: Boolean, default: true }, autoPlay: { type: Boolean, default: true }, interval: { type: Number, default: 1000 }, showDot: { type: Boolean, default: true }, click: { type: Boolean, default: true }, threshold: { type: Number, default: 0.3 }, speed: { type: Number, default: 400 } }, mounted() { this._setSliderWidth() setTimeout(() => { // 在初始化slider前初始化dot this._initDots() this._initSlider() if (this.autoPlay) { this._play() } }, 20) // 监听窗口大小改变时间 window.addEventListener('resize', () => { if (!this.slider) { return } this._setSliderWidth(true) this.slider.refresh() }) }, methods:{ _setSliderWidth(isResize) { this.children = this.$refs.sliderGroup.children let width = 0 // slider 可见宽度 let sliderWidth = this.$refs.slider.clientWidth for (let i = 0; i < this.children.length; i++) { let child = this.children[i] // 设置每个子元素的样式及高度 addClass(child, 'slider-item') child.style.width = sliderWidth + 'px' // 计算总宽度 width += sliderWidth } // 循环播放首尾各加一个,因此总宽度还要加两倍的宽度 if (this.loop && !isResize) { width += 2 * sliderWidth } this.$refs.sliderGroup.style.width = width + 'px' }, _initSlider() { this.slider = new BScroll(this.$refs.slider, { scrollX: true, scrollY: false, momentum: false, snap: { loop: this.loop, threshold: this.threshold, speed: this.speed }, bounce: false, stopPropagation: true, click: this.click }); this.slider.on("scrollEnd", this._onScrollEnd); this.slider.on("touchEnd", () => { if (this.autoPlay) { this._play(); } }); this.slider.on("beforeScrollStart", () => { if (this.autoPlay) { clearTimeout(this.timer); } }); }, _onScrollEnd() { let pageIndex = this.slider.getCurrentPage().pageX; this.currentPageIndex = pageIndex; // 第一轮1(第一张图) 2 3 4 0(最后一张图索引为0 因为放在了最前面) 1 2 3 4 0 if (this.autoPlay) { this._play(); } }, _initDots() { this.dots = new Array(this.children.length); }, _play() { clearTimeout(this.timer); this.timer = setTimeout(() => { this.slider.next(); }, this.interval); } }, watch: { loop() { this.update(); }, autoPlay() { this.update(); }, speed() { this.update(); }, threshold() { this.update(); } } } </script>