React 日历组件
使用React编写一个日历组件,能够选择月份,添加标记,如标记当天,节日等。
思路
-
先把指定月份的日期全部渲染一遍,也就是先渲染基本的日期,不管当月有多少天,都要渲染出 7 * 5的单元格,如下图所示:
 => {
const {date, tasks, project} = props;
const [days, setDays] = useState([]);
useEffect(() => {
if (date) {
const newDays = [];
let daysOfWeeks = [];
let daysOfWeek = [];
const daysOfMonth = date.daysInMonth();
let startDateOfMonth = date.startOf('month');
let startDateOfNextMonth = date.clone().add(1, 'months').startOf('month');
let startDayOfMonth = date.startOf('month').day();
if (startDayOfMonth === 0) {
startDayOfMonth = 7;
}
for (let i = 0; i < startDayOfMonth - 1; i ++) {
newDays.push({
date: startDateOfMonth.clone().subtract(startDayOfMonth - 1 + i, 'days')
});
}
for (let i = 0; i < daysOfMonth; i ++) {
newDays.push({
date: startDateOfMonth.clone().add(i, 'days')
});
}
for (let i = 0, len = newDays.length; i < 42 - len; i ++) {
newDays.push({
date: startDateOfNextMonth.clone().add(i, 'days')
});
}
for (let i = 0; i < newDays.length; i ++) {
daysOfWeek.push(newDays[i]);
if (daysOfWeek.length === 7) {
daysOfWeeks.push(daysOfWeek);
daysOfWeek = [];
}
}
setDays(daysOfWeeks);
}
}, [date]);
if (!date) {
return <></>;
}
return (
<div>
<table className="table border-top">
<thead>
<tr>
<th scope="col">MON</th>
<th scope="col">TUE</th>
<th scope="col">WED</th>
<th scope="col">THU</th>
<th scope="col">FRI</th>
<th scope="col">SAT</th>
<th scope="col">SUN</th>
</tr>
</thead>
<tbody>
{days.map(daysOfWeek => {
return (
<tr>
{daysOfWeek.map(day => {
const tasks = tasks.filter(task => moment(task.ddl).isSame(day.date, 'day'));
return (
<td>
{day.date.date()}
<div>
{day.date.isSame(moment(), 'day') && (
<span className="badge text-bg-info text-white">
Today
</span>)}
{project && day.date.isSame(project.ddl, 'day') && (
<span className={'badge text-bg-danger text-white'}>ddl</span>
)}
{tasks.map(task => {
return (
<div key={task._id}
className={'rounded-1 text-white mt-1'}>
<span
style={{borderLeft: '5px solid #2dc07c', paddingLeft: '5px', borderRadius: '1px'}}>
{task.homework}
</span>
</div>
)
})}
</div>
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
</div>
)
}