【微信小程序】picker组件多列选择器的使用
功能需求
用微信小程序的多列选择器实现对一个树状结构图中的末节点的选择,要求选择器的第一列改变时,后面列的选项会联动改变。树状结构图的部分数据如下图;
图1 数据的树状结构图
效果预览
图2 多列选择器默认图当选择“卡丘厂”后,后面的选项会联动改变:
图3 首列改变后的联动图
实现过程
1. WXML
使用
的mode = multiSelector时的多列选择器完成。
官方文档针对多列选择器的介绍是这样的:
图4 微信官方文档对多列选择器参数的介绍
下面我们进行详细的说明:
range是一个二维数组,用于存放打开多列选择器后显示的默认的数据信息,以图1中的树为例,默认的信息就是每层的第一个数组, 如下图红框所示。
![range数组示例](https://img-/8d3d3c1c97fd49eb9b44e405c2eba41d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5bCP55m95bCP55m95L2g5pyA55m9,size_19,color_FFFFFF,t_70,g_se,x_16#pic_center)<center>图5 range数组示例</center>
value是一个是数组,数组长度与range的长度相同,每个元素的值对应着range中数组的下标,用于表示range数组里的第几个元素被选中。若被选中的是“皮卡丘厂-皮班组2-皮数据线21-皮传感量211”,则value=[1,1,0,0].bindchange是一个触发事件,value改变时触发该事件。该事件被触发时,通常是将value的值存到data中。bindcolumnchange是一个触发事件,列变时触发,修改的列为event.detail.column,(列数组的下标)值为e.detail.value。该事件被触发时,需要通过修改range的值来实现滑动选择器后的联动效果。
2. wxml示例
<picker mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" range="{{defaultarray}}" value="{{multiIndex}}">已选中:{{defaultarray[0][multiIndex[0]]}}-{{defaultarray[1][multiIndex[1]]}}-{{defaultarray[2][multiIndex[2]]}}</picker>
3. JS
js部分主要是上述提到的两个触发事件的编写。
首先先设置需要用到的变量。对图1所示的树,用array表示;range数组的变量名为defaultarray;value数组的变量名为multiIndex;
在onLoad中从array里提取defaultarray的数据;
在bindchange函数中,将改变了的value值setData到data中;
bindcolumnchange函数的逻辑比较复杂:
第一步,修改改变后的multiIndex的某一列对应的数值;
第二步,根据改变的列号分情况讨论,修改剩余的multiIndex列的数值,并且更改defaultarray的内容。分析如下:
如果改变的是第1列的数据(e.detail.column==0),此时要将第二列及之后的列的数据下标全部置为0,即置为缺省数据,并将defaultarray数组进行联动变化;
改变第一列后,defaultarray联动变化的过程是:
保留defaultarray[0]的数组;
defaultarray[1]的数组变为array的multiIndex[0]的值对应的next1数组的title;
defaultarray[2]的数组变为array的multiIndex[0]的值对应的next1数组的[0]号的next2数组的title;
defaultarray[3]的数组变为array的multiIndex[0]的值对应的next1数组的[0]号的next2数组的[0]号的next3数组的title;
如果改变的是第2列的数据(e.detail.column==1),此时要将第3列及之后的列的数据下标全部置为0,即置为缺省数据,并将defaultarray数组进行联动变化;
改变第2列后,defaultarray联动变化的过程是:
保留defaultarray[0]的数组;
保留defaultarray[1]的数组;
defaultarray[2]的数组变为array的multiIndex[1]的值对应的next1数组的[0]号的next2数组的title;
defaultarray[3]的数组变为array的multiIndex[1]的值对应的next1数组的[0]号的next2数组的[0]号的next3数组的title;
以此类推…
4. JS示例
data: {array: [{title: '皮卡丘厂',next1: [{title: '皮班组1',next2: [{title: '皮数据线1',next3: [{title: '皮传感量1'}, {title: '皮传感量2'}, {title: '皮传感量3'}, {title: '皮传感量4'}, {title: '皮传感量5'}]}, {title: '皮数据线2',next3: [{title: '皮传感量21'}, {title: '皮传感量22'}, {title: '皮传感量23'}, {title: '皮传感量24'}, {title: '皮传感量25'}]}, {title: '皮数据线3',next3: [{title: '皮传感量31'}, {title: '皮传感量32'}, {title: '皮传感量33'}, {title: '皮传感量34'}, {title: '皮传感量35'}]}]}, {title: '皮班组2',next2: [{title: '皮数据线21',next3: [{title: '皮传感量211'}, {title: '皮传感量212'}, {title: '皮传感量213'}, {title: '皮传感量214'}, {title: '皮传感量215'}]}, {title: '皮数据线22',next3: [{title: '皮传感量221'}, {title: '皮传感量222'}, {title: '皮传感量223'}]}, {title: '皮数据线23',next3: [{title: '皮传感量231'}, {title: '皮传感量232'}]}]}]}, {title: '卡丘厂',next1: [{title: '卡班组1',next2: [{title: '卡数据线1',next3: [{title: '卡传感量1'}, {title: '卡传感量2'}, {title: '卡传感量3'}, {title: '卡传感量4'}, {title: '卡传感量5'}]}, {title: '卡数据线2',next3: [{title: '卡传感量21'}, {title: '卡传感量22'}, {title: '卡传感量23'}, {title: '卡传感量24'}]}, {title: '卡数据线3',next3: [{title: '卡传感量31'}, {title: '卡传感量32'}, {title: '卡传感量33'}]}]}, {title: '卡班组2',next2: [{title: '卡数据线21',next3: [{title: '卡传感量211'}, {title: '卡传感量212'}]}, {title: '卡数据线22',next3: [{title: '卡传感量221'}, {title: '卡传感量222'}, {title: '卡传感量223'}]}, {title: '卡数据线23',next3: [{title: '卡传感量231'}, {title: '卡传感量232'}]}]}]}],defaultarray: [[],[],[],[]],multiIndex: [0, 0, 0, 0],},bindMultiPickerChange: function (e) {console.log('picker发送选择改变,携带值为', e.detail.value)this.setData({multiIndex: e.detail.value})},bindMultiPickerColumnChange: function (e) {console.log('修改的列为', e.detail.column, ',(列下标)值为', e.detail.value);var that = this;var defaultarray = that.data.defaultarray,array = that.data.array,multiIndex = that.data.multiIndex// 更改multiIndexmultiIndex[e.detail.column] = e.detail.value// 联动变化defaultarray数组var searchColumn = () => {for (var i = 0; i < array.length; i++) {var arr1 = []; //defaultarray[1]var arr2 = []; //defaultarray[2]var arr3 = []; //defaultarray[3]if (i == multiIndex[0]) {//找到修改的列号ifor (var j = 0; j < array[i].next1.length; j++) {arr1.push(array[i].next1[j].title);if (j == multiIndex[1]) {for (var k = 0; k < array[i].next1[j].next2.length; k++) {arr2.push(array[i].next1[j].next2[k].title);if (k == multiIndex[2]) {for (var g = 0; g < array[i].next1[j].next2[k].next3.length; g++) {arr3.push(array[i].next1[j].next2[k].next3[g].title);}defaultarray[3] = arr3;}}defaultarray[2] = arr2;}}defaultarray[1] = arr1;}};}switch (e.detail.column) {case 0:multiIndex[1] = 0;multiIndex[2] = 0;multiIndex[3] = 0;searchColumn();break;case 1:multiIndex[2] = 0;multiIndex[3] = 0;searchColumn();break;case 2:multiIndex[3] = 0;searchColumn();break;}this.setData({defaultarray: defaultarray,multiIndex: multiIndex});},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {var that = this;var defaultarray = that.data.defaultarrayvar array = that.data.array//给defaultarray里的第1个数组赋值for (var i = 0, len = array.length; i < len; i++) {defaultarray[0].push(array[i].title)}// 给defaultarray里的第2个数组赋值for (var i = 0, len = array[0].next1.length; i < len; i++) {defaultarray[1].push(array[0].next1[i].title)}// 给defaultarray里的第3个数组赋值for (var i = 0, len = array[0].next1[0].next2.length; i < len; i++) {defaultarray[2].push(array[0].next1[0].next2[i].title)}// 给defaultarray里的第4个数组赋值for (var i = 0, len = array[0].next1[0].next2[0].next3.length; i < len; i++) {defaultarray[3].push(array[0].next1[0].next2[0].next3[i].title)}// 渲染that.setData({defaultarray: defaultarray,})//!!!!!!!!要展示到界面的数据一定要用setdata!!!!!!!!!// that.data.defaultarray = defaultarrayconsole.log(defaultarray);console.log(that.data.defaultarray);},
参考文档
微信小程序自定义多列选择器的使用
微信官方文档之picker组件
结束语
继续加油吧~