界面展示
研发初衷
在现代社会中,时间管理和任务规划对于个人和团队的效率和生产力至关重要。随着工作和生活节奏的加快,人们需要一种简单而有效的方式来管理他们的日常计划。为了满足这一需求,我写了一个名为“时空之城计划本”的小项目,它提供了一个直观的界面,用于创建、编辑、删除日常任务事项。
这个项目用react + vite去做的~
设计思路
组件化设计:将整个应用程序拆分为多个组件,每个组件负责特定的功能,如输入框、按钮、列表项等,以提高代码的可维护性和复用性。
状态管理:使用React的useState钩子来管理组件的状态,包括任务列表、新任务文本和选中的任务ID,确保状态的更新是响应式的。
事件处理:为每个交互元素(如按钮、输入框)添加事件处理函数,以响应用户的操作,如添加新任务、删除任务、标记完成等。
样式设计:使用CSS模块来管理组件的样式,确保样式的独立性和可维护性,同时提供良好的用户体验。
步骤
布局
组件结构: - 组件包含一个输入框和两个按钮,用于添加新的待办事项和批量删除已选中的待办事项。 - 里面包含一个无序列表,用于显示所有的待办事项。
一个简洁的tsx布局
放上一点css
初始化数据
这里定义了一个名为 list 的常量,它是一个包含一些初始待办事项的数组。然后,使用 useState 钩子定义了三个状态变量:
plans:用于存储待办事项列表,初始值为list。newPlanText:用于存储新待办事项的文本,初始值为空字符串。selectedPlans:用于存储选中的待办事项的 ID,初始值为空数组。
const DailyPlan: React.FC = () => {
const list = [
{ id: 1, text: '学习React', completed: false },
{ id: 2, text: '学习Vue', completed: true },
{ id: 3, text: '学习Angular', completed: false },
{ id: 4, text: '学习JavaScript', completed: true },
{ id: 5, text: '学习TypeScript', completed: false },
]
const [plans, setPlans] = useState<Plan[]>(list);
const [newPlanText, setNewPlanText] = useState('');
const [selectedPlans, setSelectedPlans] = useState<number[]>([]);
添加事项
- 它检查
newPlanText是否为空或只包含空格。trim()方法用于去除字符串两端的空格,如果去除空格后的字符串不为空,则执行下一步。 - 然后,它创建一个新的
Plan对象newPlan,其中包含当前时间戳作为 ID,newPlanText作为文本内容,以及completed状态为false。 - 使用
setPlans函数更新plans状态,将新的计划对象添加到现有的计划列表中。[...plans, newPlan]是一种扩展运算符的用法,它将现有的plans数组展开,并将newPlan添加到数组的末尾。 - 将
newPlanText重置为空字符串,以便用户可以输入下一个新的计划。
const addPlan = () => {
if (newPlanText.trim() !== '') {
const newPlan: Plan = {
id: Date.now(),
text: newPlanText,
completed: false,
};
setPlans([...plans, newPlan]);
setNewPlanText('');
}
};
删除事项
用过滤的方法,重新给计划Plans去赋值,针对单个和多个的情况
const deletePlan = (id: number) => {
setPlans(plans.filter(plan => plan.id !== id));
};
const deleteSelectedPlans = () => {
setPlans(plans.filter(plan => !selectedPlans.includes(plan.id)));
setSelectedPlans([]);
};
点击勾选框
写一个函数用于在选中的计划项列表中添加或移除指定的计划项,从而实现选择和取消选择的功能。
-
使用
setSelectedPlans更新selectedPlans状态。 -
prevSelectedPlans是当前选中的计划项的 ID 列表。 -
检查
prevSelectedPlans是否包含传入的id:- 如果包含(即该计划项已经被选中),则通过
filter方法移除该id,从而取消选择该计划项。 - 如果不包含(即该计划项未被选中),则通过展开运算符
...将id添加到prevSelectedPlans中,从而选择该计划项。
- 如果包含(即该计划项已经被选中),则通过
const toggleSelectPlan = (id: number) => {
setSelectedPlans(prevSelectedPlans =>
prevSelectedPlans.includes(id)
? prevSelectedPlans.filter(planId => planId !== id)
: [...prevSelectedPlans, id]
);
};
更新事项
-
参数:
id:一个数字,表示要更新的计划项的唯一标识符。newText:一个字符串,表示新的文本内容。
-
逻辑:
- 使用
setPlans更新plans状态。 plans.map遍历当前所有的计划项。- 对于每个计划项
plan,检查其id是否等于传入的id:- 如果相等,表示找到了需要更新的计划项,返回一个新的对象,该对象包含原计划项的所有属性(通过展开运算符
...plan),但text属性被更新为newText。 - 如果不相等,表示该计划项不需要更新,直接返回原计划项。
- 如果相等,表示找到了需要更新的计划项,返回一个新的对象,该对象包含原计划项的所有属性(通过展开运算符
- 使用
这个函数用于根据指定的 id 更新计划项的文本内容。它通过遍历计划项列表,找到匹配的计划项并更新其文本内容,然后返回更新后的计划项列表。
const updatePlanText = (id: number, newText: string) => {
setPlans(plans.map(plan => {
if (plan.id === id) {
return {
...plan,
text: newText,
};
}
return plan;
}));
};
学习感悟
在学习这个demo的过程中,我深刻体会到了React框架的强大和灵活性。
组件化思维:React的组件化思想让代码更加模块化和可重用。DailyPlan组件被设计为一个独立的功能单元,可以轻松地在不同的应用程序中复用。
状态管理:通过useState钩子,我们可以轻松地管理组件的状态。我们使用useState来管理待办事项列表、新计划的文本以及选中的计划。这种方式使得状态的更新和管理变得简单直观。
事件处理:React的事件处理机制非常简洁高效。我们通过onClick和onChange等事件处理函数来响应用户的交互,如添加新计划、删除计划、切换计划的完成状态等。
条件渲染:React的条件渲染允许我们根据组件的状态来决定渲染的内容。使用条件渲染来显示或隐藏批量删除按钮,以及根据计划的完成状态来添加删除线样式。
列表渲染:使用map方法来渲染列表是React中的常见模式。通过plans.map来遍历待办事项列表,并为每个计划渲染一个<li>元素。
函数式编程:React鼓励使用函数式编程的思想,如使用filter和map等高阶函数来处理数组。
另外的就是一点提升空间:在编写DailyPlan组件时,需要考虑代码的性能和可维护性。例如,可以使用useMemo和useCallback来优化性能,使用React.memo或React.PureComponent来避免不必要的渲染。