约定即配置
本章我们来看一下 `create-next-app` 的选项、目录结构以及 Next.js 的「约定即配置」。定义路由
本章将讨论 Next.js 定义路由的方式,包括:普通路由、动态路由、嵌套路由及嵌套动态路由。布局
本章讨论 Next.js App 路由的布局。相比之前的 Pages 路由,App 路由的布局简单多了:Next.js 会自动调用布局文件。组件与渲染
本章讨论新版 Next.js 中变化最大的部分:组件和渲染。“正在载入”的实现
Next.js 的 App 路由有一个约定:定义 `loading.js`,那么 Next.js 会自动在页面加载中显示这个组件,加载完成之后,自动隐藏该组件。错误处理
本章将讨论 Next.js 的错误处理。
定义路由
本章将讨论 Next.js 定义路由的方式,包括:普通路由、动态路由、嵌套路由及嵌套动态路由。
Next.js 的路由
Next.js 的路由无须单独配置(api除外),只需要在 app 目录下创建子目录即可。
每个路由都有一个访问入口文件,包括 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
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错误。
动态路由
通过创建名为[参数名] 的方式即可创建动态路由:
为了能正常访问,添加 [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]的子目录
分别为 news 和 news/[id] 添加 page.js:
// 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/定义路由 分支。
