微信小程序 封装一个简单的弹出滚动选择器组件

在开发中,小程序提供了内置picker组件来供开发者使用。但picker组件无法自定义按钮颜色、选择器样式,造成在有UI要求时束手无策(我觉得滑动体验也不是很好orz)。这个时候就需要使用picker-view组件来自定义弹出滚动选择器了。
样式如下:

微信小程序 封装一个简单的弹出滚动选择器组件_第1张图片
弹出样式
首先确定组件的属性

加入pickerShow是因为项目中有需要触发选择器弹出的需求

  • picker-show 【Boolean】控制弹出隐藏
  • range 【二维Array】 二维数组,长度表示多少列,数组的每项表示每列的数据
  • title 【Array】 选择器每列标题
  • value 【Array】 value 每一项的值表示选择了 range 对应项中的第几个(下标从 0 开始)
  • is-shadow 【Boolean】 是否需要显示遮罩层
  • bindchange 【EventHandle】 value 改变时触发 change 事件 event.detail = value
  • bindfinish 【EventHandle】 完成时触发 event.detail = value
  • bindcancel 【EventHandle】 取消时触发

需要有几列,就在 range 中传入几项

// 使用时,可插入选择器标题

    从底部弹起的滚动选择器

// 页面逻辑
Page({
    data: {
        val: [// 数据列表
            ['大天狗', '玉藻前', '妖刀姬', '茨木童子'],
            ['追月神', '姑获鸟', '犬神', '黑童子']
        ]
    },
    finishHandler(e){
        console.log(e.detail)// 选择的结果 如:["妖刀姬", "犬神"]
    }
})
// .json
{
    "usingComponents": {
        "my-picker": "/components/my-picker/my-picker"
    }
}

如有需要定制样式,就可以直接在components组件中直接修改就可以啦~

下面是组件的完整代码
// my-picker.js
Component({
    /**
     * 组件的属性列表
     */
    properties: {
        pickerShow:{
            type: Boolean, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
            value: false, // 属性初始值(可选),如果未指定则会根据类型选择一个
            observer (newVal, oldVal, changedPath) {
                // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange'
                // 通常 newVal 就是新设置的数据, oldVal 是旧数据
            }
        },
        isShadow: {
            type: Boolean,
            value: true,
            observer(newVal, oldVal, changedPath) {}
        },
        range:{
            type: Array,
            value: []
        }, 
        title:{
            type: Array,
            value: []
        },
        value: {// picker-view 内的 picker-view-column 当前选择的是第几项
            type: Array,
            value: [2, 2]
        }
    },
    /**
     * 组件的方法列表
     */
    methods: {
        pickerHandler() {// 控制弹出层显示隐藏
            this.setData({ pickerShow: !this.data.pickerShow })
        },
        bindChange(e) {// value 改变时触发 change 事件
            const val = e.detail.value
            this.setData({ value: val })
            let arr = []
            this.data.range.forEach((v, i) => {
                arr.push(v[this.data.value[i]])
            })
            this.triggerEvent('change', arr, {})
        },
        pickerFinish() {// 滚动选择器 - 完成
            let arr = []
            this.data.range.forEach((v, i) => {
                arr.push(v[this.data.value[i]])
            })
            this.pickerHandler()
            this.triggerEvent('finish', arr, {})
        },
        pickerCancel() {// 滚动选择器 - 取消
            this.pickerHandler()
            this.triggerEvent('cancel', arr, {})
        }
    }
})
// my-picker.wxml

    

    
        
            取消
            
            完成
        
        
            {{item}}
        
        
            
                {{a}}
            
        
    

     


/*my-picker.wxss*/
picker-view-column{font-size: 14px;text-align: center;}
.com-picker-view{position: fixed;bottom: 0;width: 100%;z-index: 3;background: #fff;}

/* 弹出标题 */
.com-picker-title{display: flex;padding: 10px 15px;font-size: 14px;border-bottom: #f8f8f8 1px solid;}
.com-picker-cancel{color: #999;}
.com-picker-finish{color: palevioletred;}
.com-picker-result{flex: 1;text-align: center;color: #999;}
.com-title{display: flex;border-bottom: #f8f8f8 1px solid;}
.com-title > view{flex:1;text-align: center;line-height: 40px;font-size: 14px;}

/* 弹出效果 */
.com-picker-view.false{transform:translateY(100%);-webkit-transform:translateY(100%);transition: all .3s cubic-bezier(0,.54,.51,.99);-webikit-transition: all .3s cubic-bezier(0,.54,.51,.99);opacity: 1;}
.com-picker-view.true{transform:translateY(0%);-webkit-transform:translateY(0%);transition: all .3s cubic-bezier(0,.54,.51,.99);-webikit-transition: all .3s cubic-bezier(0,.54,.51,.99);opacity: 1;}

/* 遮罩 */
.com-picker-shadow{width: 100%;height: 100%;position: fixed;top: 0;left: 0; background-color:rgba(0,0,0,0.3);z-index: 2}
.com-picker-shadow.true{ -webkit-transition: opacity 0.35s, visibility 0.35s;transition: opacity 0.35s, visibility 0.35s;visibility: visible;opacity: 1;}
.com-picker-shadow.false{visibility: hidden;opacity: 0;  -webkit-transition: opacity 0.35s, visibility 0.35s;transition: opacity 0.35s, visibility 0.35s;}
// my-picker.json
{
  "component": true,
  "usingComponents": {}
}

你可能感兴趣的:(微信小程序 封装一个简单的弹出滚动选择器组件)