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>