参考:
Next.js 是用于网络的一种 React 框架。一些世界上最大的公司在使用它,它能够借助 React 组件的力量让您创建高质量的网络应用程序。
1、创建项目:
另外注意:pages与app路由存在冲突,如果有app文件夹删除,比如这里创建的就用src下面app文件夹,整体删除,不然构建项目会报错
bash
npx create-next-app@latest todolist
cd todolist
2、创建组件、页面
pages目录下创建index.js
bash
import { useState, useEffect } from 'react'
import TodoForm from '../components/TodoForm'
import TodoList from '../components/TodoList'
export default function Home() {
const [todos, setTodos] = useState([])
useEffect(() => {
const storedTodos = JSON.parse(localStorage.getItem('todos') || '[]')
setTodos(storedTodos)
}, [])
useEffect(() => {
localStorage.setItem('todos', JSON.stringify(todos))
}, [todos])
const addTodo = (text) => {
setTodos([{ text, completed: false }, ...todos])
}
const toggleTodo = (index) => {
const newTodos = [...todos]
newTodos[index].completed = !newTodos[index].completed
setTodos(newTodos)
}
const deleteTodo = (index) => {
const newTodos = todos.filter((_, i) => i !== index)
setTodos(newTodos)
}
return (
<div className="container">
<h1>TodoList</h1>
<TodoForm addTodo={addTodo} />
<TodoList todos={todos} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />
</div>
)
}
pages目录下创建_app.js
bash
import '../styles/globals.css'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
在components目录下创建TodoForm.js
bash
import { useState } from 'react'
export default function TodoForm({ addTodo }) {
const [value, setValue] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
if (!value) return
addTodo(value)
setValue('')
}
return (
<form onSubmit={handleSubmit} className="todo-form">
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Add a todo"
/>
<button type="submit">Add</button>
</form>
)
}
在components目录下创建TodoList.js:
bash
export default function TodoList({ todos, toggleTodo, deleteTodo }) {
return (
<ul className="todo-list">
{todos.map((todo, index) => (
<li key={index} className={`todo-item ${todo.completed ? 'completed' : ''}`}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(index)}
/>
<span>{todo.text}</span>
<button onClick={() => deleteTodo(index)}>Delete</button>
</li>
))}
</ul>
)
}
在styles目录下的globals.css中添加样式
bash
body {
font-family: Arial, sans-serif;
max-width: 500px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
}
.todo-form {
display: flex;
margin-bottom: 20px;
}
.todo-form input {
flex-grow: 1;
padding: 10px;
font-size: 16px;
border: 1px solid #ddd;
border-radius: 4px 0 0 4px;
}
.todo-form button {
padding: 10px 20px;
font-size: 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 0 4px 4px 0;
cursor: pointer;
}
.todo-list {
list-style-type: none;
padding: 0;
}
.todo-item {
display: flex;
align-items: center;
padding: 10px;
background-color: #f9f9f9;
border: 1px solid #ddd;
margin-bottom: 10px;
border-radius: 4px;
}
.todo-item.completed {
text-decoration: line-through;
opacity: 0.6;
}
.todo-item input[type="checkbox"] {
margin-right: 10px;
}
.todo-item button {
margin-left: auto;
background-color: #f44336;
color: white;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
}
2、运行
测试
bash
npm run dev
构建部署
bash
npm run build