react实现日历插件
实现日历插件的核心步骤
安装依赖
使用react-datepicker或@mui/x-date-pickers等现成库快速实现日历功能。例如:
npm install react-datepicker
基础日历组件
通过react-datepicker创建基础日历:
import React, { useState } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
function Calendar() {
const [selectedDate, setSelectedDate] = useState(new Date());
return (
<DatePicker
selected={selectedDate}
onChange={(date) => setSelectedDate(date)}
inline
/>
);
}
自定义样式与功能扩展
样式覆盖 通过CSS覆盖默认样式:
.react-datepicker {
font-family: 'Arial';
}
.react-datepicker__header {
background-color: #f0f0f0;
}
添加日期范围选择 扩展为日期范围选择器:
const [startDate, setStartDate] = useState(new Date());
const [endDate, setEndDate] = useState(null);
<DatePicker
selectsRange
startDate={startDate}
endDate={endDate}
onChange={(update) => {
setStartDate(update[0]);
setEndDate(update[1]);
}}
/>
实现原生日历组件
月份切换逻辑 手动实现月份切换功能:
const [currentMonth, setCurrentMonth] = useState(new Date());
const navigateMonth = (increment) => {
const newMonth = new Date(currentMonth);
newMonth.setMonth(currentMonth.getMonth() + increment);
setCurrentMonth(newMonth);
};
日期渲染网格 生成日期网格的代码示例:
const renderDays = () => {
const days = [];
const firstDay = new Date(
currentMonth.getFullYear(),
currentMonth.getMonth(),
1
).getDay();
// 生成上月末尾几天
const prevMonthDays = new Date(
currentMonth.getFullYear(),
currentMonth.getMonth(),
0
).getDate();
// 生成当前月所有天数
const currentMonthDays = new Date(
currentMonth.getFullYear(),
currentMonth.getMonth() + 1,
0
).getDate();
// 构建日历网格...
return days;
};
高级功能实现
多语言支持
通过date-fns库实现国际化:
import { format, setDefaultOptions } from 'date-fns';
import { es } from 'date-fns/locale';
setDefaultOptions({ locale: es });
// 使用本地化格式
format(new Date(), 'PPPP');
日期禁用逻辑 添加禁用日期规则:
<DatePicker
filterDate={(date) => {
// 禁用周末
return date.getDay() !== 0 && date.getDay() !== 6;
}}
/>
事件标记 在特定日期添加标记:
const dayClassName = (date) => {
return hasEvents(date) ? 'has-event' : null;
};
<DatePicker
dayClassName={dayClassName}
/>
配套CSS:
.has-event::after {
content: '';
display: block;
width: 4px;
height: 4px;
background: red;
border-radius: 50%;
}






