V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
IceApril
V2EX  ›  JavaScript

小程序原生 picker 多级联动,处理数据麻烦?来试试 miniprogram-picker,提升你的效率!

  •  1
     
  •   IceApril · 2019-01-08 17:56:02 +08:00 · 3168 次点击
    这是一个创建于 1934 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    miniprogram-picker

    简介

    • 微信小程序的 Picker 组件只是半成品组件,在启用多级联动时需要监听bindcolumnchange事件,来手动更改rangevalue的值,从而完成 Picker 的联动变化,比较麻烦,不利于在不同的业务逻辑中的复用。
    • 本组件为了解决以上痛点,对微信小程序原生 Picker 组件进行了二次封装。开发者只需要提供固定数据结构的sourceData,再进行一些必要配置,本组件就可以自动帮助开发者处理联动逻辑。
    • 本组件支持 npm 构建,从小程序基础库版本2.2.1或以上、及开发者工具 1.02.1808300或以上开始,小程序支持使用 npm 安装第三方包。

    效果

    效果图不方便显示,➡️点击这里

    API

    无法显示列表,➡️点击这里

    规则

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

    使用方法

    1. 安装miniprogram-picker包。

      提醒:若是你不想用 npm,也可以直接下载最新release包放到项目的components中,就像用自己写的组件那样,只不过 npm 更加方便。

      npm install miniprogram-picker --production
      
      // 或者
      
      npm install miniprogram-picker --save
      
    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

        <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)
          },
        })
      
    6. .wxss中简单设置样式。

      .picker {
        display: flex;
        flex-direction: row;
        align-items: center;
        margin: 10rpx 0;
        padding: 10rpx 0;
        background-color: #DEECE2;
        font-size: 28rpx;
      }
      .picker view {
        padding: 2rpx 10rpx;
        margin-left: 10rpx;
        margin-right: 10rpx;
        border-bottom: 2rpx solid aqua;
      }
      

    帮助

    • 欢迎提 Issue,若是代码有 bug 或者你不明白的地方,我会尽快解决的。
    • 若有 feature 需要实现,可以 Issue 留言,若是喜欢,欢迎 star。感谢你的支持。
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3693 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 10:36 · PVG 18:36 · LAX 03:36 · JFK 06:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.