小程序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提出意見或者交流哈。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容