前言
使用 React 实现一个简单的待办事项列表:用户可以添加、编辑和删除待办事项。这个项目是众多前端实践选题我第一个想做的,因为它不像其它的选题需要探讨总结,我还是更加喜欢亲自写出代码。
I like "Talk is cheap, show me the code"
本是想先让这个 TodoList 的 UI,功能都做的差不多了才开始写这篇文章,但我发现这样不便于记录我在这其中遇到的困难与解决方法。而对于目前大三即将准备考研的我,估计是要放弃 Web 开发一段时间,许多在此次项目学到的东西可能都会被遗忘,所以本篇文章采取实时更新的模式。
前端构建工具
毫无疑问当然是本次青训营的课程重点讲述的前端构建工具 —— Vite
Lesson 11 Vite 知识体系 学习笔记 | 青训营
设计思路
Feature now:
- 通过 editBtn 开启编辑模式,所有文字改动全部在原处进行, 通过再次点击 editBtn 进行保存
- 每条 item 都有一个唯一 id,用于索引删除,用 React 来实现 id 的自增和唯一
Todo:
- 可以导出 TodoItem 为 JSON 文件,可以读取 JSON 文件快速添加 TodoItem
- 增加闹钟提醒
- ……
在做之前,我想了很多的功能,力图想一次做到最好,可是后来发现真的很难,而且对于我目前纯纯小白来说很多我想要的功能都无法实现。我曾困于很久,一直没有coding。
但我发现这对于我一个练习项目,我需要做很多功能,甚至是吸收市面上所有 TodoList 的优秀功能吗?答案肯定是否定的,这也许就是练习,也许就是学生时代的“试错成本比较低吧”。
这个 TodoList 我更倾向于练习,可能有许多用不到的功能(真的会有人通过JSON文件导入item吗?🤣)但是对于我来说这是一件很酷的事,在此之间也学到了许多。
newFunctionUpdateProcess
To be update……
Code
首先是封装 TodoItem 的代码
import React, { useState } from "react";
function TodoItem({itemTitleVar, itemLocationVar, itemTimeVar, editBoolVar}){
const [itemTitle, setItemTitle] = useState(itemTitleVar);
const [itemLocation, setItemLocation]= useState(itemLocationVar);
const [itemTime, setItemTime] = useState(itemTimeVar);
const [editBool, setEditBool] = useState(editBoolVar);
var tempItemTitle = itemTitle;
var tempItemLocation = itemLocation;
var tempItemTime = itemTime;
return (
<div>
<div className="itemTitleDiv">
<strong>itemTitle: </strong>
<h1 className="itemTitleContent" contentEditable={editBool} onInput={(e) => {tempItemTitle = e.target.innerText}} >{itemTitle}</h1>
</div>
<div className="itemLocationDiv">
<strong>itemLocation: </strong>
<div className="itemLocationContent" contentEditable={editBool} onInput={(e) => {tempItemLocation = e.target.innerText}}>{itemLocation}</div>
</div>
<div className="itemTimeDiv">
<strong>itemTime: </strong>
<div className="itemTimeContent" contentEditable={editBool} onInput={(e) => {tempItemTime = e.target.innerText}}>{itemTime}</div>
</div>
<div className="editBoolDiv">
{editBool ? (
<label id="editBtn" onClick={() => {
setEditBool(!editBool);
setItemTitle(tempItemTitle);
setItemLocation(tempItemLocation);
setItemTime(tempItemTime);
}}>✔️</label>
) : (
<label id="editBtn" onClick={() => setEditBool(!editBool)}>🖊️</label>
)}
</div>
<div className="true-state">
<h5>Var Value:</h5><br></br>
{itemTitle}<br></br>
{itemLocation}<br></br>
{itemTime}<br></br>
</div>
</div>
)
}
export default TodoItem;
接下来是渲染 TodoList 的代码
import React, { useState } from 'react';
import TodoItem from './TodoItem';
const TodoList = () => {
const [todos, setTodos] = useState([
{ id: 1, itemTitleVar: 'Buy groceries', itemLocationVar: 'Supermarket', itemTimeVar: '10:00 AM', editBoolVar: true },
{ id: 2, itemTitleVar: 'Finish project', itemLocationVar: 'Home', itemTimeVar: '3:00 PM', editBoolVar: false },
]);
const [nextId, setNextId] = useState(3);
const addTodo = () => {
const newTodo = {
id: nextId,
itemTitleVar: 'Clike 🖊️ to change content',
itemLocationVar: 'Home',
itemTimeVar: '5:00 PM',
editBoolVar: false
};
setTodos([...todos, newTodo]);
setNextId(nextId + 1);
}
const deleteTodo = (id) => {
setTodos(prev => {
return prev.filter(todo => todo.id !== id);
});
}
return (
<div>
<h1>Todo List</h1>
<button id="addTodoBtn" onClick={addTodo}>➕️</button>
{todos.map((todo) => (
<div className="todo-item">
<TodoItem
key={todo.id}
id={todo.id}
itemTitleVar={todo.itemTitleVar}
itemLocationVar={todo.itemLocationVar}
itemTimeVar={todo.itemTimeVar}
editBoolVar={todo.editBoolVar}
/>
<button onClick={() => deleteTodo(todo.id)}>❌</button>
</div>
))}
</div>
);
};
export default TodoList;
最后是样式
.todo-item {
background-color: #ffffff;
border: 1px solid #e0e0e0;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 8px;
padding: 16px;
margin: 16px;
transition: transform 0.2s ease-in-out;
background-color: lightblue;
/* Optional: Hover effect */
&:hover {
transform: translateY(-4px);
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
}
}
#editBtn {
font-size: 2rem;
float: right;
}
body{
background-color: antiquewhite;
}
#addTodoBtn{
background-color: transparent;
border: 1px solid transparent; /* 设置边框为透明 */
}
实际展示效果
功能完好