Next.js 是一個基于 React 的服務端渲染框架,它提供了很多開箱即用的功能,如自動路由、API 路由、靜態生成、增量靜態再生等。本文將帶你一步步創建一個 Next.js 項目,并實現一個簡單的 TodoList 功能。
效果地址
🧱 安裝 Next.js 項目
首先確保你的開發環境已經安裝了 Node.js(推薦版本為 Node.js 18.18 或更高)。
接下來使用 create-next-app
創建一個新的 Next.js 項目:
npm i create-next-app@latest
npx create-next-app@latest nexy-app
在創建過程中,命令行會引導你選擇以下配置項:
√ What is your project named? ... nexy-app
√ Would you like to use TypeScript? ... Yes
√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... Yes
√ Would you like your code inside a `src/` directory? ... Yes
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to use Turbopack for `next dev`? ... No
√ Would you like to customize the import alias (`@/*` by default)? ... Yes
√ What import alias would you like configured? ... @/*
這些選項的作用:
選項 | 說明 |
---|---|
TypeScript | 啟用 TypeScript 支持 |
ESLint | 添加代碼規范支持 |
Tailwind CSS | 使用 Tailwind CSS 作為樣式工具 |
src/ 目錄 | 將代碼結構放在 src 文件夾下 |
App Router | 使用 Next.js 13+ 推薦的 App Router 系統 |
Turbopack | 使用實驗性的快速打包工具 |
導入別名 | 設置模塊路徑別名,方便引用 |
完成后,進入項目目錄并運行開發服務器:
cd nexy-app
npm run dev
📁 Next.js 的文件系統路由機制
Next.js 13+ 引入了基于文件系統的路由系統(File-system based routing),這是其核心特性之一 。
基本規則如下:
- 每個
src/app
下的文件夾代表一個路由段。 - 文件夾中的
page.tsx
是該路由的頁面組件。 - 特殊文件有特定用途:
layout.tsx
:共享布局loading.tsx
:加載狀態組件error.tsx
:錯誤邊界not-found.tsx
:404 頁面
示例結構:
src/
└── app/├── page.tsx → /├── about/│ └── page.tsx → /about├── contact/│ └── page.tsx → /contact
Next.js 會在構建時自動掃描 app
目錄,根據目錄結構生成對應的路由配置,無需手動注冊 。
? 實現一個 TodoList 示例
下面我們將創建一個簡單的 TodoList 頁面,演示如何在 Next.js 中使用客戶端組件和狀態管理。
步驟一:創建頁面文件
在 src/app
目錄下新建一個 todo
文件夾,并在其內部創建 page.tsx
文件:
src/app/todo/page.tsx
步驟二:編寫 TodoList 組件
"use client"; // 表示這是一個客戶端組件import React, { useState } from "react";// 定義 Todo 項的類型
interface TodoItem {id: number;text: string;completed: boolean;
}export default function TodoPage() {const [todos, setTodos] = useState<TodoItem[]>([]);const [inputValue, setInputValue] = useState("");const addTodo = (e: React.FormEvent) => {e.preventDefault();if (inputValue.trim() === "") return;const newTodo: TodoItem = {id: Date.now(),text: inputValue.trim(),completed: false,};setTodos([...todos, newTodo]);setInputValue("");};const toggleTodo = (id: number) => {setTodos(todos.map((todo) =>todo.id === id ? { ...todo, completed: !todo.completed } : todo));};const deleteTodo = (id: number) => {setTodos(todos.filter((todo) => todo.id !== id));};return (<div className="min-h-screen p-8"><div className="max-w-md mx-auto"><h1 className="text-3xl font-bold mb-8 text-center">Todo List</h1>{/* 添加 Todo 的表單 */}<form onSubmit={addTodo} className="mb-8"><div className="flex gap-2"><inputtype="text"value={inputValue}onChange={(e) => setInputValue(e.target.value)}placeholder="添加新的待辦事項..."className="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"/><buttontype="submit"className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500">添加</button></div></form>{/* Todo 列表 */}<ul className="space-y-3">{todos.map((todo) => (<likey={todo.id}className="flex items-center justify-between p-4 bg-white rounded-lg shadow"><div className="flex items-center gap-3"><inputtype="checkbox"checked={todo.completed}onChange={() => toggleTodo(todo.id)}className="w-5 h-5 text-blue-500 rounded focus:ring-blue-500"/><spanclassName={`${todo.completed? "line-through text-gray-500": "text-gray-800"}`}>{todo.text}</span></div><buttononClick={() => deleteTodo(todo.id)}className="text-red-500 hover:text-red-700 focus:outline-none">刪除</button></li>))}</ul>{/* 顯示 Todo 統計信息 */}{todos.length > 0 && (<div className="mt-4 text-sm text-gray-500">總計: {todos.length} 項 | 已完成:{" "}{todos.filter((t) => t.completed).length} 項</div>)}</div></div>);
}
步驟三:訪問頁面
現在你可以訪問 http://localhost:3000/todo 查看這個 TodoList 頁面。
🌟 Next.js 的優勢總結
- 自動路由:無需手動注冊路由,基于文件結構自動生成。
- Server Components 和 Client Components 分離:提升性能和可維護性。
- 集成 Tailwind CSS:輕松構建現代 UI。
- 支持 TypeScript:提供更強的類型安全。
- SSG & SSR 支持:適合 SEO 友好型網站。
- Turbopack / Fast Refresh:更快的開發體驗。