微信小程序多列下拉框的实现
多列下拉框实现介绍
利用微信小程序api,实现不同传输数据格式下的多列下拉框实现
首先了解一下picker中的事件
这里是官方文档,具体意思就是 当你滑动多列中的某一列的时候,
bindcolumnchange
事件就会触发。当选择完毕点击确定的时候
bindchange
事件就会触发
微信小程序的多列下拉框是真的反人类
vue什么的就是传个数据就行了,它这样搞,麻烦。不知道读者有没有简单的办法,有的可以留言评论,反正我是想不出来了。
成果
情况一:后端返回的数据是 一层一个数组,没有树形结构
如:
[[第一层数据],[第二层数据],[第三层数据]]
实现思路
定义三个数组,分别把每一层的数据放在对应数组中,用于更新,
定义一个只有三的元素的数组
multiIndex
表示每一层对应的下标。
需要注意的是
areapicker1/2/3
是所在层的所有数据
而
areaArry
是用于展示在页面上的数据,它的格式是
[[第一层],[第二层],[第三层]]
流程是用户滚动多列下拉框,程序通过
bindcolumnchange
事件,对
areaArry
里的数据进行实时更改,同时更改
multiIndex
的值(它代表的现在所选值在areaArry数组中对应的每一层的下标有几层
multiIndex
就有几个元素,两层就只有两个元素)
wxml
<picker mode="multiSelector" class="input_item_right" bindchange="bindpatrolquestiontype" value="{{multiIndex}}" range="{{areaArry}}" bindcolumnchange="bindMultiPickerColumnChange" bindchange="bindAreaChange" range-key='text'>
<view class="picker">
<view>
<view wx:if="{{rqstAreaCode==''}}">请选择区域</view>
</view>
<view>
{{rqstAreaCode}}
</view>
</view>
</picker>
js
var areapicker1 = []; //地区选择的第一列数据总数组
var areapicker2 = []; //地区选择的第二列数据总数组
var areapicker3 = []; //地区选择的第三列数据总数组
page({
data: {
multiIndex: [0, 0, 0],
areaArry: [],//展示在页面上的数据
areaCodeArry:[],//对应的code值
},
//注意拿到数据之后进行对areaArry初始化...
bindMultiPickerColumnChange: function (e) {
var that = this;
switch (e.detail.column) {
case 0:
//用临时数组存储
var list=[],//表示第二列展示的数据(只有name值)
list2 = [],//第三列的展示数据(只有name值)
codelist=[],//表示第二列value的值(只有code值)
codelist2=[],//表示第三列value的值(只有code值)
newpicker2=[],//临时的第二列数据(item的所有属性都有)
//从所有第二列的内容中取出与第一列选中状态的值对应的数据用于实时生成第二列
for (var i = 0; i < areapicker2.length; i++) {
if (areapicker2[i].parentGuid == areapicker1[e.detail.value].id) {
//若第二列的父亲跟这个相同,则push
newpicker2.push(areapicker2[i]);
list.push(areapicker2[i].areaName)
codelist.push(areapicker2[i].areaCode)
}
}
if (areapicker3.length > 0) {
for (var i = 0; i < areapicker3.length; i++) {
if (newpicker2.length > 0) {
if (areapicker3[i].parentGuid == newpicker2[0].id) {
list2.push(areapicker3[i].areaName)
codelist2.push(areapicker3[i].areaCode)
}
}
}
}
//实时修改第二列,并且把第二列设置到第一个展示
that.setData({
"areaArry[1]": list,
"areaArry[2]": list2,
"areaCodeArry[1]": codelist,
"areaCodeArry[2]": codelist2,
"multiIndex[0]": e.detail.value,
"multiIndex[1]": 0
})
console.log(that.data.multiIndex);
break;
case 1:
//同上
var list2 = [],//第三列展示值
codelist2 = [];//第三列value值
var multiIndex1 = that.data.multiIndex[0],
newpicker2 = [];//第二列的临时数组,用于第三列的比较
//从所有第二列的内容中取出与第一列选中状态的值对应的数据 用于第三列的判断
for (var i = 0; i < areapicker2.length; i++) {
if (areapicker2[i].parentGuid == areapicker1[multiIndex1].id) {
newpicker2.push(areapicker2[i]);
}
}
//从所有第三列的内容中取出与第一列选中状态的值对应的数据用于实时生成第三列
if (areapicker3.length > 0) {
for (var i = 0; i < areapicker3.length; i++) {
if (areapicker3[i].parentGuid == newpicker2[e.detail.value].id) {
list2.push(areapicker3[i].areaName)
codelist2.push(areapicker3[i].areaCode)
}
}
that.setData({
"areaArry[2]": list2,
"areaCodeArry[2]": codelist2,
"multiIndex[1]": e.detail.value,
"multiIndex[2]": 0
})
console.log(that.data.multiIndex);
}
break;
}
},
//点击确定后的操作,用来最后提交的值 利用multiIndex
bindAreaChange: function (e) {
var that = this;
var result = e.detail.value;//这里的value 就是 multiIndex
if (result.length > 2) {
var reslutname = that.data.areaArry[0][result[0]] + that.data.areaArry[1][result[1]] + (that.data.areaArry[2][result[2]] == undefined ? '' : that.data.areaArry[2][result[2]]);
var reslutcode = that.data.areaCodeArry[2][result[2]] == undefined ? '' : that.data.areaCodeArry[2][result[2]];
} else {
var reslutname = that.data.areaArry[0][result[0]] + that.data.areaArry[1][result[1]];
var reslutcode = that.data.areaCodeArry[1][result[1]];
}
this.setData({
rqstAreaCode: reslutname,
realrqstAreaCode: reslutcode
})
},
})
情况二:后端返回的数据是树形结构
如图
实现思路
同上,这个相对于上面的简单点,不需要
areapicker
来存储数据
wxml同上
js
var arrayList = [];
page({
data: {
multiIndex: [0, 0, 0],
areaArry: []
},
//初始化
//获取诉求类型和诉求区域
getEvent: function (accesstoken) {
app.fetch({
url: '...',
token: '',
params: {},
}).then(res => {
var list = res.custom.jsonList
arrayList = list;
self.setData({
//拿到数据之后初始化列表
areaArry: [arrayList, arrayList[0].children, arrayList[0].children[0].children]
})
})
},
bindMultiPickerColumnChange: function (e) {
var that = this;
console.log("多级联动控制", e);
var that = this;
//获取当前滚动的是哪一列,通过判断哪一列来实时控制下一列的变化
console.log("第", e.detail.column + 1, '列。第', e.detail.value + 1, '个数据');
switch (e.detail.column) {
case 0://第一列
var list2 = [],
list3 = [];
//选择第一列的这个值然后找到它的儿子
list2 = that.data.areaArry[e.detail.value].children;
//实时修改第二列,并且把第二列设置到第一个展示
list3 = list2[0].children
that.setData({
"areaArry[1]": list2,
"areaArry[2]": list3,
"multiIndex[0]": e.detail.value,
"multiIndex[1]": 0,
"multiIndex[2]": 0,
})
console.log(that.data.multiIndex);
break;
case 1://第二列
var list3 = [];
//从所有第二列的内容中取出与第一列选中状态的值对应的数据用于实时生成第二列 ?????
list3 = that.data.areaArry[1][e.detail.value].children
that.setData({
"areaArry[2]": list3,
"multiIndex[1]": e.detail.value,
"multiIndex[2]": 0
})
break;
case 2://第三列
that.setData({
"multiIndex[2]": e.detail.value
})
break;
}
console.log(that.data.areaArry)
},
bindAreaChange: function (e) {
var that = this;
var result = e.detail.value;
var multiIndex = that.data.multiIndex
result = arrayList[multiIndex[0]].children[multiIndex[1]].children[multiIndex[2]];
that.setData({
rqstAreaCode: result.text,
realrqstAreaCode: result.value
})
console.log('已选择的区域名称', that.data.rqstAreaCode);
console.log('已选择的区域代码', that.data.realrqstAreaCode);
},
})