下拉多选 单选 组件 封装- react material ui

11 阅读1分钟

下拉多选 单选的封装

可以定义是都必填required, label...
主要是实现接口返回字段的下拉多选,一般的字段固定的下拉就很简单
初始化接口返回所有的下拉字段 例如
selectList = ['a','b','c']
接口添加的时候需要收到 {key:value}
changeValue(value, id) 这个是传给组件外,value 对应value ,id对应key(key不适合作为props)

import {
  FormControl, MenuItem,
} from '@mui/material'
import React, { useEffect, useState } from 'react'
import { Theme, useTheme } from '@mui/material/styles'
import Select, { SelectChangeEvent } from '@mui/material/Select'
import { getConstantPool } from '@/api/common'
import './index.scss'
const ITEM_HEIGHT = 48
const ITEM_PADDING_TOP = 8

const MenuProps = {
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      // width: 250,
    },
  },
}
function getStyles(name: string, personName: string[], theme: Theme) {
  return {
    fontWeight:
      personName.indexOf(name) === -1
        ? theme.typography.fontWeightRegular
        : theme.typography.fontWeightMedium,
  }
}

    type Props = {
      columnNameKey: string,
      label?: string,
      id: string,
      labelTitle?: string,
      disabled?: boolean,
      required?: boolean,
      defaultValue?: string,
      multiple?:boolean,
      changeValue: (value: any, key: string, mul?:boolean) => void
    }
export default function CommonSelect(props: Props) {
  const {
    columnNameKey, disabled, required, labelTitle, changeValue, defaultValue, id, multiple,
  } = props
  const [value, setValue] = useState(defaultValue)
  const [constantpoolList, setconstantpoolList] = useState<any[]>([])
  const getConstantApi = async (key: string) => {
    const param = {
      applicationID: 'CRF',
      columnName: key,
      enable: 'Y',
    }
    const res: any = await getConstantPool(param)
    if (res.code === 200) {
      setconstantpoolList(res.data)
    }
  }
  useEffect(() => {
    if (columnNameKey) {
      getConstantApi(columnNameKey)
    }
  }, [columnNameKey])
  useEffect(() => {
    if (defaultValue) {
      setValue(defaultValue)
    }
  }, [defaultValue])
  const handelChange = (event: any) => {
    setValue(event.target.value)
    changeValue(event.target.value, id)
  }
  const theme = useTheme()
  const [personName, setPersonName] = React.useState<string[]>([])

  const handleChange = (event: SelectChangeEvent<typeof personName>) => {
    const {
      target: { value },
    } = event
    setPersonName(
      typeof value === 'string' ? value.split(',') : value
    )    
    changeValue(value.toString(), id)
  }
  const isJSON = (str: any) => {
    try {
      JSON.parse(str)
      return true
    } catch (e) {
      return false
    }
  }
  useEffect(()=>{
    if (defaultValue) {
      if (isJSON(defaultValue)) {
        if (Array.isArray(JSON.parse(defaultValue)) && JSON.parse(defaultValue)) {
          setPersonName(JSON.parse(defaultValue))
        } else {
          setPersonName(
            typeof defaultValue === 'string' ? JSON.parse(defaultValue).toString().split(',') : defaultValue
          )
        }
      } else {
        setPersonName(
          // @ts-ignore
          typeof defaultValue === 'string' ? defaultValue.split(',') : defaultValue
        )
      }
    }
  }, [multiple])
  if (multiple) {
    return  <div>
      <div className="CommonformItem">
        <div className="itemLabel">
          {required && <span className="mustLabel">*</span>}
          {labelTitle}
        </div>
        <div className="itemValue">
          <FormControl sx={{ m: 1, width: 240 }} size="small">
            <Select
              multiple
              disabled={disabled}
              // @ts-ignore
              value={personName || null}
              required={required}
              onChange={handleChange}
              MenuProps={MenuProps}
            >
              {constantpoolList.map((item:any) => (
                <MenuItem
                  key={item.value}
                  value={item.value}
                  style={getStyles(item.value, personName, theme)}
                >
                  {item.value}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </div>
      </div>
    </div>
  }
  return (
    <div>
      <div className="CommonformItem">
        <div className="itemLabel">
          {required && <span className="mustLabel">*</span>}
          {labelTitle}
        </div>
        <div className="itemValue">
          <FormControl sx={{ m: 1, width: 240 }} size="small">
            <Select
              required={required}
              value={value || null}
              disabled={disabled}
              onChange={(e) => {
                handelChange(e)
              }}
            >
              {constantpoolList?.map((item: any) => (
                <MenuItem key={item.value} value={item.value}>
                  {item.value}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </div>
      </div>
    </div>
  )
}