微信小程序自定義地址組件

本文實例為大傢分享瞭微信小程序自定義地址組件的具體代碼,供大傢參考,具體內容如下

項目需求

需要調用後臺傳過來的地址,存儲地址時存的是地址的id,所以市面上的地址組件均不符合我的需求,隻能自定義一個。

技術選取

picker-view和picker-view-column

核心代碼

region.wxml

<!--地址選擇器-->
<view wx:if="{{show}}" class="region-picker" catchtap="hidePicker">
  <view class="picker-handle" catchtap>
    <view class="picker-cancel" catchtap="hidePicker">取消</view>
    <view class="picker-confirm" catchtap="chooseRegion">確定</view>
  </view>
  <picker-view class="picker" value="{{regions}}" bindchange="changePicker" catchtap>
    <picker-view-column>
      <view wx:for="{{provinces}}" wx:key="code" class="region-province">{{item.name}}</view>
    </picker-view-column>
    <picker-view-column>
      <view wx:for="{{citys}}" wx:key="code" class="region-city">{{item.name}}</view>
    </picker-view-column>
    <picker-view-column>
      <view wx:for="{{areas}}" wx:key="code" class="region-area">{{item.name}}</view>
    </picker-view-column>
  </picker-view>
</view>

region.less

.region-picker {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
  background: rgba(0, 0, 0, 0.6);

  .picker-handle {
    width: 100%;
    height: 72rpx;
    display: flex;
    justify-content: space-between;
    position: absolute;
    bottom: 500rpx;
    left: 0;
    background: #fff;
    box-sizing: border-box;
    padding: 0 30rpx;
    line-height: 72rpx;
    box-shadow: 0 6rpx 12rpx rgba(0, 0, 0, 0.6);

    .picker-cancel,
    .picker-confirm {
      font-size: 30rpx;
    }

    .picker-cancel {
      color: #9E9E9E;
    }

    .picker-confirm {
      color: #018A56;
    }
  }

  .picker {
    width: 100%;
    height: 500rpx;
    position: absolute;
    bottom: 0;
    left: 0;
    background: #fff;

    .region-province,
    .region-city,
    .region-area {
      text-align: center;
      font-size: 24rpx;
    }
  }
}

region.js

const app = getApp();
Component({
  /**
   * 組件的屬性列表
   */
  properties: {
    // 是否展示選擇器
    showPicker: {
      type: Boolean,
      value: false
    },
    // 初始省市區數組
    initRegions: {
      type: Array,
      value: []
    }
  },

  /**
   * 組件的初始數據
   */
  data: {
    // 當前省市區  0 省  1 市  2 區
    regions: [0, 0, 0],
    // 滑動選擇器之前的省市區信息
    oldRegions: [0, 0, 0],
    // 上一次選中的省市區信息
    prevRegions: [0, 0, 0],
    // 省列表
    provinces: [],
    // 市列表
    citys: [],
    // 區列表
    areas: [],
    // 省
    province: {
      name: '',
      code: ''
    },
    // 市
    city: {
      name: '',
      code: ''
    },
    // 區
    area: {
      name: '',
      code: ''
    },
    // 是否展示
    show: false
  },

  lifetimes: {
    attached: function () {

    }
  },

  observers: {
    'showPicker': function (value) {
      if (value) {
        this.setData({
          show: true
        })
        this.initPage();
      } else {
        this.setData({
          show: false
        })
      }
    }
  },

  /**
   * 組件的方法列表
   */
  methods: {
    // 初始化頁面
    initPage() {
      let regions = wx.getStorageSync('initRegions') || '';
      if (regions) {
        // 設置省
        app.api.region.index().then(res1 => {
          if (res1.code === 2000) {
            let data1 = res1.data;
            this.setData({
              provinces: data1.map(item => {
                return {
                  name: item.name,
                  code: item.rid
                }
              })
            })
            this.data.provinces.forEach((item, index) => {
              if (item.code === regions[0]) {
                this.setData({
                  ['regions[0]']: index,
                  ['oldRegions[0]']: index,
                  ['prevRegions[0]']: index,
                  province: {
                    name: item.name,
                    code: item.code
                  }
                })
                // 設置市
                app.api.region.index({
                  parent_id: regions[0]
                }).then(async res2 => {
                  if (res2.code === 2000) {
                    res2.data.forEach((item, index) => {
                      this.setData({
                        [`citys[${this.data.citys.length}]`]: {
                          name: item.name,
                          code: item.rid
                        }
                      })
                      if (item.rid === regions[1]) {
                        this.setData({
                          ['regions[1]']: index,
                          ['oldRegions[1]']: index,
                          ['prevRegions[1]']: index,
                          city: {
                            name: item.name,
                            code: item.rid
                          }
                        })
                      }
                    })
                    // 設置區
                    await app.api.region.index({
                      parent_id: regions[1]
                    }).then(res3 => {
                      if (res3.code === 2000) {
                        res3.data.forEach((item, index) => {
                          this.setData({
                            [`areas[${this.data.areas.length}]`]: {
                              name: item.name,
                              code: item.rid
                            }
                          })
                          if (item.rid === regions[2]) {
                            this.setData({
                              ['regions[2]']: index,
                              ['oldRegions[2]']: index,
                              ['prevRegions[2]']: index,
                              area: {
                                name: item.name,
                                code: item.rid
                              },
                            })
                          }
                        })
                      } else if (res3.code === 2001) {
                        app.deletetoken();
                      } else {
                        app.toast(res3.msg, 'none');
                      }
                    })
                  } else if (res2.code === 2001) {
                    app.deletetoken();
                  } else {
                    app.toast(res2.msg, 'none');
                  }
                })
              }
            })
          } else if (res.code === 2001) {
            app.deletetoken();
          } else {
            app.toast(res.msg, 'none');
          }
        })
      } else {
        this.getProvinces();
      }
    },
    /**
     * 獲取省
     */
    async getProvinces() {
      await app.api.region.index().then(res => {
        if (res.code === 2000) {
          let data = res.data;
          let provinceList = data.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            provinces: provinceList
          })
          this.initCitysAreas();
        } else if (res.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res.msg, 'none');
        }
      })
    },

    /**
     * 省改變
     * @param {number} code  省id 
     */
    changeProvince(code) {
      app.api.region.index({
        parent_id: code
      }).then(res1 => {
        if (res1.code === 2000) {
          let data1 = res1.data;
          let cityList = data1.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            citys: cityList
          })
          app.api.region.index({
            parent_id: this.data.citys[0].code
          }).then(res2 => {
            if (res2.code === 2000) {
              let data2 = res2.data;
              let areaList = data2.map(item => {
                return {
                  name: item.name,
                  code: item.rid
                }
              })
              this.setData({
                areas: areaList
              })
            } else if (res2.code === 2001) {
              app.deletetoken();
            } else {
              app.toast(res2.msg, 'none');
            }
          })
        } else if (res1.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res1.msg, 'none');
        }
      })
    },

    /**
     * 市改變
     * @param {number} code 市id
     */
    changeCity(code) {
      app.api.region.index({
        parent_id: code
      }).then(res => {
        if (res.code === 2000) {
          let data = res.data;
          let areaList = data.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            areas: areaList
          })
        } else if (res.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res.msg, 'none');
        }
      })
    },

    /**
     * 改變picker
     */
    changePicker(e) {
      let newRegion = e.detail.value;
      for (let i = 0; i < newRegion.length; i++) {
        // 找到改變的那一列
        if (newRegion[i] !== this.data.oldRegions[i]) {
          switch (i + 1) {
            case 1:
              // 省改變瞭
              this.changeProvince(this.data.provinces[newRegion[i]].code)
              this.setData({
                regions: [newRegion[i], 0, 0],
                oldRegions: [newRegion[i], 0, 0]
              })
              newRegion = [
                newRegion[0], 0, 0
              ]
              break;
            case 2:
              // 市改變瞭
              this.changeCity(this.data.citys[newRegion[i]].code)
              this.setData({
                regions: [this.data.oldRegions[0], newRegion[i], 0],
                oldRegions: [this.data.oldRegions[0], newRegion[i], 0]
              })
              break;
            case 3:
              // 區改變
              this.setData({
                regions: [this.data.oldRegions[0], this.data.oldRegions[1], newRegion[i]],
                oldRegions: [this.data.oldRegions[0], this.data.oldRegions[1], newRegion[i]]
              })
              break;
          }
        }
      }
    },
    /**
     * 初始化市區列表
     */
    initCitysAreas() {
      // 獲取市
      app.api.region.index({
        parent_id: this.data.provinces[this.data.regions[0]].code
      }).then(res1 => {
        if (res1.code === 2000) {
          let data1 = res1.data;
          let cityList = data1.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            citys: cityList
          })
          // 獲取區
          app.api.region.index({
            parent_id: this.data.citys[this.data.regions[1]].code
          }).then(res2 => {
            if (res2.code === 2000) {
              let data2 = res2.data;
              let areaList = data2.map(item => {
                return {
                  name: item.name,
                  code: item.rid
                }
              })
              this.setData({
                areas: areaList,
                regions: this.data.regions
              })
            } else if (res2.code === 2001) {
              app.deletetoken();
            } else {
              app.toast(res2.msg, 'none');
            }
          })
        } else if (res1.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res1.msg, 'none');
        }
      })
    },
    /**
     * 隱藏選擇器
     */
    hidePicker() {
      this.setData({
        show: false,
        regions: this.data.prevRegions,
        oldRegions: this.data.prevRegions
      })
    },
    /**
     * 確定選擇地址
     */
    chooseRegion() {
      this.setData({
        province: {
          name: this.data.provinces[this.data.regions[0]].name,
          code: this.data.provinces[this.data.regions[0]].code
        },
        city: {
          name: this.data.citys[this.data.regions[1]].name,
          code: this.data.citys[this.data.regions[1]].code
        },
        area: {
          name: this.data.areas[this.data.regions[2]].name,
          code: this.data.areas[this.data.regions[2]].code
        },
        prevRegions: this.data.regions,
      })
      this.triggerEvent("chooseRegion", {
        initRegions: [this.data.province.code, this.data.city.code, this.data.area.code],
        region: this.data.province.name + ' ' + this.data.city.name + ' ' + this.data.area.name
      })
      wx.setStorageSync('initRegions', [this.data.province.code, this.data.city.code, this.data.area.code]);
      this.hidePicker();
    },
  }
})

使用

wxml

<region showPicker="{{show.picker}}" initRegions="{{initRegions}}" bind:chooseRegion="chooseRegion"></region>

js

// pages/settled/settled.js
const app = getApp();
Page({

  /**
   * 頁面的初始數據
   */
  data: {
    // 選中的省市區id數組
    initRegions: [],
    // 常住地址
    region: '',
    // 展示控制
    show: {
      picker: false, // 地址選擇器
    }
  },

  /**
   * 監聽頁面卸載
   */
  onUnload: function() {
    wx.removeStorageSync('initRegions');
  },
  /**
   * 展示常住地址選擇器
   */
  showPicker() {
    this.setData({
      ['show.picker']: true
    })
  },

  /**
   * 選擇常住地址
   */
  chooseRegion(e) {
    this.setData({
      initRegions: e.detail.initRegions,
      region: e.detail.region
    })
  }
})

效果

參考文檔

picker-view | 微信開放文檔
picker-view-column | 微信開放文檔

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: