Slider 轮播图组件css
基于Better-scroll
的轮播组件,因此必须首先安装 better-scroll
vue
// slider.vue <template> <!-- 轮播图组件 --> <div class="slider" ref="slider"> <!-- images --> <div class="slider-group" ref="sliderGroup"> <slot></slot> </div> <!-- dots --> <div class="dots"> <span class="dot-item" v-for="(item, index) in dots" :key="index" :class="{'active': currentDotIndex === index}" ></span> </div> </div> </template> <script> import {addClass} from '@/common/js/Dom' import BScroll from 'better-scroll' export default { name: 'slider', props: { loop: { type: Boolean, // 循环播放 default: true }, autoPlay: { type: Boolean, // 自动播放 default: true }, interval: { type: Number, // 滚动的时间间隔 default: 4000 } }, data() { return { dots: [], currentDotIndex: 0 } }, mounted() { setTimeout(() => { this._setSliderWidth() this._initDots() this._initSlider() if (this.autoPlay) { this._play() } }, 20) // 当窗口发生变化的时候 window.addEventListener('resize', () => { if (!this.slider) { return false } this._setSliderWidth(true) this.slider.refresh() }) }, activated () { if (this.autoPlay) { this._play() } }, deactivated () { clearTimeout(this.timer) }, beforeDestroy () { clearTimeout(this.timer) }, methods: { _setSliderWidth (isResize) { // 初始化宽度 // 获取每一张图片DOM this.children = this.$refs.sliderGroup.children let width = 0 let sliderWidth = this.$refs.slider.clientWidth // 每一张图片的宽度 for (let i = 0; i < this.children.length; i++) { let child = this.children[i] addClass(child, 'slider-item') // 添加class child.style.width = sliderWidth + 'px' // 设置宽度 width += sliderWidth // 求和算出总宽度 } if (this.loop && !isResize) { width += 2 * sliderWidth // 循环增长 } // 设置图片的直接容器的宽度 this.$refs.sliderGroup.style.width = width + 'px' }, _initSlider () { // 实例化一个 better-scroll对象 this.slider = new BScroll(this.$refs.slider, { scrollX: true, scrollY: false, momentum: false, // 快速滑动不开启滑动惯性 ,默认式true snap: { loop: this.loop, // 为了支持循环轮播 threshold: 0.3, // 表示可滚动到下一个的阈值 speed: 400 // 轮播图切换的动画时间 }, click: true }) // 一页图片滚动完毕以后触发 this.slider.on('scrollEnd', () => { let pageIndex = this.slider.getCurrentPage().pageX this.currentDotIndex = pageIndex if (this.autoPlay) { // 用手拖的时候清除定时器 clearTimeout(this.timer) this._play() } }) }, _initDots () { this.dots = new Array(this.children.length) }, _play () { // 自动播放 clearTimeout(this.timer) this.timer = setTimeout(() => { this.slider.next() }, this.interval) } } } </script> <style lang="stylus" scoped> @import "../../common/stylus/varstyle.styl" .slider min-height: 1px position relative .slider-group width: 100% position relative overflow hidden white-space nowrap .slider-item float left box-sizing border-box overflow: hidden text-align: center a display block width 100% overflow hidden text-align center img display block width 100% .dots position absolute left: 0px right: 0px bottom 8px text-align center font-size 0px .dot-item display inline-block margin 0px 4px width: 8px height: 8px border-radius 50% background $color-text-l &.active width: 12px border-radius 5px background $color-text-ll </style>
使用
// <template> <div class="recommend-wrapper"> // 【1】 这里的 v-if 必须写 <div v-if="recommemds.length" class="slider-wrapper" ref="sliderWrapper"> <slider> <div v-for="(item, index) in recommemds" :key="index" > <a :href="item.linkUrl"> <img :src="item.picUrl" alt=""> </a> </div> </slider> </div> </div> </template>
Scroll 区域滚动组件app
// scroll.vue <template> <!-- 滚动区域组件 --> <div ref="wrapper"> <slot></slot> </div> </template> <script type="text/ecmascript-6"> import BScroll from 'better-scroll' export default { props: { probeType: { type: Number, default: 1 }, click: { type: Boolean, default: true }, listenScroll: { type: Boolean, default: false }, data: { type: Array, default: null }, pullup: { type: Boolean, default: false }, beforeScroll: { type: Boolean, default: false }, refreshDelay: { type: Number, default: 20 } }, mounted () { setTimeout(() => { this._initScroll() }, 20) }, methods: { _initScroll () { // 初始化 if (!this.$refs.wrapper) { return } // 实例化一个对象 this.scroll = new BScroll(this.$refs.wrapper, { probeType: this.probeType, click: this.click }) // 若是监听 if (this.listenScroll) { let me = this // 监听scroll事件 this.scroll.on('scroll', (pos) => { // 派发一个scroll事件, 传出pos参数 me.$emit('scroll', pos) }) } if (this.pullup) { // 向下滚动监听时候滚动结束 this.scroll.on('scrollEnd', () => { if (this.scroll.y <= (this.scroll.maxScrollY + 50)) { // 派发事件 this.$emit('scrollToEnd') } }) } if (this.beforeScroll) { // 监听滚动以前 this.scroll.on('beforeScrollStart', () => { this.$emit('beforeScroll') }) } }, // 下面是代理了一些better-scroll的方法 disable () { // 也就是说,调用当前组件的方法就是在调用better-scroll的原生的方法 this.scroll && this.scroll.disable() }, enable () { this.scroll && this.scroll.enable() }, refresh () { this.scroll && this.scroll.refresh() }, scrollTo () { this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments) }, scrollToElement () { this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments) } }, watch: { // 监听数据 data () { // 自动刷新 setTimeout(() => { this.refresh() }, this.refreshDelay) } } } </script> <style scoped lang="stylus" rel="stylesheet/stylus"> </style>
使用
// 必须经过css规定大小哦,而且须要设置overflow: hidden; <scroll class="recommend-wrapper" :data="discList"> <div> // 数据内容 </div> </scroll>