Vue中使用better-scroll实现轮播图组件


Posted in Javascript onMarch 07, 2020

better-scroll 是什么

better-scroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。它的核心是借鉴的 iscroll 的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化。

better-scroll 是基于原生 JS 实现的,不依赖任何框架。它编译后的代码大小是 63kb,压缩后是 35kb,gzip 后仅有 9kb,是一款非常轻量的 JS lib。

今天我们利用它实现一个横向滚动——轮播图组件。演示如下:

首先来整理一下需求:

  • 能够根据异步请求到的图片数据进行轮播图展示。
  • 能够控制它是否自动播放,是否循环播放,自动播放间隔。
  • 能够提示当前播放页。

Vue中使用better-scroll实现轮播图组件 

Mock数据

由于是一个demo,从网上找了几张图片写成json格式,数据用于模拟接口数据。这里用到了mock.js。Axios。安装方法如下:

npm install mockjs

npm install --save axios vue-axios

axios使用方法不多赘述,简述一下mock数据。在mock文件夹下新建json文件夹放置json数据文件。新建index.js导出接口。就可以使用axios请求接口了。

[
	"https://img3.mukewang.com/szimg/5df8852609e0762d12000676-360-202.png",
 "https://img1.mukewang.com/szimg/5d9c62fb0907ccf012000676-360-202.png",
 "https://img3.mukewang.com/5aeecb1d0001e5ea06000338-360-202.jpg"
]
const Mock = require('mockjs')

Mock.mock('/slider', 'get', require('./json/slider.json'))

基础组件:slider.vue

将轮播图组件抽象出来,接收isLoop、isAutoPlay、interval属性控制轮播图。从mounted方法调用顺序可以知道思路是

  • setSliderWidth()中先获取再设置显示层和图片包裹层高度。
  • initDots()根据图片包裹层子元素的个数设置数组放置圆点。
  • initSlider()初始化better-scroll。
  • autoPlay()设置自动播放。
<template>
 <div class="slider-apply" ref="slider"> <!-- 显示层 -->
 <div class="slider-group" ref="group"> <!-- 所有图片包裹层 -->
 <slot></slot>   <!-- 插槽显示图片内容 -->
 </div>
 <div class="dots">   <!-- 提示圆点 -->
 <div class="dot" v-for="(item, index) in dots" :key="index" :class="currentIndex===index?'active':''"></div>
 </div>
 </div>
</template>

<script type='text/ecmascript-6'>
import BScroll from 'better-scroll'
export default {
 data () {
 return {
 dots: [],
 currentIndex: 0 /* 当前页下标 */
 }
 },
 props: {
 isLoop: { /* 循环播放 */
 type: Boolean,
 default: true
 },
 isAutoPlay: { /* 自动播放 */
 type: Boolean,
 default: true
 },
 interval: { /* 播放间隔 */
 type: Number,
 default: 2000
 }
 },
 mounted () { /* mounted阶段dom渲染完,20ms确保刷新 */
 setTimeout(() => {
 this.setSliderWidth()
 this.initDots()
 this.initSlider()
 if (this.isAutoPlay) {
 this.autoPlay()
 }
 }, 20)
 },
 methods: {
 setSliderWidth () { /* 获取显示层宽度,计算内容层宽度 */
 const clientWidth = this.$refs.slider.clientWidth
 let sliderWidth = 0
 this.children = this.$refs.group.children
 for (let i = 0; i < this.children.length; i++) {
 this.children[i].style.width = clientWidth + 'px'
 sliderWidth += clientWidth
 }
 if (this.isLoop) { /* 循环播放需要增加前后两个宽度 */
 sliderWidth += clientWidth * 2
 }
 this.$refs.group.style.width = sliderWidth + 'px' /* 设置内容层宽度 */
 },
 initDots () {
 this.dots = new Array(this.children.length)
 },
 initSlider () {
 this.slider = new BScroll(this.$refs.slider, {
 scrollX: true, /* 横向滚动 */
 scrollY: false,
 snap: { /* 循环滚动设置 */
  loop: this.isLoop,
  threshold: 0.3,
  speed: 400
 }
 })
 this.slider.on('scrollEnd', () => {
 const pageIndex = this.slider.getCurrentPage().pageX /* 获取当前轮播页,用于圆点提示 */
 this.currentIndex = pageIndex
 if (this.isAutoPlay) {
  clearTimeout(this.timer) /* 重新设置自动播放,否则无法自动播放 */
  this.autoPlay()
 }
 })
 },
 autoPlay () {
 this.timer = setTimeout(() => {
 this.slider.next(400)
 }, this.interval)
 }
 },
 destroyed () { /* 确保清除定时器 */
 clearTimeout(this.timer)
 }
}
</script>

<style lang="stylus" scoped>
.slider-apply
 position relative  // 让dots找准位置
 height 200px
 width 100%   // slider-apply会依据父元素宽度显示宽度
 overflow hidden  // 超出元素隐藏
 border-radius 5px
 .dots
 position absolute
 bottom 10px
 left 50%
 transform translate(-50%, 0) // 居中
 display flex
 .dot
 margin 0 10px
 height 7px
 width 7px
 background #fff
 border-radius 50%
 .active   // 当前dot样式
 width 15px
 border-radius 50% 5px
</style>

应用组件:slider-apply.vue

可以根据alider-apply.vue中的使用方法应用在自己的项目中。

<template>
 <div class="slider-wrapper">
 <Slider v-if="showSlider"> <!-- showSlider使得数据请求完成后再显示,否则better-scroll可能会计算错误 -->
 <div v-for="item in imageList" :key="item" class="slider-item">
 <img :src="item" class="img">
 </div>
 </Slider>
 </div>
</template>

<script type='text/ecmascript-6'>
import Slider from 'base/slider'
export default {
 data () {
 return {
 imageList: [], // 图片列表
 showSlider: false // 显示slider标志位
 }
 },
 created () {
 this.getImages() // 获取数据
 },
 methods: {
 getImages () {
 this.axios.get('/slider').then((res) => {
 this.imageList = res.data
 this.showSlider = true
 }).catch((err) => {
 console.log(err)
 })
 }
 },
 components: {
 Slider
 }
}
</script>

<style lang="stylus" scoped>

.slider-wrapper
 margin 0 auto
 height 200px // 固定轮播图显示高度
 width 500px // 固定轮播图显示宽度,可设置百分比
 background #000
 border-radius 5px
 .slider-item
 float left // 元素向左浮动
 width 100%
 overflow hidden
 text-align center
 .img
 height 200px
 width 100%

</style>

如果以上步骤没有看明白的话,可以在我的github中找到源码https://github.com/Gesj-yean/vue-demo-collection。

总结

到此这篇关于Vue中使用better-scroll实现轮播图组件的文章就介绍到这了,更多相关vue 轮播图组件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript 写的一个简单的timer
Jul 30 Javascript
jquery+ajax每秒向后台发送请求数据然后返回页面的代码
Jan 17 Javascript
window.open不被拦截的实现代码
Aug 22 Javascript
JQUERY 实现窗口滚动搜索框停靠效果(类似滚动停靠)
Mar 27 Javascript
javascript学习笔记(六)数据类型和JSON格式
Oct 08 Javascript
改变checkbox默认选中状态及取值的实现代码
May 26 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
Jan 04 Javascript
详解基于Vue2.0实现的移动端弹窗(Alert, Confirm, Toast)组件
Aug 02 Javascript
Vue项目安装插件并保存
Jan 28 Javascript
如何用webpack4.0撸单页/多页脚手架 (jquery, react, vue, typescript)
Jun 18 jQuery
微信小程序全局变量GLOBALDATA的定义和调用过程解析
Sep 23 Javascript
Vue快速实现通用表单验证的方法
Feb 24 Javascript
JavaScript实现栈结构Stack过程详解
Mar 07 #Javascript
node创建Vue项目步骤详解
Mar 06 #Javascript
小程序跳转到的H5页面再跳转回跳小程序的方法
Mar 06 #Javascript
小程序跳转H5页面的方法步骤
Mar 06 #Javascript
js实现点赞按钮功能的实例代码
Mar 06 #Javascript
微信小程序去除左上角返回键的实现方法
Mar 06 #Javascript
vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】
Mar 06 #Javascript
You might like
Smarty变量调节器失效的解决办法
2014/08/20 PHP
PHP实现的sqlite数据库连接类
2014/12/12 PHP
PHP实现简单爬虫的方法
2015/07/29 PHP
thinkPHP框架RBAC实现原理分析
2019/02/01 PHP
JavaScript 中的事件教程
2007/04/05 Javascript
基于jquery循环map功能的代码
2011/02/26 Javascript
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
2012/01/15 Javascript
jQuery 事件的命名空间简单了解
2013/11/22 Javascript
Jquery插件分享之气泡形提示控件grumble.js
2014/05/20 Javascript
JavaScript中的console.assert()函数介绍
2014/12/29 Javascript
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
JavaScript获取IP获取的是IPV6 如何校验
2016/06/12 Javascript
AngularJS+Bootstrap实现多文件上传与管理
2016/11/08 Javascript
微信小程序 扎金花简单实例
2017/02/21 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
2018/05/15 Javascript
vue watch普通监听和深度监听实例详解(数组和对象)
2018/08/16 Javascript
Vue-component全局注册实例
2018/09/06 Javascript
layui table去掉右侧滑动条的实现方法
2019/09/05 Javascript
刷新页面后让控制台的js代码继续执行
2019/09/20 Javascript
jQuery实现王者荣耀手风琴效果
2020/01/17 jQuery
[03:03]DOTA2校园争霸赛 济南城市决赛欢乐发奖活动
2013/10/21 DOTA
python图像处理之反色实现方法
2015/05/30 Python
python中文件变化监控示例(watchdog)
2017/10/16 Python
每天迁移MySQL历史数据到历史库Python脚本
2018/04/13 Python
python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结
2019/07/04 Python
python orm 框架中sqlalchemy用法实例详解
2020/02/02 Python
python 制作简单的音乐播放器
2020/11/25 Python
HTML5页面嵌入小程序没有返回按钮及返回页面空白的问题
2020/05/28 HTML / CSS
Vero Moda西班牙官方购物网站:丹麦BESTSELLER旗下知名女装品牌
2018/04/27 全球购物
POP文化和音乐灵感的时尚:Hot Topic
2019/06/19 全球购物
Kiehl’s科颜氏西班牙官方网站:源自美国的植物护肤品牌
2020/02/22 全球购物
事业单位接收函
2014/01/10 职场文书
两年的个人工作自我评价
2014/01/10 职场文书
个人充满哲理的自我评价
2014/02/20 职场文书
三八节主持词
2014/03/17 职场文书
在Docker容器中部署SQL Server
2022/04/11 Servers