一、技术栈概述
我选择了以下技术栈:
- React:一个用于构建用户界面的 JavaScript 库,以其高效的虚拟 DOM 更新机制著称。
- Tailwind CSS:一个功能类优先的 CSS 框架,允许我们快速构建响应式且美观的界面。
- Vite:一个现代化的前端构建工具,利用浏览器的 ES 模块支持,提供了快速的开发体验。
二、初始化项目
在开始之前,我们首先需要创建一个新的 Vite + React 项目。Vite 是一个现代化的前端构建工具,它利用原生 ES 模块导入,提供了快速的开发体验。以下是初始化项目的命令:
npm create vite@latest my-todo-app -- --template react
cd my-todo-app
npm install
接下来,我们安装 Tailwind CSS,这是一个功能类优先的 CSS 框架,用于快速构建界面:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
初始化 Tailwind CSS 配置文件后,我们需要在 tailwind.config.js 中配置我们的主题和样式偏好。
二、项目文件目录结构解析
package.json:作为项目的核心配置文件,记录了所有依赖包及其版本信息,同时定义了项目运行脚本,如npm run dev用于启动开发服务器。src:项目源代码主目录,包含以下文件和子目录:main.tsx:应用入口文件,负责渲染根组件并启动 React 应用。index.css:全局样式文件,定义了页面布局和基本样式规则。components:自定义组件存放目录,具体包括:TodoList.tsx:待办事项列表组件,负责展示和管理待办事项,包括添加、编辑和删除操作。TodoItem.tsx:单个待办事项组件,展示待办事项详情,并提供编辑和删除功能。
App.tsx:根组件,负责整合TodoList组件,可能包含全局状态管理和页面布局设置。
tailwind.config.js:Tailwind CSS 配置文件,用于自定义主题和样式设置。vite.config.ts:Vite 配置文件,配置开发服务器、构建选项等,确保项目在不同环境下的正常运行。
三、功能实现详细步骤
首先先实现添加新待办事项
- 在
TodoList.tsx中,创建输入框和添加按钮,并绑定事件处理函数。- 输入框允许用户输入待办事项。
- 添加按钮的点击事件将触发
addTodo函数,从输入框获取文本并添加到待办事项列表。
- 用户点击添加按钮或按下回车键后,待办事项被添加至状态管理,输入框清空以准备下一次输入。
确定好要实现的内容后,就可以开始写代码了
代码实现: -- TodoList.jsx
interface Todo {
id: number;
text: string;
}
export const TodoList: React.FC = () => {
const [todos, setTodos] = useState<Todo[]>([]);
const [input, setInput] = useState('');
const addTodo = () => {
if (input.trim()) {
setTodos([...todos, { id: Date.now(), text: input.trim() }]);
setInput('');
}
};
const deleteTodo = (id: number) => {
setTodos(todos.filter(todo => todo.id !== id));
};
const editTodo = (id: number, newText: string) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, text: newText } : todo
));
};
return (
<div className="max-w-xl mx-auto p-6 bg-white rounded-xl shadow-lg">
<h1 className="text-3xl font-bold text-center mb-8 text-gray-800">
Todo List
</h1>
<div className="flex gap-3 mb-6">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
placeholder="Add a new todo..."
className="flex-1 p-3 border-2 border-gray-200 rounded-lg focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all duration-200 outline-none"
/>
<button
onClick={addTodo}
className="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 active:bg-blue-700 transition-colors duration-200 flex items-center gap-2 font-medium"
>
<FaPlus className="text-sm" />
Add
</button>
</div>
<div className="space-y-3">
{todos.length === 0 ? (
<div className="text-center py-8 text-gray-500">
No todos yet. Add one to get started!
</div>
) : (
todos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
onDelete={deleteTodo}
onEdit={editTodo}
/>
))
)}
</div>
</div>
);
};
- 定义 Todo 接口:
- 接口定义了待办事项的属性,包括
id和text。
- 接口定义了待办事项的属性,包括
- TodoList 组件:
TodoList是一个函数组件,使用useState钩子管理待办事项列表和输入框的值。addTodo函数用于添加新的待办事项。deleteTodo函数用于删除特定的待办事项。editTodo函数用于更新待办事项的文本。
然后在TodoItem中实现编辑现有待办事项
- 在
TodoItem.tsx中,为编辑按钮绑定点击事件。 - 点击编辑按钮后,显示编辑框并填充当前待办事项文本。
- 用户修改内容并保存,更新待办事项文本并关闭编辑状态。
代码实现: -- TodoItem.jsx
// src/components/TodoItem.tsx
import React, { useState } from 'react';
import { FaEdit, FaTrash, FaCheck, FaTimes } from 'react-icons/fa';
interface TodoItemProps {
todo: Todo;
onDelete: (id: number) => void;
onEdit: (id: number, newText: string) => void;
}
export const TodoItem: React.FC<TodoItemProps> = ({ todo, onDelete, onEdit }) => {
const [isEditing, setIsEditing] = useState(false);
const [editText, setEditText] = useState(todo.text);
const handleSubmit = () => {
if (editText.trim()) {
onEdit(todo.id, editText);
setIsEditing(false);
}
};
// ...其他代码
};
删除待办事项
- 在
TodoItem.tsx中,为删除按钮绑定点击事件。 - 点击删除按钮,从待办事项列表中移除对应项。
- React 重新渲染列表,更新显示。
代码实现: --TodoItem.jsx
// ...在TodoItem组件内
const handleDelete = () => {
onDelete(todo.id);
};
// ...其他代码
样式设计与交互优化
- 使用 Tailwind CSS 为组件添加样式,确保界面美观。
- 为按钮添加过渡和悬停效果,提升交互体验。
- 隐藏编辑和删除按钮,直到鼠标悬停在待办事项上,保持界面整洁。
- 显示空状态消息,引导用户添加待办事项。
成果展示
经过上面的步骤,一个简单的todolist就完成了