微信小程序的多列选择器picker mode="multiSelector",需要的数组结构往往和后台给的结构不同,需要我们对数组拆分处理后,实现联动效果
下面分别是微信需要的数据结构,和后台给的数据结构
[['无脊柱动物', '脊柱动物'], ['扁性动物', '线形动物', '环节动物', '软体动物', '节肢动物'], ['猪肉绦虫', '吸血虫']]
实现思路:
1、声明多个数组,用来存储一级、二级选项
2、通过map() ,unshift(),switch语句,for循环的方法,对数组进行整理
3、因为展示的数组里只能有用于展示的name城市名和门店名,最后根据选中门店的下标,匹配原始数组里的门店id
下图是写完的样子,两级联动,第一列是城市,第二列是门店
首先,wxml页面DOM结构
<picker bindchange="bindPoiPickerChange" bindcolumnchange="bindPoiPickerColumnChange" mode="multiSelector" range="{{poiTotalArr}}" value="{{poiIndex}}" class='poi-picker'>
<view class="picker">
{{poiTotalArr[0][poiIndex[0]]}}
<block wx:if="{{poiTotalArr[0]}}">,</block>
{{poiTotalArr[1][poiIndex[1]]}}
<icon class='iconfont icon-zhankai1'></icon>
</view>
</picker>
js先在data中声明储存数据的变量数组,声明的数组有点多,方便从后台获取数据后,进一步处理
data: {
poiTotalList: [], //从后台获取的原始数组
poiIndex: [0, 0], //选中的店铺序号
totalPoiArr: [], //获取后台数组里包含id和name的整体数组
poiTotalArr: [], //整理后,picker读取绑定数据的整体数组
poiVal: "", //选中的店铺id,用来提交给后台
cityArr: [], //picker读取的店铺数组里的城市数组(一级选项)
poiArr: [], //picker读取的店铺数组里的店铺数组(二级选项)
},
onLoad:function(){
//"/aaaaa"获取后台数据路径
util.getRequest("/aaaaa", {}, res => {
//从后台获取的原始数组
let poiTotalList = res.data.data;
//因为数组里没有全国所有门店,手动添加,unshift()添加到数组最前面
poiTotalList.unshift({
"name": "全国",
"id": 0,
"shopList": [{
"name": "所有门店",
"id": 0,
}]
})
//给picker读取的店铺数组里的城市数组(一级选项)赋值
let cityArr = poiTotalList.map(item => {
return item.name;
})
console.log(cityArr, "cityArr")
//给包含id和name的二级门店数组赋值
//原理:Array.prototype.map()
//map()方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组,它不会改变原来的数组。
let totalPoiArr = poiTotalList.map(item => {
return item.shopList;//把原始数组里每一项里的shopList二级门店数据返回给新数组totalPoiArr
})
console.log(totalPoiArr, "totalPoiArr");
let poiArr = [];
//循环包含id和name的二级门店数组,并返回每一项里的name,把name push进用于picker组件读取的二级数组选项,即poiTotalArr[1]
totalPoiArr.forEach(item => {
poiArr.push(item.map(i => {
return i.name;
}));
})
console.log(poiArr, "poiArr")
//赋值
that.setData({
poiTotalList: poiTotalList,
poiTotalArr: [cityArr, poiArr[0]],//弹出时,默认二级是全国所有门店
poiArr: poiArr,
cityArr: cityArr,
totalPoiArr: totalPoiArr
})
console.log("poiTotalArr", that.data.poiTotalArr)
})
}
数组poiArr,picker读取的店铺数组里的店铺数组(二级选项):
数组poiTotalArr,picker读取绑定数据的整体数组的初始状态,数组中的第二项(二级选项)根据绑定的bindcolumnchange="bindPoiPickerColumnChange"方法动态变动
//某一列的值改变时触发 columnchange 事件
bindPoiPickerColumnChange(e) {
console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
let data = {
poiTotalArr: that.data.poiTotalArr,
poiIndex: that.data.poiIndex
}
data.poiIndex[e.detail.column] = e.detail.value;
switch (e.detail.column) {
case 0://第一列滚动时,用第一列下标,匹配第二列的值
for (let i = 0; i < that.data.cityArr.length; i++) {
if (data.poiIndex[0] == i) {
data.poiTotalArr[1] = that.data.poiArr[i];
}
}
data.poiIndex[1] = 0;//每次滚动第一列时,默认第二列第一项选中
break;
}
that.setData(data);
},
最后确认选择,根据下标匹配原始数组中门店id
//value 改变时触发 change 事件
bindPoiPickerChange(e) {
let cityIndex = e.detail.value[0];//第一列城市下标
let poiIndex = e.detail.value[1];//第二列门店下标
console.log("cityIndex:" + cityIndex, "poiIndex:" + poiIndex)
//选中的门店是第cityIndex项中的第poiIndex个门店
let poiVal = that.data.totalPoiArr[cityIndex][poiIndex].id;
that.setData({
poiIndex: e.detail.value, //门店下标
poiVal: poiVal //门店id
})
console.log(that.data.poiVal, "poiVal");
},