微信小程序自定义picker多列选择器
陆荣涛 时间:2022-10-16
需求说明
- 使用
mpvue
实现自定义的picker
多列选择器。
1、数据结构说明
根据 picker 的数据特征,需要构造一个如下所示的数据结构。data
数组中的三个元素,分别用于渲染 picker 多列选择器的三列数据。能否构造出这个数据结构,直接影响了 picker 多列选择器实现的难易程度。
pid
的作用是用于构建出满足 picker 多列选择器的树状数据结构,要特别注意。
const data = [ // 用于picker第一列的数据源 [ {id:1, name:'A'}, {id:2, name: 'B'} ], // 用于picker第二列的数据源 [ {id: 11, pid: 1, name: 'A1' }, {id: 12, pid: 1, name: 'A2' }, {id: 13, pid: 2, name: 'B1' }, {id: 14, pid: 2, name: 'B2' }, {id: 15, pid: 2, name: 'B3' } ], // 用于picker第三列的数据源 [ {id: 101, pid: 11, name: 'A1-0000000' }, {id: 102, pid: 11, name: 'A1-1111111' }, {id: 103, pid: 12, name: 'A2-0000000' }, {id: 104, pid: 13, name: 'B1-0000000' }, {id: 105, pid: 14, name: 'B2-0000000' }, {id: 106, pid: 15, name: 'B3-0000000' }, ]]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
2、视图代码说明
- picker 是微信小程序内置组件,基础使用方法请参见其官方文档。
mode
属性指定了 picker 是多列选择模式。change
方法监听 picker 发生变化,用于最终获取 picker 的选择结果。columnchange
方法监听 picker 列的变化,这个方法非常重要,在后面写 js 逻辑时要重点使用到它,因为列的变化会导致 picker 视图数据的变化。range
是用于 picker 渲染的动态数据,其语法格式是[[第一列数据], [第二列数据], [第三列数据]]
,在我们这个需求中,除了第一列数据是不变的之外,第二列和第三列数据都会随着父级数据的变化而变化。range-key
用于指定使用哪个字段来渲染 picker 视图。
<template> <picker mode="multiSelector" @change="change" @columnchange="columnChange" :value="idx" :range="list" range-key='name' > <view > <text>你选择的结果是:</text> <text v-text='list[0][idx[0]].name'></text> <text>、</text> <text v-text='list[1][idx[1]].name'></text> <text>、</text> <text v-text='list[2][idx[2]].name'></text> </view> </picker></template>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
3、业务逻辑说明
- 声明式变量
idx
,它是一个数组[第一列数据的索引, 第二列数据的索引, 第三列数据的索引]
,是多列选择器选择结果的索引号列表。 - 声明式变量
list
,它是动态变化的,它用于渲染picker视图,每当columnchange
列变化时,list
都要发生变化,以保证 picker 多列的联动变化。注意和数据源data
区分开来。 - 此 demo 的核心难点是
updatelist(col, idx)
方法的封装,它负责修改list
(注意灵活使用filter
这个数组方法),进而更新 picker 视图的联动变化。 - picker 视图变化分为三种情况:当第一列发生变化时,第二列和第三列都要变化;当第二列变化时,只影响第三列的变化;当第三列变化时,无须修改
list
。
export default { data: function() { return { idx: [0,0,0], // 多列选择结果的索引号列表 list: [] // 用于渲染UI } }, onShow() { this.updatelist(0,0) // 初始化渲染 }, methods: { // 确定picker选择结果时 change(e) { let idx = e.target.value let arr = this.list this.idx = idx console.log('你选择的结果是:', arr[0][idx[0]].name, arr[1][idx[1]].name, arr[2][idx[2]].name) }, // picker的列发生变化时 columnChange(e) { // column列索引(0-第一列) value是列中数组索引 this.updatelist(parseInt(e.target.column), parseInt(e.target.value)) }, // 用于更新picker视图的方法封装 updatelist(col, idx) { let list = this.list // 视图渲染 list[0] = data[0] // picker的第一列数据 // 当第一列变化时 if(col==0) { // 更新第二列的数据 list[1] = data[1].filter(ele=>ele.pid==list[0][idx].id) // 更新第三列的数据 list[2] = data[2].filter(ele=>ele.pid==list[1][0].id) this.idx = [idx,0,0] } // 当第二列变化时 if(col==1) { // 只用更新第三列数据 list[2] = data[2].filter(ele=>ele.pid==list[1][idx].id) this.idx = [this.idx[0], idx, 0] } // 当第三列变化时,不用考虑 // 更新list,更新picker视图 this.list = list } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
*获取千锋教育学习视频资料+源码笔记 ,进学习交流群
请添加下方微信(备注CSDN推荐)
特别声明:本站部分内容收集于互联网是出于更直观传递信息的目的。该内容版权归原作者所有,并不代表本站赞同其观点和对其真实性负责。如该内容涉及任何第三方合法权利,请及时与824310991@qq.com联系,我们会及时反馈并处理完毕。