微信小程序,省市区三级联动组件

微信小程序有默认省市区三级联动组件

<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>
bindRegionChange: function (e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      region: e.detail.value
    })
  }

这样可以满足基本的开发需求,但是有时候后台要传省市区的id,这时候这个组件不满足这个需求了。

在data里面定义几个值

    region: ['浙江省', '杭州市', '西湖区'],
    regionArray: [[], [], []],
    regionOpts: [[], [], []],
    regionIndex: [0, 0, 0],
    prevRegionArray: null,
    prevRegionOpts: null,
    prevRegionIndex: null,

在onload里面

onLoad: function (option) {
    let getCallBack = (_regionIndex, initRegionId) => {
      return (opts, array) => {
        for (let index in opts) {
          let opt = opts[index];
          if (opt.region_id == initRegionId) {
            let regionIndex = this.data.regionIndex;
            regionIndex[_regionIndex] = index;
            this.setData({ regionIndex });
          }
        }
        this.changeRegionOpt(_regionIndex, opts, array);
      }
    };
    this.getRegionOpts(1, getCallBack(0, 2));
    2 && this.getRegionOpts(2, getCallBack(1, 52));
    52 && this.getRegionOpts(52, getCallBack(2, 500));
  },

从后台获取省市区三级联动

bindRegionChange: function (e) {
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      region: e.detail.value
    })
  },
  /*省市区联动*/
  getRegionOpts(regionId, callBack) {
    Trequest({
      url: "region/children",
      method: 'post',
      data: {
        m: 'area',
        a: 'get_area',
        parent_id: regionId
      },
      callback({ data: r }) {
        if (!Array.isArray(r))
          return;
        var opts = [];
        var regionArray = [];
        r.forEach(({ region_id, region_name }, index) => {
          opts.push({ region_id, region_name });
          regionArray.push(region_name);
        });
        callBack(opts, regionArray);
      }
    })
  },

  changeRegionOpt(index, regionOpts, regionArray) {
    let { regionArray: mArray, regionOpts: mOpts } = this.data;
    mArray[index] = regionArray;
    mOpts[index] = regionOpts;
    this.setData({
      regionArray: mArray,
      regionOpts: mOpts
    });
  },

  regionFocus() {
    let {
      regionArray, regionOpts, regionIndex
    } = this.data;
    this.setData({
      prevRegionArray: JSON.parse(JSON.stringify(regionArray)),
      prevRegionOpts: JSON.parse(JSON.stringify(regionOpts)),
      prevRegionIndex: JSON.parse(JSON.stringify(regionIndex))
    });
  },

  regionCancel() {
    let {
      prevRegionArray, prevRegionOpts, prevRegionIndex
    } = this.data;
    this.setData({
      regionArray: prevRegionArray,
      regionOpts: prevRegionOpts,
      regionIndex: prevRegionIndex
    });
  },
  
  regionPickerChange({ detail: { value: regionIndex } }) {
    let opts = this.data.regionOpts;
    let userInfo = this.data.userInfo;
    /*获取对应的省市区*/
    userInfo.province = (opts[0][regionIndex[0]] || {}).region_id;
    userInfo.city = (opts[1][regionIndex[1]] || {}).region_id;
    userInfo.district = (opts[2][regionIndex[2]] || {}).region_id;
    /*保存到用户信息*/
    this.setData({ userInfo, regionIndex });
  },

  regionPickerColumnChange({ detail: { value: index, column: col } }) {
    let region = this.data.regionOpts[col][index];
    /*如果改变了省或者市,则获取对应的市或区的子集*/
    if (col === 0)
      /*获取市列表*/
      this.getRegionOpts(region.region_id, (opts, array) => {
        /*更新市列表*/
        this.changeRegionOpt(1, opts, array);
        /*获取第一个市对应的区列表并更新*/
        this.getRegionOpts(opts[0].region_id, this.changeRegionOpt.bind(this, 2))
      }
      );
    else if (col === 1)
      /*获取区列表并更新*/
      this.getRegionOpts(region.region_id, this.changeRegionOpt.bind(this, 2))
  },

在wxml里面

<view class='line_item item_one senderStaticDiv flex_bt' bindtap='accountSet'>
        <text class='_left'>所在省市区</text>
        <view class='_right _right_rt '>
            <picker mode="multiSelector" bindtap="regionFocus"
                    bindcancel = 'regionCancel'
                    bindchange="regionPickerChange" bindcolumnchange="regionPickerColumnChange" value="{{regionIndex}}" range="{{regionArray}}">
                <view class="picker">
                    {{regionArray[0][regionIndex[0]]}}
                    {{regionArray[1][regionIndex[1]]}}
                    {{regionArray[2][regionIndex[2]]}}
                </view>
            </picker>
        </view>
    </view>

你可能感兴趣的:(微信小程序,小程序)