react实现考勤表
React 实现考勤表
数据结构设计
考勤表通常需要记录员工、日期和考勤状态。可以使用以下数据结构:
const attendanceData = [
{
id: 1,
name: "张三",
records: [
{ date: "2023-10-01", status: "present" },
{ date: "2023-10-02", status: "absent" }
]
}
];
组件结构
创建三个主要组件:
AttendanceTable:主表格组件EmployeeRow:处理单行员工数据StatusCell:渲染单个考勤状态单元格
function AttendanceTable({ data }) {
return (
<table>
<thead>
<tr>
<th>姓名</th>
<th>日期1</th>
<th>日期2</th>
</tr>
</thead>
<tbody>
{data.map(employee => (
<EmployeeRow key={employee.id} employee={employee} />
))}
</tbody>
</table>
);
}
状态管理
使用React状态管理考勤数据:
const [attendance, setAttendance] = useState(initialData);
const updateStatus = (employeeId, date, newStatus) => {
setAttendance(prev => prev.map(emp => {
if(emp.id === employeeId) {
return {
...emp,
records: emp.records.map(rec =>
rec.date === date ? {...rec, status: newStatus} : rec
)
};
}
return emp;
}));
};
可视化呈现
为不同状态添加样式:
.present { background-color: #a3e635; }
.absent { background-color: #f87171; }
.leave { background-color: #60a5fa; }
完整示例
function StatusCell({ status, onUpdate }) {
const colors = {
present: 'bg-green-300',
absent: 'bg-red-300',
leave: 'bg-blue-300'
};
return (
<td
className={`p-2 ${colors[status]}`}
onClick={onUpdate}
>
{status}
</td>
);
}
function AttendanceApp() {
const [data, setData] = useState(attendanceData);
const handleStatusChange = (employeeId, date) => {
const statusOptions = ['present', 'absent', 'leave'];
const employee = data.find(e => e.id === employeeId);
const currentIndex = statusOptions.indexOf(
employee.records.find(r => r.date === date).status
);
const nextStatus = statusOptions[(currentIndex + 1) % statusOptions.length];
setData(prev => prev.map(emp => {
if(emp.id === employeeId) {
return {
...emp,
records: emp.records.map(rec =>
rec.date === date ? {...rec, status: nextStatus} : rec
)
};
}
return emp;
}));
};
return (
<div className="p-4">
<AttendanceTable
data={data}
onStatusChange={handleStatusChange}
/>
</div>
);
}
扩展功能
- 添加日期选择器动态生成表头
- 实现数据持久化(localStorage或API)
- 添加统计功能计算出勤率
- 支持批量操作和导出功能
这个实现提供了基础考勤表功能,可根据实际需求进一步扩展和完善。







