在Material-UI的Select组件点击自定义选项时如何唤起Date Picker
实现方案
可以直接在现有代码基础上实现该效果,不需要替换现有Select组件,核心逻辑是监听Select值变化,当选中「自定义」选项时触发日期选择器弹出,具体实现如下:
前置依赖
根据你使用的Material UI版本安装对应日期选择器依赖:
- Material UI v4:
npm install @material-ui/pickers @date-io/date-fns@1.x date-fns - MUI v5:
npm install @mui/x-date-pickers date-fns
核心修改逻辑
- 新增两个状态:分别控制日期选择器的显隐、存储用户选择的自定义日期
- 改造
handleChange事件回调,判断选中值为自定义对应值0时,直接打开日期选择器 - 新增日期选择器组件,配置显隐、选择回调等逻辑
- 可选配置:通过
renderValue属性自定义Select显示内容,当用户选择自定义日期后,Select内直接显示格式化后的日期
完整修改后代码(适配Material UI v4)
import React, {useState} from 'react'; import { makeStyles } from '@material-ui/core/styles'; import InputLabel from '@material-ui/core/InputLabel'; import MenuItem from '@material-ui/core/MenuItem'; import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; import EventSharpIcon from '@material-ui/icons/EventSharp'; // 新增日期选择器相关导入 import DateFnsUtils from '@date-io/date-fns'; import { DatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'; const useStyles = makeStyles((theme) => ({ formControl: { margin: theme.spacing(1), marginBottom: theme.spacing(3), minWidth: 150, }, iconOpen:{ transform:'none' }, })); export default function SimpleSelect() { const classes = useStyles(); const [date, setDate] = useState(''); // 新增状态:控制日期选择器显隐、存储自定义日期 const [openDatePicker, setOpenDatePicker] = useState(false); const [customDate, setCustomDate] = useState(null); const handleChange = (event) => { const selectedValue = event.target.value; // 选中自定义选项时打开日期选择器 if (selectedValue === 0) { setOpenDatePicker(true); return; } setDate(selectedValue); // 切换为非自定义选项时清空已选自定义日期 setCustomDate(null); }; // 自定义日期选择回调 const handleCustomDateChange = (pickedDate) => { setCustomDate(pickedDate); setOpenDatePicker(false); // 此处可添加自定义日期的后续业务逻辑,比如参数提交等 }; return ( <div> <FormControl className={classes.formControl}> <InputLabel id="demo-simple-select-label">Date Created</InputLabel> <Select IconComponent = {EventSharpIcon} labelId="demo-simple-select-label" id="demo-simple-select" value={customDate ? 0 : date} onChange={handleChange} classes={{icon:classes.icon, iconOpen:classes.iconOpen}} MenuProps={{getContentAnchorEl: () => null}} // 自定义Select显示内容 renderValue={(value) => { if (customDate) { // 可根据需求调整日期格式化规则 return new Intl.DateTimeFormat('zh-CN').format(customDate); } const matchedOption = dateOptions.find(opt => opt.value === value); return matchedOption ? matchedOption.date : ''; }} > { dateOptions.map((dateOption) => ( <MenuItem value={dateOption.value} key={dateOption.value}> {dateOption.date} </MenuItem> )) } </Select> </FormControl> {/* 日期选择器组件 */} <MuiPickersUtilsProvider utils={DateFnsUtils}> <DatePicker open={openDatePicker} value={customDate} onChange={handleCustomDateChange} onClose={() => setOpenDatePicker(false)} label="选择自定义日期" // 可自行添加日期格式、禁用日期、弹窗位置等配置 /> </MuiPickersUtilsProvider> </div> ); } const dateOptions = [ { date: 'Today', value: 1, }, { date: 'Yesterday', value: -1, }, { date: 'Last 7 Days', value: -7, }, { date: 'Last 14 Days', value: -14, }, { date: 'Last 30 Days', value: -30, }, { date: 'Last 90 Days', value: -90, }, { date: 'Custom', value: 0, } ]
备选方案
如果你不希望使用官方的日期选择器,也可以替换为任意第三方日期选择组件,核心逻辑保持一致:在选中「自定义」选项时触发对应日期组件的显示即可。如果需要实现和示例图一致的、日期选择器直接挂载在下拉菜单位置的效果,可以调整日期选择器的弹出层锚点为Select组件。
内容的提问来源于stack exchange,提问作者JCastillo
相关产品推荐
相关产品推荐

