定义路由

916
2023/06/17 11:55:58

本章将讨论 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 目录

分别为 useruser/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/定义路由 分支。