小程序 动态三级联动
微信小程序中提供了原生的省市区选择器: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, }) } }) },