vue利用better-scroll实现轮播图与页面滚动详解
程序员文章站
2022-04-09 22:13:46
前言
better-scroll 也很强大,不仅可以做普通的滚动列表,还可以做轮播图、picker 等等...所以本文主要给大家介绍了关于vue用better-scrol...
前言
better-scroll 也很强大,不仅可以做普通的滚动列表,还可以做轮播图、picker 等等...所以本文主要给大家介绍了关于vue用better-scroll实现轮播图与页面滚动的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
1.安装better-scroll
在根目录中package.json的dependencies中添加:
"better-scroll": "^0.1.15"
然后 npm i
安装。
2.封装代码
将better-scroll封装成两个基础组件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) // 监听窗口大小改变时间 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: true, snaploop: this.loop, snapthreshold: 0.3, snapspeed: 400, // click:true }) // 监听滚动结束时间获取pagex this.slider.on('scrollend', () => { let pageindex = this.slider.getcurrentpage().pagex if (this.loop) { // 由于bscroll循环播放首尾各加一个,因此索引-1 pageindex -= 1 } this.currentpageindex = pageindex if (this.autoplay) { this._play() } }) this.slider.on('beforescrollstart', () => { if (this.autoplay) { cleartimeout(this.timer) } }) }, _initdots() { // 长度为n的空数组 this.dots = new array(this.children.length) }, _play() { // currentpageindex为不含首尾副本的索引,因此若有循环要+2 let pageindex = this.currentpageindex + 1 if (this.loop) { pageindex += 1 } this.timer = settimeout(() => { this.slider.gotopage(pageindex, 0, 400) }, this.interval) } }, // 生命周期destroyed销毁清除定时器,有利于内存释放 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()方法为每个轮播图添加一个slider-item类,dom.js代码如下:
export function hasclass (el, classname) { // 开始或空白字符+类名+空白字符或结束 let reg = new regexp('(^|\\s)' + classname + '(\\s|$)') // 测试元素是否有该类名,返回布尔值 return reg.test(el.classname) } export function addclass (el, classname) { if (hasclass(el, classname)) { return } // 以空白符为切割位置切割生成新数组 let newclass = el.classname.split(' ') // 数组中加入新类名 newclass.push(classname) // 将数组元素放入一个字符串,以空白符间隔 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为位置参数 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.使用封装组件
使用这两个组件的页面组件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>
注意点:
slider组件的父元素必须给他一个100%的宽度且定义overflow:hidden,否则整个页面会被撑开,整个页面都能横向滚动
scroll组件在引用时必须给他一个固定高度。只有拥有固定高度才会发生滚动。
效果图如下:
总结
以上就是这篇文章的全部内容了,本文还有许多不足,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。