您的当前位置:首页正文

微信小程序实现三级联动

2024-11-29 来源:个人技术集锦

该三级联动是借助于vant-weapp组件库中的vant-picker多级联动实现的

我们先看一下效果图

我们都知道官方对vant-picker多级联动组件的介绍并不多,而且还会让初学者看的绞尽脑汁,这个是干什么的啊,这是啥啊,会有很多个疑问,官方组件介绍

如果你还没有用过vant-weapp组件库,请先对该组件库进行一些初步的了解,这是一个很利于大家快速开发微信小程序的一个组件库,笔者大力推荐大家使用。

  • vant-weapp组件库官方使用文档
  • 如果你还不知道怎么引用vant-weapp组件库请看我的博客

下面就贴一下我实现的具体代码

  • index.wxml代码
<van-picker 
show-toolbar 
columns='{{columns}}' 
value-key='name' 
bind:change='onChange' 
bind:confirm='onConfirm' 
bind:cancel='onCancel'/>
  • index.json代码
"usingComponents": {
    "van-picker": "/miniprogram_npm/vant-weapp/picker/index"
 }
  • index.js代码
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])
    }
 },

本文是前端静态实现,如果你想结合后端实现三级联动,请查看我的这篇文章

参考:

显示全文