小程序miniprogram-picker组件,自动处理多级联动,支持npm

miniprogram-picker已经在Github开源,并发布了npm包。并写了详细的说明文档和示例,欢迎各位大佬前往拍砖、star。如果能给你提升一点效率,那再好不过了,先谢谢各位了。

IceApriler/miniprogram-picker​

简介

微信小程序的Picker组件只是半成品组件,在启用多级联动时需要监听bindcolumnchange事件,来手动更改rangevalue的值,从而完成Picker的联动变化,比较麻烦,不利于在不同的业务逻辑中的复用。

本组件为了解决以上痛点,对微信小程序原生Picker组件进行了二次封装。开发者只需要提供固定数据结构的sourceData,再进行一些必要配置,本组件就可以自动帮助开发者处理联动逻辑。

本组件支持npm构建,从小程序基础库版本2.2.1或以上、及开发者工具1.02.1808300或以上开始,小程序支持使用npm安装第三方包。

效果

WX20181217-105545@2x.png
WX20181217-105613@2x.png
WX20181217-105849@2x.png

API

属性

属性 说明 类型 默认值 是否必填
sourceData 源数组,sourceData有几维,Picker就可以有几阶。格式必须为数组和对象的集合,参考示例 Array [] true
steps Picker的阶数 Number 1 false
shownFieldName 展示数据的字段名称 String 'name' false
subsetFieldName 子节点的字段名称,该字段的值为Picker下一阶的数组 String 'subset' false
otherNeedFieldsName 其他需要返回的字段,开发者可以根据需求自定义 Array [] false
defaultIndex 默认选中项的下标数组,优先于defaultValue Array [] false
defaultValue 默认选中项的值数组,此属性启用时defaultValueUniqueField为必填项 Array [] false
defaultValueUniqueField 默认选中项的值数组的唯一字段,用来和源数组进行比对 String '' -
autoSelect 初始化时,是否需要自动调用bindchange事件返回结果给开发者 Boolean false false
initColumnSelectedIndex 选择了第n列后,是否将大于n的列的选择值自动初始化为0 Boolean false false
disabled 是否禁用 Boolean false false

方法

方法 说明 类型 事件对象
bindchange 用户点击确认时触发 EventHandle event.detail = {selectedIndex, selectedArray}
bindcancel 用户点击取消时触发 EventHandle event.detail为原生组件的bindcancel触发时的event对象
bindcolumnchange 用户滑动某一列的值改变时触发 EventHandle event.detail为原生组件的bindcolumnchange触发时的event对象

规则

  • sourceData为源数组,是一个数组对象结构的集合,sourceData有几维,Picker就可以有几阶。
  • steps,你需要明确指定Picker的阶数,比如三级联动则设置steps: 3
  • 需要注意的是,比如steps设置了3,那么sourceData务必要满足这个阶数。
  • initColumnSelectedIndex属性启用后,开发者调试工具上会有失效情况,但是真机目前没有发现问题,所以是否开启请开发者自行决定。
  • bindchange触发的事件对象:
    • selectedIndex:Picker选择项的索引数组;
    • selectedArray:Picker选择项的值数组;
  • 本组件的有些方法和属性与微信原生API的行为一致,比如:bindchangebindcancelbindcolumnchangedisabled。具体可以查看源码。

使用方法

  1. 安装miniprogram-picker包。

    npm install miniprogram-picker --production
    
  2. 点击微信开发者工具中的菜单栏:工具 --> 构建 npm。此时你会发现项目中多出一个miniprogram_npm目录,里面有编译过的miniprogram-picker

  3. .json中引入miniprogram-picker第三方组件。使用方法与使用自己封装的组件相同,只不过不需要写具体路径了,很方便。

    {
        "usingComponents": {
         "miniprogram-picker": "miniprogram-picker"
        }
    }
    
  4. .wxml中使用miniprogram-picker。我这里给出了两个小例子,第一个是三级联动,第二个是两级联动。具体属性和事件方法可以参考API。

    miniprogram-picker是没有任何样式的,具体样式开发者可以自定义,如果你熟悉slot的用法那就更好了,具体参考小程序组件wxml的slot
    css就略过了哈,各位可以去项目地址看。

      <miniprogram-picker
        sourceData="{{sourceData_1}}"
        steps="{{3}}"
        shownFieldName="{{'name'}}"
        subsetFieldName="{{'sonValue'}}"
        otherNeedFieldsName="{{['id', 'other']}}"
        defaultValue="{{[{name: '2'}, {name: '2.2'}, {name: '2.2.1'}]}}"
        defaultValueUniqueField="{{'name'}}"
        autoSelect="{{true}}"
        initColumnSelectedIndex
        disabled="{{false}}"
        bindchange="pickerChange"
        bindcancel="pickerCancel"
        bindcolumnchange="pickerColumnchange"
        data-picker="picker_1">
          <view class="picker">
            当前选择:<view wx:for="{{result_1}}" wx:key="index">{{item['name']}}</view>
          </view>
      </miniprogram-picker>
    
      <miniprogram-picker
        sourceData="{{sourceData_2}}"
        steps="{{2}}"
        shownFieldName="{{'name'}}"
        subsetFieldName="{{'nextLevel'}}"
        otherNeedFieldsName="{{['code']}}"
        defaultValue="{{[{code: '0110'}, {code: '011002'}]}}"
        defaultValueUniqueField="{{'code'}}"
        autoSelect="{{true}}"
        initColumnSelectedIndex
        disabled="{{false}}"
        bindchange="pickerChange"
        bindcancel="pickerCancel"
        bindcolumnchange="pickerColumnchange"
        data-picker="picker_2">
          <view class="picker">
            当前选择:<view wx:for="{{result_2}}" wx:key="index">{{item['name']}}</view>
          </view>
      </miniprogram-picker>
    
  5. .js中设置sourceData和监听pickerChange事件等。

      Page({
        /**
         * 页面的初始数据
         */
        data: {
          result_1: [],
          result_2: [],
          sourceData_1: [
            {
              id: 'id-1',
              name: '1',
              sonValue: [
                {
                  id: 'id-11',
                  name: '1.1',
                  sonValue: [
                    { id: 'id-111', name: '1.1.1' },
                    { id: 'id-112', name: '1.1.2' }
                  ]
                },
                {
                  id: 'id-12',
                  name: '1.2',
                  sonValue: [
                    { id: 'id-121', name: '1.2.1' },
                    { id: 'id-122', name: '1.2.2' }
                  ]
                }
              ]
            },
            {
              id: 'id-2',
              name: '2',
              sonValue: [
                {
                  id: 'id-21',
                  name: '2.1',
                  sonValue: [
                    { id: 'id-211', name: '2.1.1' },
                    { id: 'id-212', name: '2.1.2' }
                  ]
                },
                {
                  id: 'id-22',
                  name: '2.2',
                  sonValue: [
                    { id: 'id-221', name: '2.2.1' },
                    { id: 'id-222', name: '2.2.2' }
                  ]
                }
              ]
            }
          ],
          sourceData_2: [
            { name: '河北', code: '0311', nextLevel: [{ name: '石家庄', code: '031101' }, { name: '保定', code: '031102' }]},
            { name: '北京', code: '0110', nextLevel: [{ name: '朝阳', code: '011001' }, { name: '海淀', code: '011002' }]},
          ]
        },
        /**
         * Picker用户点击确认时触发
         *
         * @param {Object} e pickerChange的事件对象
         * @param {Object} e.detail.selectedIndex 用户选择的数据在数组中所在的下标
         * @param {Object} e.detail.selectedArray 用户选择的数据
         */
        pickerChange(e) {
          const { picker } = e.currentTarget.dataset
          const { selectedIndex, selectedArray } = e.detail
          const list = {
            picker_1: 'result_1',
            picker_2: 'result_2',
          }
          console.log('多级联动结果:', selectedIndex, selectedArray)
          const change = {}
          change[list[picker]] = selectedArray
          this.setData(change)
        },
        /**
         * Picker用户点击取消时触发
         *
         * @param {Object} e  pickerCancel的事件对象
         * @param {Object} e.detail  是原生Picker组件的bindcancel触发时的事件对象e
         */
        pickerCancel(e) {
          console.log(e)
        },
        /**
         * Picker用户滑动某一列的值改变时触发
         *
         * @param {Object} e pickerColumnchange的事件对象
         * @param {Object} e.detail  是原生Picker组件的bindcolumnchange触发时的事件对象e
         */
        pickerColumnchange(e) {
          console.log(e)
        },
      })
    

总结

这个组件其实在两三个月前就写好了,只不过当时正处于离职期间,一直没有时间精力去整理出来,然后在新公司写react-native也用了这个组件的逻辑,感觉确实比较方便吧,所以就在github开源了,并学习发布了npm包。

今天就写到这里啦,谢谢各位咯,欢迎众大佬到对miniprogram-picker提出意见或者交流哈。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容