微信小程序自定义 picker 多列选择器

2020-08-28  本文已影响0人  夏海峰
效果演示

需求说明:使用 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' },
  ]
]

2、视图代码说明

<template>
  <picker
    mode="multiSelector"
    @change="change"
    @columnchange="columnChange"
    :value="idx"
    :range="list"
    range-key='name'
  >
    <view class="picker">
      <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>

3、业务逻辑说明

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
    }
  }
}

本篇结束!!!

上一篇 下一篇

猜你喜欢

热点阅读