🌟 为什么 Next.js 的路由这么香?
在传统 React 项目中,我们要实现多页面跳转,必须手动安装并配置 react-router-dom
,写一堆 Route
、Switch
、Link
,代码繁琐又容易出错。
而 Next.js 内置了强大的文件系统路由(File-based Routing) —— 你只需要创建文件,路由就自动生成了!
✅ 核心思想:文件即路由(File = Route)
比如:
- 创建
pages/about.js
→ 自动拥有/about
路由 - 创建
pages/blog/[id].js
→ 自动支持/blog/123
、/blog/abc
等动态路由
是不是超简单?下面手把手带你实战!
🛠️ 一、准备工作:创建 Next.js 项目
如果你还没项目,先用官方脚手架创建一个:
npx create-next-app@latest my-next-app
# 一路回车,选择默认配置即可
cd my-next-app
npm run dev
项目启动后,默认访问 http://localhost:3000
,看到欢迎页就说明成功了!
📁 二、基础路由:静态页面
Next.js 的路由基于 pages
目录(注意:这是 Pages Router 模式,不是 App Router)。
✅ 规则 1:pages/index.js
对应根路径 /
// pages/index.js
export default function Home() {
return <h1>这是首页!</h1>;
}
访问 http://localhost:3000
→ 显示“这是首页!”
✅ 规则 2:文件名 = 路径名
在 pages
下新建文件:
// pages/about.js
export default function About() {
return <h1>关于我们</h1>;
}
访问 http://localhost:3000/about
→ 自动显示“关于我们”!
💡 不需要配置任何路由表!Next.js 自动扫描
pages
目录生成路由。
✅ 规则 3:文件夹 = 路径层级
创建嵌套路由:
// pages/dashboard/settings.js
export default function Settings() {
return <h1>仪表盘 - 设置页面</h1>;
}
访问 http://localhost:3000/dashboard/settings
→ 路径自动匹配!
🔗 三、页面跳转:用 Link
组件
虽然路由自动生成,但页面之间如何跳转?用 Next.js 提供的 <Link>
组件!
⚠️ 不要用
<a>
标签! 否则会整页刷新,失去 SPA 体验。
示例:首页跳转到关于页
// pages/index.js
import Link from 'next/link';
export default function Home() {
return (
<div>
<h1>首页</h1>
<p>
<Link href="/about">去关于页</Link>
</p>
</div>
);
}
点击链接,页面无刷新跳转,URL 变为 /about
,完美!
🔄 四、动态路由:处理变化的参数
很多场景需要动态路径,比如文章详情页:/post/1
、/post/2
……
✅ 规则:用方括号 [param].js
定义动态段
// pages/post/[id].js
import { useRouter } from 'next/router';
export default function Post() {
const router = useRouter();
const { id } = router.query; // 获取动态参数
return <h1>文章 ID 是:{id}</h1>;
}
现在访问:
http://localhost:3000/post/123
→ 显示 “文章 ID 是:123”http://localhost:3000/post/hello
→ 显示 “文章 ID 是:hello”
📌
useRouter().query
是获取 URL 参数的关键!
🔗 动态路由跳转示例
// pages/index.js
import Link from 'next/link';
export default function Home() {
return (
<div>
<h1>首页</h1>
<ul>
<li><Link href="/post/1">文章1</Link></li>
<li><Link href="/post/2">文章2</Link></li>
<li><Link href="/post/nextjs">文章:Next.js入门</Link></li>
</ul>
</div>
);
}
🧩 五、可选动态参数(Catch-all Segments)
如果路径参数个数不确定,比如 /docs/a/b/c
,可以用 可选动态路由。
1. 必填多段:[...slug].js
// pages/docs/[...slug].js
import { useRouter } from 'next/router';
export default function Docs() {
const router = useRouter();
const { slug } = router.query; // slug 是数组!
return (
<div>
<h1>文档路径:</h1>
<p>{Array.isArray(slug) ? slug.join(' / ') : slug}</p>
</div>
);
}
访问 /docs/guide/install
→ slug = ['guide', 'install']
2. 可选多段:[[...slug]].js
(双括号)
// pages/optional/[[...slug]].js
import { useRouter } from 'next/router';
export default function Optional() {
const router = useRouter();
const { slug } = router.query;
if (!slug) {
return <h1>没有参数</h1>;
}
return <h1>参数:{Array.isArray(slug) ? slug.join('-') : slug}</h1>;
}
/optional
→ 显示“没有参数”/optional/a/b
→ 显示“参数:a-b”
🚀 六、编程式导航:router.push()
除了 <Link>
,你还可以用 JS 代码跳转:
// pages/index.js
import { useRouter } from 'next/router';
export default function Home() {
const router = useRouter();
const goToAbout = () => {
router.push('/about');
};
const goToPost = () => {
router.push('/post/999');
};
return (
<div>
<button onClick={goToAbout}>去关于页(JS跳转)</button>
<button onClick={goToPost}>去文章999</button>
</div>
);
}
常用方法:
router.push('/path')
:跳转(加入历史记录)router.replace('/path')
:替换当前页(不加入历史)router.back()
:返回上一页
🧪 七、实战小项目:简易博客首页 + 详情页
1. 博客首页(列出文章)
// pages/index.js
import Link from 'next/link';
const posts = [
{ id: '1', title: 'Next.js 入门' },
{ id: '2', title: 'React 最佳实践' },
{ id: '3', title: '前端性能优化' },
];
export default function Home() {
return (
<div>
<h1>我的博客</h1>
<ul>
{posts.map(post => (
<li key={post.id}>
<Link href={`/post/${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
</div>
);
}
2. 文章详情页
// pages/post/[id].js
import { useRouter } from 'next/router';
const postContent = {
'1': 'Next.js 是 React 的全栈框架...',
'2': 'React Hooks 让状态管理更简单...',
'3': '懒加载、代码分割提升性能...',
};
export default function Post() {
const router = useRouter();
const { id } = router.query;
const content = postContent[id] || '文章不存在';
return (
<div>
<h1>文章 #{id}</h1>
<p>{content}</p>
<br />
<button onClick={() => router.back()}>返回首页</button>
</div>
);
}
✅ 运行效果:点击文章标题 → 跳转详情页 → 点击返回 → 回到首页!
📝 总结:Next.js 路由 vs React Router
功能 | React Router | Next.js |
---|---|---|
路由定义 | 手写 <Route path="..."> | 文件系统自动生成 |
动态路由 | :id + useParams() | [id].js + router.query |
跳转 | <Link to="..."> | <Link href="..."> |
编程式导航 | useNavigate() | useRouter().push() |
嵌套路由 | 手动嵌套 <Route> | 文件夹结构自动映射 |
✅ Next.js 的优势:零配置、约定优于配置、开发体验极佳!
🌈 小提示:本文基于 Pages Router(
pages/
目录)。Next.js 13+ 新增了 App Router(app/
目录),路由机制略有不同,后续文章会专门讲解。