详解vue之better-scroll实现轮播图和页面滚动
来源:互联网 发布:无线摄像头破解软件 编辑:程序博客网 时间:2024/06/06 02:37
(该方法只针对移动端使用效果较好,PC端不推荐,使用的版本是better-scroll@0.1.15,其他版本会出错)
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组件在引用时必须给他一个固定高度。只有拥有固定高度才会发生滚动。
效果图如下:
阅读全文
0 2
- 详解vue之better-scroll实现轮播图和页面滚动
- vue使用Better-Scroll实现纵向滚动
- vue之滚动轴插件better-scroll
- Vue之better-scroll
- vue实现横向滚动效果(better-scroll)
- vue三级界面使用better-scroll滚动
- vue 中使用better-scroll插件时无法滚动问题
- vue使用 better-scroll的参数和方法
- 当 better-scroll 遇见 Vue
- 当 better-scroll 遇见 Vue
- 当better-scroll遇见Vue
- 页面局部滚动(scroll)实现方式
- Vue中better-scroll插件的使用
- better-scroll VS vue 纯干货
- better-scroll在vue项目中的使用
- vue中实现移动端的scroll滚动
- better-scroll滚动不了的问题
- better-scroll无法滚动的问题
- php
- web安全
- 自适应simpson 积分
- hdu 1166 敌兵布阵
- Win10中Docker下修改mysql配置(主要修改utf-8字符集)
- 详解vue之better-scroll实现轮播图和页面滚动
- [SDOI2009]学校食堂Dining(洛谷2157)
- NavigationView控件
- 【区块链】EVM反编译软件Porosity的使用-mac
- matlib与excel交互
- POJ_3468 A Simple Problem with Integers(线段树区间修改+附线段树模板)
- electron打包
- poj 3013 Big Christmas Tree 最短路 (转换思维,看点不看边)
- maven用变量的方法统一管理jar包版本