本章将讨论 Next.js 定义路由的方式,包括:普通路由、动态路由、嵌套路由及嵌套动态路由。
Next.js 的路由
路由访问入口文件(「首页」)
每个路由都有一个访问入口文件,包括 app
本身。它的功能类似于 index.html
,就是「默认首页」的意思。
Next.js 的访问入口文件是 page.js
(最次后说明一次,除特殊说明,本专题提及的 .js
文件的文件扩展名可以是 .js/.jsx/.ts/.tsx
)
假如,我们的应用程序的域名是 nextjs.axum.rs
,那么:
- 访问
https://nextjs.axum.rs
时,调用的是app/page.js
- 访问
https://nextjs.axum.rs/about
时,调用的是app/about/page.js
与 Pages 路由的区别:Next.js 的 Pages 路由里,访问入口文件名是
index.js
普通路由
直接在app
目录下创建子目录,该目录的名字就是路由路径。比如:
cd app
mkdir about
- 确保在
app
目录下 - 创建
about
子目录
为了确保能正常访问,还需要加上 page.js
文件:
// app/about/page.js
export default function About() {
return <h1>关于我们</h1>;
}
现在即可通过 /about
访问该路由了!
与 Pages 路由的区别:App 路由只能通过子目录的方式定义,不能通过 about.js
这种文件方式定义
嵌套路由
在 app
目录下,通过创建 路由名/子路由
的层级目录,即可创建嵌套路由:
cd app
mkdir -p user/profile
- 确保在
app
目录下 - 创建
user/profile
目录
分别为 user
和 user/profile
创建 page.js
// app/user/page.js
export default function User() {
return <h1>用户中心</h1>;
}
// app/user/profile/page.js
export default function UserProfile() {
return <h1>用户中心-个人资料</h1>;
}
访问用户中心:/user
访问个人资料:/user/profile
再次提醒,App 路由必须通过创建目录的方式来创建!
错误的示例
我们试着在 user
目录下创建一个 info.js
:
// app/user/info.js
// 错误的示例
// 应该使用 app/user/info/page.js
export default function UserInfo() {
return <h1>用户中心-信息(无法正常访问)</h1>;
}
访问 /user/info
将报404错误。
动态路由
通过创建名为[参数名]
的方式即可创建动态路由:
cd app
mkdir '[page_name]'
- 确保在
app
目录下 - 创建一个
[page_name]
的动态路由
为了能正常访问,添加 [page_name]/page.js
文件:
// app/[page_name]/page.js
export default function PageName() {
return <h1>你访问的是[page_name]路由</h1>;
}
访问:
/feed
:将调用这个动态路由/about
:还是正常调用之前定义的about/page.js
/user
:同/about
一样,调用之前定义的user/page.js
动态路由的参数
本例中,[page_name]
目录的 page_name
是参数名,我们可以拿到它。Next.js 会将它打包到 params
里,并通过 props
传递给它:
// app/[page_name]/page.js
export default function PageName(props) {
return <h1>你访问的是{props.params.page_name}路由</h1>;
}
利用 ES6 的解构语法,可以写成:
// app/[page_name]/page.js
export default function PageName({ params }) {
return <h1>你访问的是{params.page_name}路由</h1>;
}
嵌套动态路由
cd app
mkdir -p 'news/[id]'
- 确保在
app
目录下 - 创建了一个
news
目录,它有一个[id]
的子目录
// app/news/page.js
export default function News() {
return <h1>新闻列表</h1>;
}
// app/news/[id]/page.js
export default function NewsDetail({ params }) {
return <h1>ID为{params.id}的新闻详情</h1>;
}
分别访问:
/news
:调用news/page.js
/news/123
:调用news/[id]/page.js
试一试:访问
/news/456
试试看效果。由于是动态路由,所以本例中的id
值是可以动态变化的,所以你会发现/news/789
也正常工作。
本章代码位于 01/定义路由 分支。