vue利用better-scroll实现轮播图与页面滚动详解


Posted in Javascript onOctober 20, 2017

前言

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组件在引用时必须给他一个固定高度。只有拥有固定高度才会发生滚动。

效果图如下:

vue利用better-scroll实现轮播图与页面滚动详解

总结

以上就是这篇文章的全部内容了,本文还有许多不足,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
Jan 16 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
May 08 Javascript
Javascript中arguments和arguments.callee的区别浅析
Apr 24 Javascript
jQuery中animate动画第二次点击事件没反应
May 07 Javascript
jquery实现手机号码选号的方法
Jul 31 Javascript
javascript中sort排序实例详解
Jul 24 Javascript
JavaScript每天必学之事件
Sep 18 Javascript
js遍历获取表格内数据的方法(必看)
Apr 06 Javascript
Vue渲染函数详解
Sep 15 Javascript
浅谈webpack下的AOP式无侵入注入
Nov 12 Javascript
Angular @HostBinding()和@HostListener()用法
Mar 05 Javascript
vue-better-scroll 的使用实例代码详解
Dec 03 Javascript
浅谈如何使用 webpack 优化资源
Oct 20 #Javascript
利用jQuery实现简单的拖曳效果实例代码
Oct 20 #jQuery
Js利用prototype自定义数组方法示例
Oct 20 #Javascript
js 中rewrap-ajax.js插件实例代码
Oct 20 #Javascript
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
Oct 20 #jQuery
JS 中使用Promise 实现红绿灯实例代码(demo)
Oct 20 #Javascript
用JavaScript做简易的购物车的代码示例
Oct 20 #Javascript
You might like
Oracle Faq(Oracle的版本)
2006/10/09 PHP
php读取数据库信息的几种方法
2008/05/24 PHP
使用php 获取时间今天明天昨天时间戳的详解
2013/06/20 PHP
php压缩文件夹最新版
2018/07/18 PHP
laravel框架中间件 except 和 only 的用法示例
2019/07/12 PHP
在html页面中包含共享页面的方法
2008/10/24 Javascript
JQuery 学习笔记 选择器之四
2009/07/23 Javascript
JS setCapture 区域外事件捕捉
2010/03/18 Javascript
Javascript中获取出错代码所在文件及行数的代码
2010/09/23 Javascript
javascript hashtable 修正版 下载
2010/12/30 Javascript
JavaScript中数组对象的那些自带方法介绍
2013/03/12 Javascript
jquery的ajax简单结构示例代码
2014/02/17 Javascript
JS获得浏览器版本和操作系统版本的例子
2014/05/13 Javascript
JS常用函数使用指南
2014/11/23 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
2015/03/10 Javascript
JS实现动态移动层及拖动浮层关闭的方法
2015/04/30 Javascript
JS访问SWF的函数用法实例
2015/07/01 Javascript
webpack+vue.js实现组件化详解
2016/10/12 Javascript
简单实现Vue的observer和watcher
2016/12/21 Javascript
vue.js中proxyTable 转发请求的实现方法
2018/09/20 Javascript
vue.js多页面开发环境搭建过程
2019/04/24 Javascript
如何阻止小程序遮罩层下方图层滚动
2019/09/05 Javascript
vue 全局环境切换问题
2019/10/27 Javascript
python连接远程ftp服务器并列出目录下文件的方法
2015/04/01 Python
python数据结构链表之单向链表(实例讲解)
2017/07/25 Python
Python matplotlib 画图窗口显示到gui或者控制台的实例
2018/05/24 Python
Sanic框架异常处理与中间件操作实例分析
2018/07/16 Python
selenium+python截图不成功的解决方法
2019/01/30 Python
TensorFlow基于MNIST数据集实现车牌识别(初步演示版)
2019/08/05 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
2019/08/21 Python
Python如何给函数库增加日志功能
2020/08/04 Python
夏洛特和乔治婴儿和儿童时装精品店:Charlotte and George
2018/06/06 全球购物
意大利在线购买隐形眼镜网站:VisionDirect.it
2019/03/18 全球购物
室内拓展活动方案
2014/02/13 职场文书
Python机器学习之基础概述
2021/05/19 Python
详解OpenCV曝光融合
2022/04/29 Python