该三级联动是借助于vant-weapp组件库中的vant-picker多级联动实现的
我们先看一下效果图
我们都知道官方对vant-picker多级联动组件的介绍并不多,而且还会让初学者看的绞尽脑汁,这个是干什么的啊,这是啥啊,会有很多个疑问,官方组件介绍
如果你还没有用过vant-weapp组件库,请先对该组件库进行一些初步的了解,这是一个很利于大家快速开发微信小程序的一个组件库,笔者大力推荐大家使用。
下面就贴一下我实现的具体代码
<van-picker
show-toolbar
columns='{{columns}}'
value-key='name'
bind:change='onChange'
bind:confirm='onConfirm'
bind:cancel='onCancel'/>
"usingComponents": {
"van-picker": "/miniprogram_npm/vant-weapp/picker/index"
}
var one = [
{ id: 111, 'name': '杭州' },
{ id: 222, 'name': '宁波' },
]
var two = {
'杭州': [
{ id: 11100, 'name': '国杭州' },
{ id: 22201, 'name': '国宁波' },
],
'宁波': [
{ id: 11102, 'name': '中杭州' },
{ id: 22203, 'name': '中宁波' },
{ id: 33304, 'name': '中温州' },
]
}
var three = {
'国杭州': [
{ id: 1110000, 'name': 'aaa' },
{ id: 2220101, 'name': 'bbb' },
],
'国宁波': [
{ id: 1110102, 'name': 'ccc' },
{ id: 2220103, 'name': 'ddd' },
{ id: 3330104, 'name': 'eee' },
],
'中杭州': [
{ id: 1110205, 'name': 'fff' },
{ id: 2220206, 'name': 'ggg' },
{ id: 3330207, 'name': 'hhh' },
],
'中宁波': [
{ id: 1110308, 'name': 'www' },
{ id: 2220309, 'name': 'ttt' },
{ id: 3330310, 'name': 'yyy' },
],
'中温州': [
{ id: 1110411, 'name': 'jjj' },
{ id: 2220412, 'name': 'kkk' },
{ id: 3330413, 'name': 'ppp' },
]
}
Page({
data: {
columns: [
{
values: one, //可以是数组,或者对象数组
className: 'column1' //选择器的第一列
},
{
values: two[one[0].name], //默认选中two对象中的第一项
className: 'column2', //选择器的第二列
},
{
values: three[two[one[0].name][0].name], //默认选中three对象中的第一项
className: 'column3', //选择器的第三列
}
]
},
onLoad() {
},
onConfirm(event) {
let value = event.detail.value
//将选中的文字和对应的id拿出来使用
wx.showModal({
title: '',
content: '您选中了“' + value[0].name + ',' + value[1].name + ','
+ value[2].name + '”, di为“'+ value[0].id + ',' + value[1].id
+ ',' + value[2].id + '”',
showCancel: false
})
},
onChange(event) {
let picker = event.detail.picker
let value = event.detail.value
let index = event.detail.index
//在change 第一列的时候,动态更改第二列的数据
//setColumnValues是vant自带的实例方法
//第一个参数是列数,从0开始;第二个参数是第二列应该显示的数据
picker.setColumnValues(1, two[value[0].name])
//此处vant-picker有一个bug,当只滑动第一级时,返回的value数据是错误的,需要我们自己根据第二
级计算,去获取第三级数据
if (index == 0) {
picker.setColumnValues(2, three[(two[value[0].name][0]).name])
} else {
picker.setColumnValues(2, three[value[1].name])
}
},
onCancel() {
}
})
以上就是实现功能的全部代码,需要特别注意的就是官方的onChange方法,返回的第二列数据是有问题的,这里需要我们单独处理下,bug如下
我们可以看到,当我们只操作第一列的时候,显然返回的value只有第一列是正确的,其他两列都是错误的,但是这种错误只在change事件出现,在confirm事件并没有这种情况,但是这明显也是也bug,会造成数据不统一问题,废话不多说直接说解决方案。
解决方案:
首先,我们可以清晰的看到,我们是可以获取到用户操作的那一列的下标的,0:第一列,1:第二列,2:第三列,依次类推,那么我们就可以通过下标判断,如果是第一列也就是index是0的情况,说明只滑动了第一列,我们就使用第二列的第一个对象数组key,否则就按照change方法返回的对象数组key,代码展示如下:
onChange(event) {
let picker = event.detail.picker
let value = event.detail.value
let index = event.detail.index
//在change 第一列的时候,动态更改第二列的数据
//setColumnValues是vant自带的实例方法
//第一个参数是列数,从0开始;第二个参数是第二列应该显示的数据
picker.setColumnValues(1, two[value[0].name])
//此处vant-picker有一个bug,当只滑动第一级时,返回的value数据是错误的,需要我们自己根据第二
级计算,去获取第三级数据
if (index == 0) {
picker.setColumnValues(2, three[(two[value[0].name][0]).name])
} else {
picker.setColumnValues(2, three[value[1].name])
}
},
本文是前端静态实现,如果你想结合后端实现三级联动,请查看我的这篇文章
参考: