微信小程序-官方組件picker云開發省市區三級聯動選擇器

早在一年多以前,我寫過一篇微信小程序-省市區縣三級聯動選擇器的文章,那時候小程序剛起步,網上找了很久沒有相關的文獻,官方也沒有相關的組件,我就自己動手寫了一個,也因為剛開始接觸寫的不是很好。
當時省市區的數據我是在網上找的一個json文檔,然后把里面的json數據復制出來,在js文件里寫了一個方法用數組接收復制出來的json數據,外部調用這個方法就直接返回這個數組,因為json數據有幾百k的占用,顯然不是很符合小程序的“小”的初衷。
最近無事,研究了下云開發,我就想把數據放在云端數據庫,重寫一下省市區三級聯動選擇器。后來在查看小程序組件的時候發現,現在官方組件picker專門為我們提供了"省市區選擇器"這個控件,假如單單只是需要文字形式的"省市區選擇器",大家可以選用官方的,性能方面以及簡易方面應該更適合普通開發者,因為直接接入就行了,不用寫內部復雜的邏輯。

圖1-官方省市區選擇器文檔說明

<!.wxml-->
<view class="section">
  <view class="section__title">省市區選擇器</view>
  <picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}">
    <view class="picker">
      當前選擇:{{region[0]}},{{region[1]}},{{region[2]}}
    </view>
  </picker>
</view>
//.js
//點擊確定按鈕
bindRegionChange: function (e) {
    console.log(e)
    console.log('picker發送選擇改變,攜帶值為', e.detail.value)
    this.setData({
      region: e.detail.value
    })
  }

但是我們往往不只是需要e.detail.value里面的省市區名字,可能后臺只需要傳code就行了。按圖1bingchange的屬性是有code的但是我打印e.detail.code發現是沒有code的。不知道是不是我版本的問題,反正打印除了e.detail.value有值postcode和code都是沒值的,那怎么辦呢?沒值我就自己造值,從某接口獲取了一份數據,已經按省市區三維數組處理好了,我存在了云數據庫里。
因為官方的"省市區選擇器"mode="region"里的數組是定死的由微信提供,不能做更改,好在同是piker組件mode="multiSelector"時提供了自定義的"多列選擇器":


圖2-多列選擇器

本文使用的數據結構大致如下:

[
  {
    "citys":[
              {
                 "areas":[
                           {
                             "code":"440303",
                             "name":"羅湖區"
                           },
                           {
                             "code":"440304",
                             "name":"福田區"
                           },   
                           ...
                         ],
                  "code":"440300",
                  "name":"深圳市"
               },
               ...
            ],
    "code":"440000",
    "name":"廣東省"
  },
  ...
]

屬性rang對應是最外層的整個數組,range-key指定選擇器上要顯示的內容,這里range-key="name"就會顯示中文內容,假若range-key="code"顯示的就是code字段內容了就是一串數字,眼尖的朋友應該知道其實這串數字就是身份證前六位,通過它們的組合傳給后臺就可以定位省市區了。
言歸正傳動手寫代碼:

<!--pages/getCityData/getCityData.wxml-->
<view class="section">
  <view class="section__title">多列選擇器</view>
  <picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}" range-key="name">
    <button class="picker">
      當前選擇:{{multiArray[0][multiIndex[0]].name}}({{multiArray[0][multiIndex[0]].code}}){{multiArray[1].length > 0 ?("," + multiArray[1][multiIndex[1]].name + "(" + multiArray[1][multiIndex[1]].code + ")"):""}}{{multiArray[2].length > 0 ?("," + multiArray[2][multiIndex[2]].name + "(" + multiArray[2][multiIndex[2]].code + ")"):""}}
    </button>
  </picker>
</view>
/* pages/getCityData/getCityData.wxss */

.picker{
    padding: 13px;
    background-color: #FFFFFF;
}
//pages/getCityData/getCityData.json
{
  "component": true,
  "usingComponents": {}
}

js文件中multiArray代表顯示的[省,市,區]數組,multiIndex代表滑動后定位的下標數組。從數據庫獲取數據后通過[0,0,0]得到初始化的multiArray,通過滑動調用bindMultiPickerColumnChange方法得到新的數組下標數組,進而得到新的數據數組。

// pages/getCityData/getCityData.js
Component({
  /**
   * 組件的屬性列表
   */
  properties: {

  },

  /**
   * 組件的初始數據
   */
  data: {
    multiArray: [],
    multiIndex: [0,0,0]
  },
  lifetimes: {
    // 生命周期函數,可以為函數,或一個在methods段中定義的方法名
    attached: function () { 
      this.getCityInfo()
    }
  },
  /**
   * 組件的方法列表
   */
  methods: {
    //獲取數據庫數據
    getCityInfo: function(){
      wx.showLoading({
        title: 'Loading...',
      })
      const db = wx.cloud.database()
      //因為數據庫只存有一個總的數據字典,所以指定它的ID直接獲取數據
      var that = this
      db.collection('cityDataArr').doc('5bdad6225f23a246bb2a97e1').get({
        success: res => {
          wx.hideLoading();
          if (res.data){
            //獲取云數據庫數據
            var temp = res.data.data;
            //初始化更新數據
            that.setData({
              provinces: temp,
              multiArray: [temp, temp[0].citys, temp[0].citys[0].areas],
              multiIndex: [0, 0, 0]
            })
            console.log(that.data.provinces)
          }
        },
        fail: err => {
          wx.hideLoading();
          console.error(err)
        }
      })     
    },
    //點擊確定
    bindMultiPickerChange: function (e) {
      console.log('picker發送選擇改變,攜帶值為', e.detail.value)
      this.setData({
        multiIndex: e.detail.value
      })
    },
    //滑動
    bindMultiPickerColumnChange: function(e){
      console.log('修改的列為', e.detail.column, ',值為', e.detail.value);
      var data = {
        multiArray: this.data.multiArray,
        multiIndex: this.data.multiIndex
      };
      //更新滑動的第幾列e.detail.column的數組下標值e.detail.value
      data.multiIndex[e.detail.column] = e.detail.value;
      //如果更新的是第一列“省”,第二列“市”和第三列“區”的數組下標置為0
      if (e.detail.column == 0){
        data.multiIndex = [e.detail.value,0,0];
      } else if (e.detail.column == 1){
        //如果更新的是第二列“市”,第一列“省”的下標不變,第三列“區”的數組下標置為0
        data.multiIndex = [data.multiIndex[0], e.detail.value, 0];
      } else if (e.detail.column == 2) {
        //如果更新的是第三列“區”,第一列“省”和第二列“市”的值均不變。
        data.multiIndex = [data.multiIndex[0], data.multiIndex[1], e.detail.value];
      }
      var temp = this.data.provinces;
      data.multiArray[0] = temp;
      if ((temp[data.multiIndex[0]].citys).length > 0){
        //如果第二列“市”的個數大于0,通過multiIndex變更multiArray[1]的值
        data.multiArray[1] = temp[data.multiIndex[0]].citys;
        var areaArr = (temp[data.multiIndex[0]].citys[data.multiIndex[1]]).areas;
        //如果第三列“區”的個數大于0,通過multiIndex變更multiArray[2]的值;否則賦值為空數組
        data.multiArray[2] = areaArr.length > 0 ? areaArr : [];
      }else{
        //如果第二列“市”的個數不大于0,那么第二列“市”和第三列“區”都賦值為空數組
        data.multiArray[1] = [];
        data.multiArray[2] = [];
      }
      //data.multiArray = [temp, temp[data.multiIndex[0]].citys, temp[data.multiIndex[0]].citys[data.multiIndex[1]].areas];
      //setData更新數據
      this.setData(data);
    }
  }
})

注釋說明都在以上代碼中,至于最后怎么顯示?省:multiArray[0][multiIndex[0]],市:multiArray[1][multiIndex[1]],區:multiArray[2][multiIndex[2]]。得到的是object的字典鍵值對,需要顯示中文取.name,需要獲取編碼取.code。

<!--pages/getCityData/getCityData.wxml-->
當前選擇:{{multiArray[0][multiIndex[0]].name}}({{multiArray[0][multiIndex[0]].code}}){{multiArray[1].length > 0 ?("," + multiArray[1][multiIndex[1]].name + "(" + multiArray[1][multiIndex[1]].code + ")"):""}}{{multiArray[2].length > 0 ?("," + multiArray[2][multiIndex[2]].name + "(" + multiArray[2][multiIndex[2]].code + ")"):""}}
圖3-最終效果

下面附上處理后的json數據cityDataArr.json,直接上傳到云數據庫即可。
未處理的plist文件cityDataArr.plist也一并附上 。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網絡請求組件 FMDB本地數據庫組件 SD...
    陽明先生_X自主閱讀 16,000評論 3 119
  • 所謂“決情定宜”,就是要能夠決斷出最有價值、最值得去做的事。你能夠認清自己的能力極限,在第一時間作出有效地判斷,對...
    不會飛的章魚閱讀 675評論 1 0
  • 2018.6.5 星期二 晴 今晚雯爸把一個大西瓜一切兩半,用勺子挖著先吃起來,我忙完手里的活坐到桌前準備...
    開心靖雯閱讀 193評論 0 0
  • 聽說蛇是會復仇的,真的有這回事嗎? 殺死毒蛇 賈家世世代代都住在一片深山老林里,這里沒人打擾,特別安靜。 賈三每天...
    那年木槿花開閱讀 1,365評論 50 53