这里再安利一下better-scroll这个组件库,该库的源代码结构清晰,借鉴了vue源码的组织形式。better-scroll提供的各功能模块相互独立,易于阅读,对初学者非常友好,建议学习一下。
另外,我们可以借助better-scroll提供的功能封装出更为复杂的组件。这里要说的picker选择器组件就是基于better-scroll提供的特性实现的。
实现原理
这里主要借助better-scroll提供的wheel属性,利用该属性并配合相应的html结构以及css样式可以很简单的实现选择器组件。
<template>
<div class="wheel-wrapper" ref="wrapper">
<ul class="wheel-scroller">
<li class="wheel-item" v-for="index in data">{{index}}</li>
</ul>
</div>
</template>
<script>
const EVENT_CHANGE = 'change'
import BScroll from 'better-scroll'
export default {
props: {
data: {
type:Array,
default:function(){
return []
}
},
selectedIndex: {
type:Number,
default:0
}
},
data() {
return {
}
},
mounted() {
this.$nextTick(() => {
this._createWheel().enable()
})
},
methods: {
_createWheel() {
if (!this.wheels) {
const wheel = this.wheels = new BScroll(this.$refs.wrapper, {
wheel: {
selectedIndex: this.selectedIndex,
wheelWrapperClass: 'wheel-scroller',
wheelItemClass: 'wheel-item',
rotate: 0
},
observeDOM: false
})
wheel.on('scrollEnd', () => {
//滚动完成之后获取当前选取的索引值
this.$emit(EVENT_CHANGE,wheel.getSelectedIndex())
})
} else {
this.wheels.refresh()
}
return this.wheels
},
}
}
</script>
<style lang="scss" scoped>
.wheel-wrapper{
height: 100px;
overflow: hidden;
.wheel-scroller{
.wheel-item{
line-height:24px;
}
}
}
</style>
以上代码实现的效果图如下所示,第一行即为当前选中的选项,我们接下来要做的事情就是给选中的选项设计样式。
image
样式设计
<template>
<div class="relative">
<div class="mask-top absolute"></div>
<div class="mask-bottom absolute"></div>
<div class="wheel-wrapper" ref="wrapper">
<ul class="wheel-scroller">
<li class="wheel-item" v-for="index in data">{{index}}</li>
</ul>
</div>
</div>
</template>
<script>
const EVENT_CHANGE = 'change'
import BScroll from 'better-scroll'
export default {
props: {
data: {
type:Array,
default:function(){
return []
}
},
selectedIndex: {
type:Number,
default:0
}
},
data() {
return {
}
},
mounted() {
this.$nextTick(() => {
this._createWheel().enable()
})
},
methods: {
_createWheel() {
if (!this.wheels) {
const wheel = this.wheels = new BScroll(this.$refs.wrapper, {
wheel: {
selectedIndex: this.selectedIndex,
wheelWrapperClass: 'wheel-scroller',
wheelItemClass: 'wheel-item',
rotate: 0
},
observeDOM: false
})
wheel.on('scrollEnd', () => {
//滚动完成之后获取当前选取的索引值
this.$emit(EVENT_CHANGE,wheel.getSelectedIndex())
})
} else {
this.wheels.refresh()
}
return this.wheels
},
}
}
</script>
<style lang="scss" scoped>
.relative{
position: relative;
}
.absolute{
position: absolute;
}
.mask-top{
height:24px;
width:100%;
top:0;
border-bottom:1px solid red;
}
.mask-bottom{
height:24px;
width:100%;
top:24px;
border-bottom:1px solid red;
background:red;
z-index:-1;
}
.wheel-wrapper{
height: 100px;
overflow: hidden;
.wheel-scroller{
margin-top:24px;
.wheel-item{
line-height:24px;
}
}
}
</style>
以上代码实现的效果如下图所示,这里只给出了简单的原理以及演示,具体实现可根据自己的实际情况设计。
image
扩展
这里只演示了单列选择器组件,相对来说简单,我们在开发时常遇到的情形是多列的情况,再复杂就是各列存在联动关系。至于多列的设计,这里只需要创建多个better-scroll的实例即可。若存在多列联动的情形,需要根据滚动情况动态的输入相应了list,这里不再对详细设计做赘述。
总结
基于better-scroll还可以设计出很多复杂实用的组件,在后续会不断总结。。。。。