Next.js 路由系统详解:文件即路由,再也不用手写 `react-router`!

技术解析

🌟 为什么 Next.js 的路由这么香?

在传统 React 项目中,我们要实现多页面跳转,必须手动安装并配置 react-router-dom,写一堆 RouteSwitchLink,代码繁琐又容易出错。

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/installslug = ['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 RouterNext.js
路由定义手写 <Route path="...">文件系统自动生成
动态路由:id + useParams()[id].js + router.query
跳转<Link to="..."><Link href="...">
编程式导航useNavigate()useRouter().push()
嵌套路由手动嵌套 <Route>文件夹结构自动映射

Next.js 的优势零配置、约定优于配置、开发体验极佳!



🌈 小提示:本文基于 Pages Routerpages/ 目录)。Next.js 13+ 新增了 App Routerapp/ 目录),路由机制略有不同,后续文章会专门讲解。


0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动客户端性能优化最佳实践
在用户日益增长、需求不断迭代的背景下,如何保证 APP 发布的稳定性和用户良好的使用体验?本次分享将结合字节跳动内部应用的实践案例,介绍应用性能优化的更多方向,以及 APM 团队对应用性能监控建设的探索和思考。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论