美文网首页
基于better-scroll的picker组件实现

基于better-scroll的picker组件实现

作者: hsay | 来源:发表于2018-08-21 18:29 被阅读0次

这里再安利一下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还可以设计出很多复杂实用的组件,在后续会不断总结。。。。。

相关文章

网友评论

      本文标题:基于better-scroll的picker组件实现

      本文链接:https://www.haomeiwen.com/subject/bngjiftx.html