Taro 小程序Picker多列下拉框选择

301 阅读1分钟

小程序picker

多列选择器:mode = multiSelector

属性名类型默认值说明最低版本
rangearray/object array[]mode 为 selector 或 multiSelector 时,range 有效
range-keystring当 range 是一个 Object Array 时,通过 range-key 来指定 Object 中 key 的值作为选择器显示内容
valuearray[]表示选择了 range 中的第几个(下标从 0 开始)
bindchangeeventhandlevalue 改变时触发 change 事件,event.detail = {value}
bindcolumnchangeeventhandle列改变时触发

案例

image.png

  • 数据格式

image.png

import { queryAreaDetailInfo } from "@lw/api";
import store from "@lw/mini/store";
import { init } from "@lw/mini/utils";
import { Picker, View } from "@tarojs/components";
import { useLoad } from "@tarojs/taro";
import { useEffect, useState } from "react";
import "./index.scss";

interface Props {
  onChange?: (e: any) => void;
  status: any;
}
const MultiPicker: React.FC<Props> = ({ onChange, status }) => {
  const [value, setValue] = useState('');
  const [multiIndex, setMultiIndex] = useState<any>([0, 0, 0]);
  const [list, setList] = useState<any>([])
  const [multiArray, setMultiArray] = useState<any>([
    [],
    [],
    [],
  ]);

  useLoad(async () => {
    const { userInfo } = await init();
    await initData(userInfo);
  })
  useEffect(() => {
    if (store?.user?.userInfo) {
      initData(store?.user?.userInfo);
    }

  }, [status])
  const bindMultiPickerChange = (e) => {
    let { value } = e.detail
    let curData = list[value[0]].children[value[1]].children[value[2]]
    setValue(curData.name)
    onChange && onChange(curData);
  }
  const bindMultiPickerColumnChange = (e) => {
    const { column, value } = e.detail;
    let multiArrayTemp = [...multiArray];
    let multiIndexTemp = [...multiIndex];
    multiIndexTemp[column] = value || 0;
    switch (column) {
      case 0:
        switch (multiIndexTemp[1]) {
          case 0:
            multiArrayTemp[2] = multiArrayTemp[2]
            break;
          case 1:
            multiArrayTemp[2] = multiArrayTemp[2]
            break;
        }
        multiIndexTemp.splice(1, 1, 0)
        multiIndexTemp.splice(2, 1, 0)
        processMultiArray(multiIndexTemp[0], multiIndexTemp[1], list)
        break;
      case 1:
        switch (multiIndexTemp[1]) {
          case 0:
            multiArrayTemp[2] = multiArrayTemp[2]
            break;
          case 1:
            multiArrayTemp[2] = multiArrayTemp[2]
            break;
        }
        multiIndexTemp.splice(2, 1, 0);
        break;
    }
    processMultiArray(multiIndexTemp[0], multiIndexTemp[1], list)
    setMultiIndex(multiIndexTemp);
  }
  // 处理多维数组
  const processMultiArray = (m, n, data?) => {
    let multiArrayTemp = [...multiArray]
    let listData = data || [...list]
    multiArrayTemp[0] = listData.map(item => {
      return {
        name: item.name,
        value: item.id
      }
    })
    if (listData.length) {
      if (listData[m].children.length) {
        multiArrayTemp[1] = listData[m].children
        if (listData[m].children[n].children.length) {
          multiArrayTemp[2] = listData[m].children[n].children
        } else {
          multiArrayTemp[2] = []
        }

      } else {
        multiArrayTemp[1] = []
        multiArrayTemp[2] = []
      }
    }

    setMultiArray(multiArrayTemp)
  }

  const initData = async (userInfo) => {

    const { data } = await queryAreaDetailInfo(userInfo.id);
    if (data.data.length > 0) {
      let listTemp: any = []
      listTemp = data.data.map(item => {
        return {
          name: item.name,
          value: item.id,
          children: item.storeInfos.length ? item.storeInfos.map(item => {
            return {
              name: item.name,
              value: item.id,
              children: item.employees.length ? item.employees.map(item => {
                return {
                  name: item.name,
                  value: item.id,
                  id: item.id,
                  code: item.code,
                }
              }) : []
            }
          }) : []
        }
      })
      console.log('@@@listTemp', listTemp)
      processMultiArray(0, 0, listTemp)
      setList(listTemp);
    }
  }
  return (
    <View className="al-multi-picker">
      {
        list.length > 0 ? <Picker mode="multiSelector" rangeKey="name" range={multiArray} value={multiIndex} onColumnChange={bindMultiPickerColumnChange} onChange={bindMultiPickerChange}>
          <View className="al-multi-picker-select">
            <View className={`content ${value ? 'active' : ''}`}>{value || '选择BA'}</View>
            <View className="al-triangle"></View>
          </View>
        </Picker> : ''
      }

    </View>
  )
}
export default MultiPicker;