欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > 【前端】简易化看板

【前端】简易化看板

2024/10/24 9:23:58 来源:https://blog.csdn.net/m0_74120525/article/details/140052375  浏览:    关键词:【前端】简易化看板

【前端】简易化看板

在这里插入图片描述
在这里插入图片描述

项目简介

看板分为三个模块,分别是待办,正在做,已做完三个部分。每个事件采取"卡片"式设计,支持任务间拖拽,删除等操作。

代码

import React, { useState } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';const KanbanBoard = () => {const [tasks, setTasks] = useState({todo: [{ id: '1', title: '设计新的登录页面' },{ id: '2', title: '优化数据库查询' }],doing: [{ id: '3', title: '实现用户认证功能' },{ id: '4', title: '编写单元测试' }],done: [{ id: '5', title: '更新API文档' },{ id: '6', title: '修复登录bug' }]});const [newTasks, setNewTasks] = useState({todo: '',doing: '',done: ''});const onDragStart = (e, id, sourceColumn) => {e.dataTransfer.setData('text/plain', JSON.stringify({ id, sourceColumn }));};const onDragOver = (e) => {e.preventDefault();};const onDrop = (e, targetColumn) => {e.preventDefault();const { id, sourceColumn } = JSON.parse(e.dataTransfer.getData('text'));if (sourceColumn === targetColumn) return;const updatedTasks = { ...tasks };const taskToMove = updatedTasks[sourceColumn].find(task => task.id === id);updatedTasks[sourceColumn] = updatedTasks[sourceColumn].filter(task => task.id !== id);updatedTasks[targetColumn].push(taskToMove);setTasks(updatedTasks);};const addTask = (column) => {if (newTasks[column].trim()) {const updatedTasks = { ...tasks };updatedTasks[column] = [...tasks[column], { id: Date.now().toString(), title: newTasks[column]}];setTasks(updatedTasks);setNewTasks({...newTasks, [column]: ''});}};const deleteTask = (columnId, taskId) => {const updatedTasks = { ...tasks };updatedTasks[columnId] = tasks[columnId].filter(task => task.id !== taskId);setTasks(updatedTasks);};const renderTask = (task, columnId) => (<Card key={task.id}draggableonDragStart={(e) => onDragStart(e, task.id, columnId)}className="mb-2 shadow-sm hover:shadow-md transition-shadow duration-200"><CardContent className="p-3 flex justify-between items-center"><p className="text-sm font-medium text-gray-700 truncate flex-grow mr-2">{task.title}</p><Button onClick={() => deleteTask(columnId, task.id)}className="text-gray-400 hover:text-red-500 transition-colors duration-200 flex-shrink-0"variant="ghost"size="sm">×</Button></CardContent></Card>);const renderColumn = (title, columnId) => (<div className="flex-1 min-w-[250px] bg-gray-50 rounded-lg p-4 border border-gray-200"onDragOver={onDragOver}onDrop={(e) => onDrop(e, columnId)}><h2 className="text-lg font-semibold mb-4 text-gray-700">{title}</h2><div className="space-y-2">{tasks[columnId].map(task => renderTask(task, columnId))}</div><div className="mt-4"><Inputtype="text"value={newTasks[columnId]}onChange={(e) => setNewTasks({...newTasks, [columnId]: e.target.value})}placeholder={`添加任务到 ${title}`}className="mb-2"/><Button onClick={() => addTask(columnId)} className="w-full bg-blue-500 hover:bg-blue-600 text-white">添加任务</Button></div></div>);return (<div className="container mx-auto p-6 bg-white"><header className="text-center mb-8"><h1 className="text-3xl font-bold text-gray-800">SeeBoard</h1></header><div className="flex flex-wrap gap-6">{renderColumn('待办', 'todo')}{renderColumn('进行中', 'doing')}{renderColumn('已完成', 'done')}</div></div>);
};export default KanbanBoard;

效果图

在这里插入图片描述
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com