vue利用better-scroll實(shí)現(xiàn)輪播圖與頁(yè)面滾動(dòng)詳解
前言
better-scroll 也很強(qiáng)大,不僅可以做普通的滾動(dòng)列表,還可以做輪播圖、picker 等等...所以本文主要給大家介紹了關(guān)于vue用better-scroll實(shí)現(xiàn)輪播圖與頁(yè)面滾動(dòng)的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。
1.安裝better-scroll
在根目錄中package.json的dependencies中添加:
"better-scroll": "^0.1.15"
然后 npm i
安裝。
2.封裝代碼
將better-scroll封裝成兩個(gè)基礎(chǔ)組件slider和scroll放于src/base文件夾中。
slider.vue 代碼
<template> <div class="slider" ref="slider"> <div class="slider-group" ref="sliderGroup"> <slot> </slot> </div> <div class="dots"> <span class="dot" :class="{active: currentPageIndex === index }" v-for="(item, index) in dots"></span> </div> </div> </template> <script> import {addClass} from '../common/js/dom' 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:4000 } }, mounted() { this._setSliderWidth() setTimeout(() => { // 在初始化slider前初始化dot this._initDots() this._initSlider() if (this.autoPlay) { this._play() } }, 20) // 監(jiān)聽窗口大小改變時(shí)間 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] // 設(shè)置每個(gè)子元素的樣式及高度 addClass(child, 'slider-item') child.style.width = sliderWidth + 'px' // 計(jì)算總寬度 width += sliderWidth } // 循環(huán)播放首尾各加一個(gè),因此總寬度還要加兩倍的寬度 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: true, snapLoop: this.loop, snapThreshold: 0.3, snapSpeed: 400, // click:true }) // 監(jiān)聽滾動(dòng)結(jié)束時(shí)間獲取pageX this.slider.on('scrollEnd', () => { let pageIndex = this.slider.getCurrentPage().pageX if (this.loop) { // 由于bscroll循環(huán)播放首尾各加一個(gè),因此索引-1 pageIndex -= 1 } this.currentPageIndex = pageIndex if (this.autoPlay) { this._play() } }) this.slider.on('beforeScrollStart', () => { if (this.autoPlay) { clearTimeout(this.timer) } }) }, _initDots() { // 長(zhǎng)度為n的空數(shù)組 this.dots = new Array(this.children.length) }, _play() { // currentPageIndex為不含首尾副本的索引,因此若有循環(huán)要+2 let pageIndex = this.currentPageIndex + 1 if (this.loop) { pageIndex += 1 } this.timer = setTimeout(() => { this.slider.goToPage(pageIndex, 0, 400) }, this.interval) } }, // 生命周期destroyed銷毀清除定時(shí)器,有利于內(nèi)存釋放 destroyed() { clearTimeout(this.timer) }, } </script> <style scoped> .slider{ min-height: 1px; position: relative; } .slider-group{ position: relative; overflow: hidden; white-space: nowrap; } .slider-item{ float: left; box-sizing: border-box; overflow: hidden; text-align: center; height: 150px; overflow: hidden; } .slider-item a{ display: block; width: 100%; overflow: hidden; text-decoration: none; } .slider-item img{ display: block; width: 100%; } .dots{ position: absolute; right: 0; left: 0; bottom: 12px; text-align: center; font-size: 0; } .dot{ display: inline-block; margin: 0 4px; width: 8px; height: 8px; border-radius: 50%; background: red; } .active{ width: 20px; border-radius: 5px; } </style>
該代碼引用common/js/dom.js中的addClass()方法為每個(gè)輪播圖添加一個(gè)slider-item類,dom.js代碼如下:
export function hasClass (el, className) { // 開始或空白字符+類名+空白字符或結(jié)束 let reg = new RegExp('(^|\\s)' + className + '(\\s|$)') // 測(cè)試元素是否有該類名,返回布爾值 return reg.test(el.className) } export function addClass (el, className) { if (hasClass(el, className)) { return } // 以空白符為切割位置切割生成新數(shù)組 let newClass = el.className.split(' ') // 數(shù)組中加入新類名 newClass.push(className) // 將數(shù)組元素放入一個(gè)字符串,以空白符間隔 el.className = newClass.join(' ') }
scroll.vue代碼
<template> <div ref="wrapper"> <slot></slot> </div> </template> <script> import BScroll from 'better-scroll' export default { props: { probeType: { type: Number, default: 1 }, click: { type: Boolean, default: true }, listenScroll: { type: Boolean, default: false }, object: { type: Object, default: null }, data: { type: Array, default: null }, string: { type: String, default: '' }, 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 // pos為位置參數(shù) this.scroll.on('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') }) } }, disable() { 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) }, string() { setTimeout(() => { this.refresh() }, this.refreshDelay) }, object() { setTimeout(() => { this.refresh() }, this.refreshDelay) } } } </script> <style> </style>
3.使用封裝組件
使用這兩個(gè)組件的頁(yè)面組件home.vue 代碼如下:
<template> <div> <scroll :data="su" class="scroll"> <div> <div class="slider-wrapper"> <slider> <div v-for='item in slider'> <a href=""> <img :src="item.url" alt=""> </a> </div> </slider> </div> <ul v-for='item in su'> <li>{{item}}</li> </ul> </div> </scroll> </div> </template> <script> import Slider from '../base/slider' import Scroll from '../base/scroll' export default { data () { return { slider: [ {url: 'http://upload-images.jianshu.io/upload_images/7932253-54c81df0beed405b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/q/50'}, {url: 'https://y.gtimg.cn/music/photo_new/T003R720x288M000004ERTpn1UBu2f.jpg?max_age=2592000&max_age=2592000'}, {url: 'https://y.gtimg.cn/music/photo_new/T003R720x288M00000077s7P0HaZpc.jpg?max_age=2592000&max_age=2592000'}, {url: 'https://y.gtimg.cn/music/photo_new/T003R720x288M000001QL1Si05yMPq.jpg?max_age=2592000&max_age=2592000'}, {url: 'https://y.gtimg.cn/music/photo_new/T003R720x288M000002ke7OC3ooZ5g.jpg?max_age=2592000&max_age=2592000'}, ], su:[1,2,3,4,5,6,7,8,9,10,1,2,3,4,2,3,5,8,7,4,] } }, methods: { }, components: { Slider, Scroll } } </script> <style> .slider-wrapper{ width: 100%; position: relative; overflow: hidden; } .scroll{ height: 500px; } </style>
注意點(diǎn):
slider組件的父元素必須給他一個(gè)100%的寬度且定義overflow:hidden,否則整個(gè)頁(yè)面會(huì)被撐開,整個(gè)頁(yè)面都能橫向滾動(dòng)
scroll組件在引用時(shí)必須給他一個(gè)固定高度。只有擁有固定高度才會(huì)發(fā)生滾動(dòng)。
效果圖如下:
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,本文還有許多不足,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
vue實(shí)現(xiàn)div可拖動(dòng)位置也可改變盒子大小的原理
這篇文章主要介紹了vue實(shí)現(xiàn)div可拖動(dòng)位置也可改變盒子大小,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09FastApi+Vue+LayUI實(shí)現(xiàn)前后端分離的示例代碼
本文主要介紹了FastApi+Vue+LayUI實(shí)現(xiàn)前后端分離的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11vue腳手架搭建/idea執(zhí)行vue項(xiàng)目全過(guò)程
新建目錄并運(yùn)行命令提示符,通過(guò)npm安裝Vue腳手架并查看版本號(hào),接著,使用vue create命令創(chuàng)建Vue項(xiàng)目,選擇所需配置后完成項(xiàng)目創(chuàng)建,創(chuàng)建成功可見Vue文件夾,使用IDEA打開項(xiàng)目,并啟動(dòng)項(xiàng)目,根據(jù)需求修改初始化界面2024-10-10vue實(shí)現(xiàn)側(cè)邊欄導(dǎo)航效果
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)側(cè)邊欄導(dǎo)航效果,右側(cè)顯示對(duì)應(yīng)內(nèi)容,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10解決Antd 里面的select 選擇框聯(lián)動(dòng)觸發(fā)的問題
這篇文章主要介紹了解決Antd 里面的select 選擇框聯(lián)動(dòng)觸發(fā)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10vue.draggable實(shí)現(xiàn)表格拖拽排序效果
這篇文章主要為大家詳細(xì)介紹了vue.draggable實(shí)現(xiàn)表格拖拽排序效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12