使用better-scroll实现slider组件
2017-10-24 14:50
344 查看
经过很长的一段时间折腾和看视频、文档,终于热乎乎的slider的组件编写,已经基本完成了,以下就是整个思路:
首先呢,需要用到大名鼎鼎的移动端滑动库better-scroll了
新建一个名为slider.vue的文件,基本结构如下:
上述代码中的slot插槽的说明:在外部引用slide时,slider包裹的DOM会被插入进这个slot插槽部分 ,
eg:在相关页面需要引用slide组件的地方写下如下代码:
在slider.vue中加入script部分,然后引用我们需要用到better-scroll库。ps:一定要先安装才可以使用它哦,npm install better-scorll –save
上述代码中,因为我们是吧slider这个组件抽离出来做成木偶组件,并不直接进行数据之间的交互,所以我们需要先在props中定义可以在外部控制的属性(loop 是否循环播放,autoPlay自动播放,interval 自动轮播间隔)
1、在mounted的计算属性中进行初始化
2、在methods中进行私有函数的定义,自定义的函数方法都是在该计算属性中进行的
2-1、关于addClass()方法的说明,因为该方法是直接进行DOM操作,所以该方法是单独放在一个js文件中,代码如下:
然后在
这个时候我们的slider的宽度已经计算完成,现在需要初始化slider,这里需要使用better-scroll暴露出来的方法与事件来操作slider,在methods计算属性中新建一个方法叫_initSlider(),代码如下:
上述代码里面需要特别注意的是better-scroll的版本的不同,初始化scroll的时有参数不同,具体请参照官方文档
全部代码如下:
如何使用slider
在该使用的地方直接 import slider from ‘你的slider文件的路径’
代码如下:
好了,关于slider的封装与使用就到此结束了….
首先呢,需要用到大名鼎鼎的移动端滑动库better-scroll了
新建一个名为slider.vue的文件,基本结构如下:
<template> <div class="slider" ref="slider"> <div class="slider-group" ref="sliderGroup"> <slot></slot> </div> <div class="dots"> <span class="dot"></span> </div> </div> </template>
上述代码中的slot插槽的说明:在外部引用slide时,slider包裹的DOM会被插入进这个slot插槽部分 ,
eg:在相关页面需要引用slide组件的地方写下如下代码:
<slide> <div>这里div的部分会被放进slot里面</div> </slide>
在slider.vue中加入script部分,然后引用我们需要用到better-scroll库。ps:一定要先安装才可以使用它哦,npm install better-scorll –save
import BScroll from 'better-scroll' export default { props: { // 这里定义可在外部控制的属性 loop: { // 是否是循环轮播 type: Boolean, default: true }, autoPlay: { // 自动播放 type: Boolean, default: true }, interval: { // 自动轮播间隔 type: Number, default: 4000 } }, mounted() { // 初始化 setTimeout(() => { this._setSliderWideth() //初始化slider的宽度 }, 20) }, methods: { _setSliderWideth(isResize) { // 获取整个列表有多少个元素 this.children = this.$refs.slideGroup.children let width = 0 // 总的宽度 // slider 父元素的宽度 let slideWidth = this.$refs.slider.clientWidth for (let i = 0; i < this.children.length; i++) { let child = this.children[i] // 获取每个子元素 addClass(child, 'slider-item') // 添加名为slider-item的类名 child.style.width = slideWidth + 'px' console.log(child.style.width) width += slideWidth } if (this.loop && !isResize) { // 如果slide是需要循环的话,slide会在左右两侧copy两个子元素从而保证循环切换 width += 2 * slideWidth console.log(width) } this.$refs.slideGroup.style.width = width + 'px' } } }
上述代码中,因为我们是吧slider这个组件抽离出来做成木偶组件,并不直接进行数据之间的交互,所以我们需要先在props中定义可以在外部控制的属性(loop 是否循环播放,autoPlay自动播放,interval 自动轮播间隔)
1、在mounted的计算属性中进行初始化
2、在methods中进行私有函数的定义,自定义的函数方法都是在该计算属性中进行的
2-1、关于addClass()方法的说明,因为该方法是直接进行DOM操作,所以该方法是单独放在一个js文件中,代码如下:
export function addClass(el, className) { if (hasClass(el, className)) { // 该DOM对象有这个类名时,什么都不做 return } let newClass = el.className.split('') // 获取类名 newClass.push(className) el.className = newClass.join('') } export function hasClass(el, className) { // 是否存在该类名 let reg = new RegExp('(^|\\s)' + className + '(\\s|$)') // (\\s| 空白字符) return reg.test(el.className) // el.className 获取class }
然后在
import BScroll from 'better-scroll'下面引入import { addClass } from ‘你的那个dom.js文件路径’
这个时候我们的slider的宽度已经计算完成,现在需要初始化slider,这里需要使用better-scroll暴露出来的方法与事件来操作slider,在methods计算属性中新建一个方法叫_initSlider(),代码如下:
_initSlider() { // 初始化slide this.slider = new BScroll(this.$refs.slider, { scrollX: true, // 横向滚动 scrollY: false, // 不允许纵向滚动 momentum: false, // 是否开启动量动画,关闭可以提升效率 // ***配置:在better-scroll版本0.1.15以前可用以下参数进行slide配置,但1.0.0版本以上需按照未注释前的方法使用***/ // snap: true, // slide组件 // snapLoop: this.loop, // 循环 // snapThreshold: 0.3, // // snapSpeed: 400 snap: { loop: this.loop, threshold: 0.3, speed: 400 } }) this.slider.on('scrollEnd', () => { // 参考文档 https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/api-specific.html#getcurrentpage let pageIndex = this.slider.getCurrentPage().pageX if (this.loop) { pageIndex -= 1 // 因为设置自动播放之后,会自动在左右两侧copy两个子元素,所以在设置pageIndex时应减一 } this.currentPageIndex = pageIndex if (this.autoPlay) { this._play() } }) // 参考文档 https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/events.html#beforescrollstart this.slider.on('beforeScrollStart', () => { if (this.autoPlay) { clearTimeout(this.timer) } }) },
上述代码里面需要特别注意的是better-scroll的版本的不同,初始化scroll的时有参数不同,具体请参照官方文档
全部代码如下:
<template>
<div class="slider" ref="slider">
<div class="slider-group" ref="slideGroup">
<slot></slot>
<!--slot插槽说明
//外部引用slide时,slider包裹的DOM会被插入进这个slot插槽部分
eg:
在相关页面需要引用slide组件的地方写下如下代码:
<slide>
<div>...这里写循环的内容与结构....</div>
</slide>
-->
</div>
<div class="dots">
<span class="dot" v-for="(item, index) in dots" :class="{active: currentPageIndex === index}"></span>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
import { addClass } from '../../assets/js/dom'
// slide 基于better-scroll实现,监听了它的几个事件{snap,snapLoop,snapThreshold,snapSpeed } **注:better-scroll因为版本原因,以上几个事件会有出入,请参考官方文档,下面在实例化better-scroll时有做详细说明**
export default {
data() {
return {
dots: [], // 定义一个名为dots的数组,小圆点数组
currentPageIndex: 0 // 当前的页码
}
},
props: { // 这里定义可在外部控制的属性
loop: { // 是否是循环轮播
type: Boolean,
default: true
},
autoPlay: { // 自动播放
type: Boolean,
default: true
},
interval: { // 自动轮播间隔
type: Number,
default: 4000
}
},
mounted() { // 初始化 better-scroll时机(*一般初始化better-scroll不成功,会引起*)
setTimeout(() => {
this._setSliderWideth()
this._initDots()
this._initSlider()
if (this.autoPlay) {
this._play()
}
}, 20)// 保证DOM被渲染,做了20ms的延时(*为何值为20??* 因为浏览器刷新时间一般为17ms一次)
//
window.addEventListener('resize', () => {
if (!this.slider) {
return
}
this._setSliderWideth(true)
this.slider.refresh()
})
},
methods: {
// 因为是横向滚动,需计算slide 的宽度并且赋值
_setSliderWideth(isResize) {
this.children = this.$refs.slideGroup.children // 获取整个列表有多少个元素
console.log(this.children.length)
let width = 0 // 总的宽度
let slideWidth = this.$refs.slider.clientWidth // slide 父元素的宽度
for (let i = 0; i < this.children.length; i++) {
let child = this.children[i] // 获取每个子元素
addClass(child, 'slider-item') // 添加名为slider-item的类名
child.style.width = slideWidth + 'px'
console.log(child.style.width)
width += slideWidth
}
if (this.loop && !isResize) { // 如果slide是需要循环的话,slide会在左右两侧copy两个子元素从而保证循环切换
width += 2 * slideWidth
}
this.$refs.slideGroup.style.width = width + 'px'
},
_initDots() {
this.dots = new Array(this.children.length)
},
_initSlider() { // 初始化slide this.slider = new BScroll(this.$refs.slider, { scrollX: true, // 横向滚动 scrollY: false, // 不允许纵向滚动 momentum: false, // 是否开启动量动画,关闭可以提升效率 // ***配置:在better-scroll版本0.1.15以前可用以下参数进行slide配置,但1.0.0版本以上需按照未注释前的方法使用***/ // snap: true, // slide组件 // snapLoop: this.loop, // 循环 // snapThreshold: 0.3, // // snapSpeed: 400 snap: { loop: this.loop, threshold: 0.3, speed: 400 } }) this.slider.on('scrollEnd', () => { // 参考文档 https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/api-specific.html#getcurrentpage let pageIndex = this.slider.getCurrentPage().pageX if (this.loop) { pageIndex -= 1 // 因为设置自动播放之后,会自动在左右两侧copy两个子元素,所以在设置pageIndex时应减一 } this.currentPageIndex = pageIndex if (this.autoPlay) { this._play() } }) // 参考文档 https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/events.html#beforescrollstart this.slider.on('beforeScrollStart', () => { if (this.autoPlay) { clearTimeout(this.timer) } }) },
_play() {
let pageIndex = this.currentPageIndex + 1
if (this.loop) {
pageIndex += 1
}
this.timer = setTimeout(() => {
this.slider.goToPage(pageIndex, 0, 400)
}, this.interval)
}
},
destroyet() {
clearTimeout(this.timer)
}
}
</script>
<style rel="stylesheet" lang="stylus">
@import "../../assets/stylus/variable"
.slider
min-height: 1px
.slider-group
position: relative
overflow: hidden
white-space: nowrap
.slider-item
float: left
box-sizing: border-box
overflow: hidden
text-align: center
a
display: block
width: 100%
overflow: hidden
text-decoration: none
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: $color-text-l
&.active
width: 20px
border-radius: 5px
background: $color-text-ll
</style>
</style>
如何使用slider
在该使用的地方直接 import slider from ‘你的slider文件的路径’
代码如下:
<template> <div v-if="recommends.length" class="slider-wrapper"> <slider > <div v-for="item in recommends"> <a> <img class="needsclick" :src="item.picUrl" alt=""> </a> </div> </slider> </div> </template> <script> import Slider from '你的slider文件的路径' export default{ data() { return { recommends: [ {'picurl':'http://y.gtimg.cn/music/photo_new/T003R720x288M000002QA9kw0QwiVQ.jpg'}, {'picurl':'http://y.gtimg.cn/music/photo_new/T003R720x288M000002QA9kw0QwiVQ.jpg'}, {'picurl':'http://y.gtimg.cn/music/photo_new/T003R720x288M000002QA9kw0QwiVQ.jpg'}, {'picurl':'http://y.gtimg.cn/music/photo_new/T003R720x288M000002QA9kw0QwiVQ.jpg'} ] } }, components: { Slider } } </script>
好了,关于slider的封装与使用就到此结束了….
相关文章推荐
- cocostudio之类似于服务器选择功能的实现ScrollView+Slider组件结合使用
- better-scroll上拉加载 和下拉刷新 的使用(基于vue写成组件的形式)
- vue使用Better-Scroll实现纵向滚动
- 微信小程序例子——如何使用scroll-view组件实现视图垂直滚动
- ionic实现上拉加载更多(组件 ion-infinite-scroll使用,以及多次加载的问题)
- Vue组件Better-Scroll使用
- 基于vue2.0以及better-scroll实现scroll滑动组件及所实现组件的应用例子
- 使用FileUpload组件实现文件上传
- 使用VS2005的 ClickOnce 技术实现按需下载组件(ZT)
- windows 2003 COM+组件使用Delphi实现
- 使用VS2005的 ClickOnce 技术实现按需下载组件
- 使用VS2005的 ClickOnce 技术实现按需下载组件
- 使用VS2005的 ClickOnce 技术实现按需下载组件
- FleaPHP 开发指南 - 8. 如何使用 RBAC 组件实现访问控制
- 使用FileUpload组件实现文件上传
- FleaPHP 开发指南 - 8. 如何使用 RBAC 组件实现访问控制
- FleaPHP 开发指南 - 8. 如何使用 RBAC 组件实现访问控制
- windows 2003 COM+组件使用Delphi实现
- 使用#default#userdata组件实现的可记忆内容的编辑器
- 如何使用JMAIL组件实现邮件的发送与接收