前言
本篇是为《React小白自学指南》前三篇的学习量身打造的一个练习项目当然也可以作为完全初学React的学习者们的第一个项目,项目是一个经典的 “待办事项” 。该项目通过创建一个持续的待办事项列表来讲解React中的一些重要特性,如state管理、组件创建和事件处理。通过本教程,学习者将了解React的一些基本概念。本教程中使用的是Vite来快速创建React项目,没有使用 create-react-app , 并使用 Tailwind 来实现轻量且快速的样式设计,使用 Hero Icons 库里面的精美的图标作为按钮的装饰!!!
如果想和更多的小伙伴交流讨论也可以在联系我,我们有一个专门的完全免费的交流群🥰!!!
🧐介绍
1️⃣项目简介
如果你是一个前端新手,或者说React新手的话,那这个精巧的小项目,将非常适合你,作为一个完美的入门项目,它将保持一个简洁但高级的样式,这样我们就可以专注于创建组件、使用和传递状态、处理事件、属性使用等概念!
2️⃣项目展示
🚀创建和初始化项目
- 打开【终端】-> 输入命令
npm i -g pnpm回车,全局安装pnpm工具 -> 安装完成输入命令pnpm -v回车,检查是否安装成功, 如下图:
-
打开【终端】 -> 通过
cd命令进入项目根目录 -> 输入命令pnpm create vite TodoList --template react回车,创建TodoList项目,如下图:
😋小白提示:
- PNPM 是一款 Node.js 包管理工具,相较于 NPM 它可以将多个版本的同一个依赖包安装到一个存储库中,节省磁盘空间和下载时间,并且支持并发安装和自动依赖项解析。
- Vite 是一款基于浏览器原生 ES 模块化开发的构建工具,相较于 create-react-app 它具有具有快速的冷启动、实时更新和高效的构建能力,适用于现代前端框架(如 Vue 和 React)的开发和构建。
-
接着第2步完成后,通过
cd命令进入项目目录 -> 输入命令pnpm i -D tailwindcss postcss autoprefixer回车,在开发环境下安装这三个项目依赖包,如下图:
😋小白提示:这个命令使用 PNPM 包管理器安装 Tailwind CSS、PostCSS 和 Autoprefixer 这三个前端工具,它们 通常用于处理 CSS 样式,其中:
-
Tailwind CSS 是一个功能强大的 CSS 框架,可以快速构建灵活的响应式界面。
-
PostCSS 是一个 CSS 处理器,它可以自动处理浏览器兼容性问题,并提供了许多插件来增强 CSS 的功能。
-
Autoprefixer 是一个 PostCSS 插件,它可以根据浏览器的兼容性自动添加 CSS 前缀。
-
第三步完成后,输入命令
pnpm install @heroicons/react回车,安装React Hero Icons库,如下图:
😋小白提示:
-
React Hero Icons 是一个基于 SVG 图标的 React 组件库,提供了一系列简洁、易于使用的图标,可用于构建现代 Web 应用程序的用户界面设计。
-
输入命令
code ./回车,通过vscode编辑器打开TodoList项目, 接下来我们都将在vscode中操作了。
-
在vscode中打开终端,输入命令
pnpm run dev来启动项目,启动成功后,如下图:
😋小白提示:
-
启动时终端路径要和项目目录保持一致。
自此项目的创建和初始化工作全部完成😎!!!
🔑配置Tailwind
终端中输入命令 pnpm tailwind init -p 回车,会在项目目录下生成两个配置文件 **tailwind.config.js ** 和 postcss.config.js,如下图:
打开 tailwind.config.js 文件,修改 content 属性,如下所示:
/** @type {import('tailwindcss').Config} */
export default {
content: [ "./index.html",
"./src/**/*.{js,ts,jsx,tsx}",], // 修改这部分
theme: {
extend: {},
},
plugins: [],
}
😋小白提示:
-
这个配置的的主要是为项目文件添加所有模板文件的路径。
-
content: 用于指定需要扫描的 HTML、JavaScript 和 TypeScript 文件路径,以便 Tailwind CSS 可以分析这些文件中的 CSS 类名,并生成相应的样式。 -
theme: 用于指定全局的主题样式配置,例如颜色、字体、间距等。在 extend 属性中可以添加自定义的主题配置,这些配置会覆盖默认的配置。 -
plugins: 用于指定需要使用的插件。
打开 src/index.css 文件,删除里面的内容,修改为如下内容:
@tailwind base;
@tailwind components;
@tailwind utilities;
😋小白提示:
-
这个配置的主要目的是将每个 Tailwind 层的 @tailwind 指令添加到您的 ./src/index.css 文件中。
删除 src/App.css 文件并修改 src/App.jsx 删除其中的 import './App.css' 和 return 中的部分代码,如下:
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
function App() {
const [count, setCount] = useState(0)
return (
<div className="App">
接下来要开始构建本项目的html结构了
</div>
)
}
export default App
😋小白提示:
-
删除原来的 App.css 文件是因为,该文件包含了一些默认的样式,这些样式可能与 Tailwind CSS 的样式存在冲突或重复,从而导致应用程序的样式出现异常。因此,在使用 Tailwind CSS 时,通常会删除或清空原来的 CSS 文件,并将所有的样式定义都集中在 index.css 文件中。
-
App.jsx 是 React 应用程序的主组件,它通常包含整个应用程序的布局和路由逻辑,并且将其他子组件作为子元素进行组合,这里删除return中的部分代码是项目创建时默认的 html 结构,现在我们已经不需要它了,我们要开始重新构建我们的html代码了(激动宝子们😋)!!!
🌈构建React组件、结构和样式
接下来我们将自定义两个React组件,分别用来展示 输入待办事项前 和 完成一条待办事项后 !
在开始之前首先在 src 目录下,新建 **components **目录,之后所有的自定义组件都将在该目录下创建🥰。
Let's go!!!
1️⃣构建自定义组件1
该组件是用来渲染 输入待办事项前 的画面以及实现一些相关功能,效果如图所示:
第一步:构建组件的结构和样式
在 components 目录下新建文件 CustonForm.jsx 作为第一个组件,这里所有的CSS的样式都是使用Taliwind的样式类,这里将省略对各种样式的解释(主要是太多了,要不真给你解释一下每个样式的作用🤔!),代码内容为如下:
// 图标导入
import { ArrowRightCircleIcon } from '@heroicons/react/24/solid'
const Form = ({todolist, handleInput, handleSubmit}) => {
return (
<>
<h1 className='text-3xl sm:text-5xl font-bold text-center'>你的 "待办事项" !</h1>
<form className='flex ring-4 rounded-md ring-slate-200 dark:ring-slate-800 focus-within:ring-teal-600 focus-within: ring-offset-4 bg-slate-200 ring-offset-slate-200 dark:ring-offset-slate-800'
onSubmit={handleSubmit}>
<input
type="text"
className='bg-inherit rounded-md text-slate-800 py-2 px-6 focus:outline-none text-xl sm:text-2xl placeholder:text-slate-400 caret-teal-600 appearance-none w-full'
placeholder='请输入'
autoFocus
maxLength="64"
value={todolist} // 设置输入框的值
onInput={handleInput}
/>
<button className='bg-inherit rounded-md text-slate-800 py-2 px-6 focus:outline-none focus:text-teal-600 hover:text-teal-600'>
<ArrowRightCircleIcon className='h-12 w-12 pointer-events-none' />
</button>
</form>
</>
)
}
export default Form
😋小白提示:
-
这是一个 React 组件,用于渲染一个待办事项表单。该表单包括一个输入框和一个提交按钮。表单包含一个带有“你的 '待办事项'!”标题的标签。
-
组件接受三个 props:todolist,handleInput 和 handleSubmit。todolist 是输入框的值,handleInput 是当用户在输入框中输入时调用的函数,handleSubmit 是当用户提交表单时调用的函数。
-
按钮中包含一个向右的箭头图标,该图标从 @heroicons/react 库中导入
-
当用户在输入框中输入时,将触发 onInput 事件,并调用 handleInput 函数。此函数使用输入框的当前值更新 todolist 状态。
-
当用户提交表单时,将触发 onSubmit 事件,并调用 handleSubmit 函数。此函数负责将输入框的当前值添加到待办事项列表中。
-
关于样式的部分,这里给出:Tailwind官网 。
2️⃣构建自定义组件2
该组件是用来渲染 待办事项完成后 的画面以及实现一些相关功能,效果如图所示:
第一步:构建组件的结构和样式
在 components 目录下新建文件 TodoList.jsx 作为第二r个组件,这里同理所有的CSS的样式都不做解释,代码内容为如下:
// 按钮图标导入
import { CheckCircleIcon } from "@heroicons/react/24/solid"
const TodoList = ({ todolist, handleCompletedThing}) => {
return (
<>
<h1 className='text-3xl sm:text-6xl font-bold text-center'>{todolist}</h1>
<button
className='flex items-center space-x-3 text-2xl bg-teal-600 dark:bg-teal-500 px-6 py-3 rounded-md text-slate-200 focus:outline-none focus-visible:ring-4 ring-offset-slate-200 dark:ring-offset-slate-800 hover:opacity-80 transition-opacity disabled:opacity-50'
autoFocus
onClick={handleCompletedThing}
>
<span className='pointer-events-none'>完成</span>
<CheckCircleIcon className='pointer-events-none w-12 h-12'/>
</button>
</>
)
}
export default TodoList
😋小白提示:
-
这是一个 React 组件,用于渲染待办事项列表的内容。该组件包括一个待办事项标题和一个“完成”按钮。
-
组件接受两个 props:todolist 和 handleCompletedThing。todolist 是待办事项的标题,handleCompletedThing 是当用户点击“完成”按钮时调用的函数。
-
按钮中包含一个文字“完成”和一个勾选圆圈图标,该图标从 @heroicons/react 库中导入。
-
当用户点击“完成”按钮时,将触发 onClick 事件,并调用 handleCompletedThing 函数。此函数将设置待办事项的状态为已完成,并将其从待办事项列表中删除。
3️⃣将组件合并到App.jsx组件中
接下来我们将把上面两个自定义组将合并到App.jsx这个主要组件上,并在其中实现各种事件的处理函数,具体代码如下:
// React导入
import { useState } from 'react'
// 自定义组件导入
import CustomForm from './components/CustomForm' // 表单
import TodoList from './components/TodoList' // 点击后特殊显示的表单组件
// 其他库导入(五彩纸屑)
import JSConfetti from 'js-confetti'
const jsConfetti = new JSConfetti()
// 随机获取成功消息
function getSuccessMessage() {
const message = ['恭喜!', '干的漂亮!', '棒棒哒!', '加油,加油!', '冲冲冲!']
return message[Math.floor(Math.random() * message.length)]
}
function App() {
// todolist_state
const [isCompleted, setIsCompleted] = useState(true)
// form_state
const [todolist, setThing] = useState("")
// 处理表单提交事件
const handleSubmit = (e) => {
e.preventDefault(); // 阻止表单的默认行为(即提交刷新)
setIsCompleted(false); // 修改isCompleted的状态
}
// 处理表单输入事件
const handleInput = (e) => {
setThing(e.target.value); // 更新todolist的值
}
// 待办事项输入完成后的事件
const handleCompletedThing = async (e) => {
e.target.setAttribute('disabled', true) // 点击一次后按钮设置为禁用状态
setThing(getSuccessMessage())
await jsConfetti.addConfetti()
e.target.removeAttribute('disabled') // 移除按钮的禁用状态
setThing('') // 清空输入框
setIsCompleted(true) // 回归初始状态
}
return (
<main className='grid place-items-center min-h-screen bg-gradient-to-b from-slate-100 to-slate-200 dark:from-slate-800 dark:to-slate-900 text-slate-900 dark:text-slate-200'>
<div className='grid place-items-center gap-9 m-8'>
{isCompleted && <CustomForm
todolist={todolist}
handleInput={handleInput}
handleSubmit={handleSubmit}
/>}
{
!isCompleted && <TodoList todolist={todolist} handleCompletedThing={handleCompletedThing} />
}
</div>
</main>
)
}
export default App
😋小白提示:
-
这是一个 React 应用程序的主要组件,它包含一个待办事项列表和一个表单组件。用户可以在表单中输入待办事项,然后单击提交按钮,将待办事项添加到列表中。
-
App 组件使用 useState 钩子来管理应用程序的状态。它包含两个状态变量:isCompleted 和 todolist。isCompleted 变量用于跟踪待办事项的状态,如果为 true,则表单组件将显示,否则将显示待办事项列表。todolist 变量用于存储用户输入的待办事项。
-
在 handleSubmit 函数中,它将阻止表单的默认行为,并将 isCompleted 的状态设置为 false,从而显示待办事项列表。
-
在 handleInput 函数中,它将更新 todolist 的值,以便将用户输入的待办事项存储在状态变量中。
-
在 handleCompletedThing 函数中,它将设置按钮为禁用状态,然后使用 getSuccessMessage 函数随机获取一个成功消息,并使用 jsConfetti 库添加五彩纸屑效果。最后,它将清空输入框,将 isCompleted 的状态设置为 true,并将按钮的禁用状态移除。
-
在 render 方法中,根据 isCompleted 变量的值,它将渲染 CustomForm 或 TodoList 组件。CustomForm 组件用于显示待办事项表单,TodoList 组件用于显示待办事项列表和一个特殊的按钮,用户单击该按钮后,将触发 handleCompletedThing 函数。
-
整个 App 组件的功能是:可以添加新的待办事项,可以将待办事项标记为已完成,并且在完成待办事项时显示五彩纸屑效果以及随机的成功消息。
最后
以上就是 “💥一个完美的react入门项目《TodoList---待办事项》”的全部内容,如果理解起来还是有困难的,可以看一看前三篇的内容,也希望大家可以给我 ”点赞、关注、评论“ ,这也是我持续下去的动力,我是多动症男孩(ddboy),因为自己淋过雨,所以想给你们撑把伞的未来前端技术专家,最后希望大家都能通过这个小案例有所收获!!!