小程序 动态三级联动

微信小程序中提供了原生的省市区选择器:mode = region,但是这次项目中使用的是后台的省市区数据,所以需要自定义选择器。使用到的是 mode = multiSelector 多列选择器。

选择器官方地址:https://developers.weixin.qq.com/miniprogram/dev/component/picker.html

这次的需求是根据前两级省市,列出第三级的法院列表(后台数据)

交互

首先用户点击选择法院按钮,选择省级地区,然后通过选择的省级id充当查询条件获取市级数据,然后用选择市级后的id查询法院数据。

    <view>法院选择</view>
    <view class="location flex-row">
      <view class="iconfont icon-chaxun pt10"> </view>

      <picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">
        <!-- <view class="picker">
          {{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}
        </view> -->
        <view class="picker f30">
         {{selname}}{{multiArray[2][multiIndex[2]]}}
        </view>
      </picker>

    </view>
解释:
1、picker组件用来创建一个从底部弹起的滚动选择器
2、mode="multiSelector"用来声明创建的是多列选择器
3、range="{{multiArray}}" multiArray就是我们的多维数组,这次我们用来放置数据所有的名字
4、value="{{multiIndex}}" multiIndex也是数组,用来表示选择的多维数组的每一项的第几个
5、bindchange是value改变触发的事件,bindcolumnchange每一列值改变时候触发的事件

另外,注释部分是三级的选择结果都显示,而我们只显示法院名。

bindcolumnchange与bindchange

bindcolumnchange

上面说了,bindcolumnchange用来绑定每一列值改变时候触发的事件

bindMultiPickerColumnChange(e){
    console.log(e.detail)   // {column: 2, value: 1}
    switch (e.detail.column)  { // 此时的改变列数
      case 0:
          // 处理逻辑
      break;
      case 1:
          //  处理逻辑
      break;
    }
    this.setData({
      // 更新数据
    })
}

column 的值表示改变了第几列(下标从0开始),value 的值表示变更值的下标

bindchange

bindchange用来绑定value改变触发的事件

bindMultiPickerChange(e){ // picker发送选择改变时候触发 通过e.detail.value获取携带的值
    console.log(e.detail.value)  //  [0,1,2]  
    this.setData({
      multiIndex: e.detail.value  // 直接更新即可
    })
}

逻辑

认识了上面的两个方法,我们来缕下思路,然后实现起来大体分为以下几步:

1、加载省级数据,处理后放置在multiArray里面,存储下原始数据并用第一个数据的id请求市级数据,拿到市级数据后做同样操作,法院同理。

2、编写bindMultiPickerColumnChange和bindMultiPickerChange函数,用来处理选择器更改时候的操作

3、页面加载后,调用获取省级数据的函数,这个函数逐层会去拿市级和法院的数据

js代码:

Page({

  /**
   * 页面的初始数据
   */
  data: {
    selname: "请选择法院",

    multiArray: [],
    multiIndex: [0, 0, null],
    chinaData: [],

    changeP: '', //
    changeC: '', //
    courtName:'', //法院名
    courtId: '', //法院ID

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.getSiteData();

    var courtinfo = wx.getStorageSync('cpwsCourt'); //读缓存
    console.log(courtinfo);
    if (courtinfo){
      this.setData({
        multiIndex: courtinfo.value,
        selname: '',
      })
    }

  },

  //value 改变时触发 change 事件
  bindMultiPickerChange: function (e) {
    var that = this;
    console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      multiIndex: e.detail.value
    }) 

    wx.request({
      url: '法院接口地址',
      data:{
        province: that.data.changeP,
        city: that.data.changeC
      },
      method: 'GET',
      success: res => {
        console.log(res);
        var courtIndex = that.data.multiIndex[2];
        console.log(res.data.data[courtIndex].systemCourtId);
        that.setData({
          courtId: res.data.data[courtIndex].systemCourtId,
          courtName: res.data.data[courtIndex].courtName,
          selname:'',
        })
        var obj = {};
        obj.name = that.data.courtName;
        obj.code = that.data.courtId;
        obj.value = that.data.multiIndex;
        wx.setStorageSync('cpwsCourt', obj);//存储法院
        
      }
    })

  },
  //列改变时触发
  bindMultiPickerColumnChange: function (e) {
    //console.log(e.detail.value);
    var move = e.detail;
    var index = move.column;
    var value = move.value;
    if (index == 0) {
      this.setData({
        multiIndex: [value, 0, 0]
      })
      this.getCity();
    }
    if (index == 1) {
      this.setData({
        "multiIndex[1]": value,
        "multiIndex[2]": 0,
      })
      this.getCourt();
    }

  },

  //省份
  getSiteData: function () {
    var that = this;
    wx.request({
      url: 'http://localhost:8080/pc-code.json', // 这是我们本地的地址
      success: res => {
        console.log(res); //输出接口的回调
        var chinaData = res.data;
        this.data.chinaData = chinaData;
        var sheng = []; //  设置省数组
        for (var i = 0; i < chinaData.length; i++) {
          sheng.push(chinaData[i].name);
        }
        this.setData({
          "multiArray[0]": sheng
        })
        that.getCity(); // 得到市

      }
    })
  },

  getCity: function () { // 得到市
    var shengNum = this.data.multiIndex[0];
    var chinaData = this.data.chinaData;
    var cityData = chinaData[shengNum].children;
    var city = [];
    for (var i = 0; i < cityData.length; i++) {
      city.push(cityData[i].name)
    }
    this.setData({
      "multiArray[1]": city
    })
    this.getCourt(); //得到法院
  },

  getCourt: function () {
    var that = this;
    var shengNum = this.data.multiIndex[0];
    var cityNum = this.data.multiIndex[1];
    var chinaData = this.data.chinaData;

    that.setData({
      changeP: chinaData[shengNum].name,
      changeC: chinaData[shengNum].children[cityNum].name,
    })
    
    wx.request({
      url:'法院接口地址',
      data:{
        province: that.data.changeP,
        city: that.data.changeC
      },
      method: 'GET',
      header: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      success: res => {
        console.log(res);
        var court = [];
        for (var i = 0; i < res.data.data.length; i++) {
          court.push(res.data.data[i].courtName);
        }
        that.setData({
          "multiArray[2]": court,
        })

      }
    })

  },




})

找了一个“省份、城市” 二级联动的数据放在本地测试,所以代码是根据本地数据写的,有后台数据接口,在更换。

  data: {
     currnetProvinceId:'',
     currnetCityId:'',
  },
   ...

  //省份
  getSiteData: function () {
     wx.request({
      url: '../province_list', //  
      success: res => {
        ...
        var defaultCode = this.data.provinceList[0].id  // 使用第一项当作参数获取市级数据
        if (defaultCode){
          this.setData({
            currnetProvinceId: defaultCode  // 保存在当前的省级key
          })
          this.getCity(defaultCode)  // 获取市级数据
        }

      }
  },

  getCity: function (code) { 
     this.setData({
       currnetProvinceKey: code  // 保存当前选择的市级code
     })
     wx.request({
      url: '../city_list',
      data:{
         provinceCode: code
      }  
      success: res => {
         ...
         var defaultCode = this.data.cityList[0].id  // 用第一个获取门店数据
          if (defaultCode){
          this.setData({
            currnetCityId: defaultCode  // 存下当前选择的城市key
          })
          this.getCourt(defaultCode) // 获取法院数据
        }

      }

  },
    
  getCourt: function () {
     wx.request({
      url: '../court_list', 
      data:{
         provinceCode: this.data.currnetProvinceId,
         cityCode: this.data.currnetCityId
      },  
      success: res => {
         ...
      }
  }
      

调用后台接口代码:

//省份
  getSiteData: function () {
    var that = this;
    wx.request({
      url: api.wx.chinaAddr,
      data: app.getSign({
        'adCode':'000000'  //默认000000
      }),
      success: res => {
        var chinaData = res.data.data;
        this.data.chinaData = chinaData;
        var sheng = []; //  设置省数组
        for (var i = 0; i < chinaData.length; i++) {
          sheng.push(chinaData[i].adName);
        }
        this.setData({
          "multiArray[0]": sheng
        })
        that.getCity('101000'); // 得到市

      }
    })
  },
  //
  getCity: function (code) { // 得到市
    var that = this;
    var courtinfo = wx.getStorageSync('ktggCourt');
    if (courtinfo.currentProvinceCode){ //缓存中的省级code
      code = courtinfo.currentProvinceCode
    }
    wx.request({
      url: api.wx.chinaAddr ,
      data: app.getSign({
        'adCode': code
      }),
      success: res => {
        console.log(res);
        var cityData = res.data.data;
        this.data.cityData = cityData;
        var city = [];
        for (var i = 0; i < cityData.length; i++) {
          city.push(cityData[i].adName)
        }
        this.setData({
          "multiArray[1]": city
        })
        this.getCourt(res.data.data[0].adCode); //得到法院

      }
    })
  },
  //法院
  getCourt: function (code) {
    var that = this;
    var courtinfo = wx.getStorageSync('ktggCourt');
    if (courtinfo.currentCityCode) { //缓存中的市级code
      code = courtinfo.currentCityCode
    }
    wx.request({
      url: api.wx.codeCourt,
      method: 'GET',
      header: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      data:app.getSign({
        'adCode': code
      }),
      success: res => {
        console.log(res);
        var courtData = res.data.data;
        this.data.courtData = courtData;
        var court = [];
        for (var i = 0; i < courtData.length; i++) {
          court.push(courtData[i].courtName);
        }
        that.setData({
          "multiArray[2]": court,
        })

      }
    })

  },
原文地址:https://www.cnblogs.com/joe235/p/11424385.html