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 相关文章推荐
关于文本限制字数的js代码
Apr 02 Javascript
javascript 显示当前系统时间代码
Dec 28 Javascript
表单JS弹出填写提示效果代码
Apr 16 Javascript
利用jQuery操作对象数组的实现代码
Apr 27 Javascript
jQuery源码分析-04 选择器-Sizzle-工作原理分析
Nov 14 Javascript
JavaScript创建对象的写法
Aug 29 Javascript
js字符串完全替换函数分享
Dec 03 Javascript
vue-cli的webpack模板项目配置文件分析
Apr 01 Javascript
jQuery实现简单复制json对象和json对象集合操作示例
Jul 09 jQuery
在axios中使用params传参的时候传入数组的方法
Sep 25 Javascript
对angularJs中2种自定义服务的实例讲解
Sep 30 Javascript
js实现缓动动画
Nov 25 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
PHP数组无限分级数据的层级化处理代码
2012/12/29 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
thinkphp3.x中变量的获取和过滤方法详解
2016/05/20 PHP
Zend Framework实现自定义过滤器的方法
2016/12/09 PHP
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
用模版生成HTML的的框架jquery.tmpl使用详解
2015/01/07 Javascript
JS实现霓虹灯文字效果的方法
2015/08/06 Javascript
网页从弹窗页面单选框传值至父页面代码分享
2015/09/29 Javascript
js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
2015/11/09 Javascript
JavaScript与HTML的结合方法详解
2015/11/23 Javascript
jQuery验证插件validate使用详解
2016/05/11 Javascript
JavaScript+Java实现HTML页面转为PDF文件保存的方法
2016/05/30 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
vuejs2.0实现一个简单的分页示例
2017/02/22 Javascript
Vue.js鼠标悬浮更换图片功能
2017/05/17 Javascript
angular框架实现全选与单选chekbox的自定义
2017/07/06 Javascript
简单谈谈vue的过渡动画(推荐)
2017/10/11 Javascript
Angular 利用路由跳转到指定页面的指定位置方法
2018/08/31 Javascript
VScode格式化ESlint方法(最全最好用方法)
2019/09/10 Javascript
[02:11]完美世界DOTA2联赛10月28日赛事精彩集锦:来吧展示实力强劲
2020/10/29 DOTA
Ubuntu下使用Python实现游戏制作中的切分图片功能
2018/03/30 Python
Diango + uwsgi + nginx项目部署的全过程(可外网访问)
2018/04/22 Python
Python redis操作实例分析【连接、管道、发布和订阅等】
2019/05/16 Python
Python 合并多个TXT文件并统计词频的实现
2019/08/23 Python
Django 创建后台,配置sqlite3教程
2019/11/18 Python
Python json转字典字符方法实例解析
2020/04/13 Python
基于pandas向csv添加新的行和列
2020/05/25 Python
阿迪达斯德国官方网站:adidas德国
2017/07/12 全球购物
加拿大最大的体育用品、鞋类和服装零售商:Sport Chek
2018/11/29 全球购物
LightInTheBox法国站:中国跨境电商
2020/03/05 全球购物
解释下面关于J2EE的名词
2013/11/15 面试题
电气自动化个人求职信范文
2014/02/03 职场文书
机关作风整顿个人整改措施思想汇报
2014/09/29 职场文书
医者仁心观后感
2015/06/17 职场文书
教学工作总结范文5篇
2019/08/19 职场文书
解读Vue组件注册方式
2021/05/15 Vue.js