antd三级级联选择器

1,325 阅读1分钟

写在前面

本组件是基于antd4.x的Select组件,二次封装的三级级联选择器,用法:将数据按照规定的格式传入为组件的props,即可完成选择。

代码如下:

DiSelect3Cas.tsx

/**
 * @author zhangzheyi
 * 3级联动的选择器
 */
import React from "react";
import { Select } from "antd";

const { Option } = Select;
const stPre = { color: "red", display: "inline-block", verticalAlign: "top" };
export default function DiSelect3Cas({
  pre,
  required,
  block,
  title,
  value = [],
  onChange,
  data = [],
  hasEmpty,
  emptyLabel = "不限",
  emptyValue = "",
  extraStyle = {}
}: DiSelect3) {
  const style = { display: "inline-block" };
  if (block) style.display = "block";
  const preView = pre ? <pre style={stPre}>{required ? "* " : "  "}</pre> : "";

  const {
    title: titleSt = { width: "80px", fontWeight: 500 },
    input: inputSt = { width: 120 }
  } = extraStyle;
  const [data0 = [], data1 = [], data2 = []] = data;
  const [value0, value1, value2] = value;

  const onSelectChange = (selectorIdx: number, value: string) => {
    if (onChange) {
      const passedValue = [value0, value1, value2];
      passedValue[selectorIdx] = value;
      if (selectorIdx === 0) {
        passedValue[1] = emptyValue;
        passedValue[2] = emptyValue;
      } else if (selectorIdx === 1) {
        passedValue[2] = emptyValue;
      }
      onChange(passedValue);
    }
  };

  return (
    <div className="difilter-item-wrap" style={style}>
      {preView}
      <span className="func-title" style={titleSt}>
        {title}
      </span>
      <Select
        value={value0}
        size={"small"}
        style={inputSt}
        onChange={(value) => onSelectChange(0, value)}
      >
        {hasEmpty ? (
          <Option key="__hasEmpty__" value={emptyValue}>
            {emptyLabel}
          </Option>
        ) : (
          ""
        )}
        {data0.map((v: any, i: any) => (
          <Option key={i} value={v.value}>
            {v.label}
          </Option>
        ))}
      </Select>
      <Select
        value={value1}
        size={"small"}
        style={inputSt}
        onChange={(value) => onSelectChange(1, value)}
      >
        {hasEmpty ? (
          <Option key="__hasEmpty__" value={emptyValue}>
            {emptyLabel}
          </Option>
        ) : (
          ""
        )}
        {data1.map((v: any, i: any) => (
          <Option key={i} value={v.value}>
            {v.label}
          </Option>
        ))}
      </Select>
      <Select
        value={value2}
        size={"small"}
        style={inputSt}
        onChange={(value) => onSelectChange(2, value)}
      >
        {hasEmpty ? (
          <Option key="__hasEmpty__" value={emptyValue}>
            {emptyLabel}
          </Option>
        ) : (
          ""
        )}
        {data2.map((v: any, i: any) => (
          <Option key={i} value={v.value}>
            {v.label}
          </Option>
        ))}
      </Select>
    </div>
  );
}

interface DiSelect3 {
  pre: boolean;
  required: boolean;
  block: boolean;
  title: string;
  value: string[];
  data: any;
  hasEmpty: boolean;
  emptyLabel: string;
  emptyValue: string;
  extraStyle: {
    title?: {};
    input?: {};
  };
  onChange: any;
}

App.js

import DiSelect3Cas from "./DiSelect3Cas";
import { data } from "./const";
import "./styles.css";
import { useState } from "react";

/**
 *
 * @param {*} data 原始数据
 * @param {*} cateForUi 默认值为['', '', ''], 三个字符串分表代表一二三级级联的id
 */
function computed(data, cateForUi) {
  const [value0, value1] = cateForUi;
  return [data[0], data[1][value0] || [], data[2][value1] || []];
}

export default function App() {
  const [cateForUi, changeUI] = useState(["", "", ""]);
  return (
    <div className="App">
      <DiSelect3Cas
        data={computed(data, cateForUi)}
        title="所属行业"
        hasEmpty={true}
        emptyLabel="请选择"
        onChange={(e) => changeUI(e)}
        value={cateForUi}
      />
    </div>
  );
}

具体演示地址在codesandbox.io/s/diselectc…, 有兴趣的大佬可以去小弟博客刷个访问量zhangzheyi1.com/