我在这个项目中使用 MUI Date Picker 和 React.js。
我遇到的问题是,我无法可视化应根据当前为虚拟数组的突出显示日期呈现为徽章的 checkIcon。
我无法在文档中找到任何具体信息,并尝试按照视频说明进行操作,但似乎没有任何效果。
import { useState } from 'react';
import TextField from '@mui/material/TextField';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker';
import Badge from '@mui/material/Badge';
import { PickersDay } from '@mui/x-date-pickers/PickersDay';
import CheckIcon from '@mui/icons-material/Check';
export const Calendar = () => {
const [value, setValue] = useState(new Date());
const [highlightedDays, setHighlightedDays] = useState([1, 2, 13]);
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<StaticDatePicker
variant='static'
orientation='portrait'
value={value}
disableFuture
onChange={(newValue) => setValue(newValue)}
renderInput={(params) => {
<TextField {...params} />;
}}
renderDay={(day, _value, DayComponentProps) => {
const isSelected =
!DayComponentProps.outsideCurrentMonth &&
highlightedDays.indexOf(day.getDate()) >= 0;
return (
<Badge
key={day.toString()}
overlap='circular'
badgeContent={isSelected ? <CheckIcon color='red' /> : undefined}
>
<PickersDay {...DayComponentProps} />
</Badge>
)
}}
/>
</LocalizationProvider>
);
};
我检查了 MUI 文档,不知何故,StaticDatePicker 组件中没有任何属性“renderDay”、“renderInput”或“variant”。
相反,您应该使用 slot 属性自定义 StaticDatePicker。您可以在此处查看有关自定义选项的更多信息。
我重构了您的代码以使用 slot 属性,如下所示:
import { useState } from "react";
import {
LocalizationProvider,
PickersDay,
StaticDatePicker,
} from "@mui/x-date-pickers";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
import { Badge } from "@mui/material";
import CheckIcon from '@mui/icons-material/Check';
export const Calendar = () => {
const [value, setValue] = useState(new Date());
const [highlightedDays, setHighlightedDays] = useState([1, 2, 13]);
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<StaticDatePicker
orientation="portrait"
value={value}
disableFuture
onChange={(newValue) => setValue(newValue)}
slots={{
day: (props) => {
const isSelected = !props.outsideCurrentMonth && highlightedDays.indexOf(props.day.getDate()) >= 0;
return (
<Badge
key={props.day.toString()}
overlap="circular"
badgeContent={isSelected ? <CheckIcon htmlColor="red" /> : undefined}
>
<PickersDay {...props} />
</Badge>
);
},
}}
/>
</LocalizationProvider>
);
};
现在一切似乎都正常,第 1、2 和 13 天都用红色勾号正确突出显示。
如果您希望能够使用 DateCalendar 选择不同的日期,这里是解决方案:
import { useState, useEffect, useRef } from "react";
import { LocalizationProvider, PickersDay } from "@mui/x-date-pickers";
import { DateCalendar } from "@mui/x-date-pickers/DateCalendar";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
export const Calendar = () => {
const [value, setValue] = useState<Date | null>(null);
const refDates = useRef<number[]>([]);
const handleSetNewVal = (date: Date | null) => {
if (!date) return;
setValue(date);
const pickedDay = new Date(date).getTime();
const refsDays = refDates.current;
const inxPickedDay = refsDays.indexOf(pickedDay);
if (inxPickedDay >= 0) {
refsDays.splice(inxPickedDay, 1);
} else {
refsDays.push(pickedDay);
}
};
const [pickedDates, setPickedDates] = useState<number[]>([]);
console.log("dates", pickedDates);
useEffect(() => {
setPickedDates(refDates.current);
}, [refDates.current.length]);
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DateCalendar
value={value}
disablePast
onChange={(newValue) => handleSetNewVal(newValue)}
slots={{
day: (props) => {
const dayNumber = new Date(props.day).getTime();
const refDays = refDates.current;
const isSelected = refDays.indexOf(dayNumber) >= 0;
return <PickersDay {...props} selected={isSelected} />;
},
}}
/>
</LocalizationProvider>
);
};
export default Calendar;