如何在Next.js中链接两个或更多页面的教程

本教程从第一个Next.js教程开始。我们建立了一个包含一个页面的网站:

我想在这个网站上添加第二个页面,一个博客文章列表。它将呈现在/blog目录下,并且暂时只包含一个简单的静态页面,就像我们的第一个index.js组件一样:

保存新文件后,正在运行的npm run dev进程已经能够渲染出页面,而无需重启。

当我们访问URL http://localhost:3000/blog 时,会得到新的页面:

这是终端显示的内容:

现在,URL是/blog取决于文件名以及其在pages文件夹下的位置。

你可以创建一个pages/hey/ho页面,该页面将显示在URL http://localhost:3000/hey/ho 上。

对于URL的目的,文件中的组件名称并不重要。

尝试查看通过服务器加载的页面源代码,你会看到它将/_next/static/development/pages/blog.js列为已加载的捆绑包之一,而不是像主页那样列出/_next/static/development/pages/index.js。这是因为由于自动代码分割,我们不需要捆绑提供主页的捆绑包。只需要提供博客页面的捆绑包。

我们还可以从blog.js中导出一个匿名函数:

export default () => (
 <div>
 <h1>博客</h1>
 </div>
)

或者如果你更喜欢非箭头函数的语法:

export default function() {
 return (
 <div>
 <h1>博客</h1>
 </div>
 )
}

现在,我们有了由index.jsblog.js定义的2个页面,我们可以引入链接。

页面内的普通HTML链接使用a标签完成:

<a href="/blog">博客</a>

但是在Next.js中我们不能这样做。

为什么呢?从技术上讲,当然我们可以,因为这是Web,而且在Web上的事情从不会出错(这就是我们仍然可以使用<marquee>标签的原因)。但是使用Next的主要优点之一是一旦页面被加载,到其他页面的过渡非常快,得益于客户端渲染。

如果你使用普通的a链接:

const Index = () => (
 <div>
 <h1>主页</h1>
 <a href='/blog'>博客</a>
 </div>
)

export default Index

现在打开开发者工具,特别是网络面板。当我们第一次加载http://localhost:3000/时,我们下载了所有页面捆绑包:

现在,如果你点击“保留日志”按钮(以避免清除网络面板),然后点击“博客”链接,将发生以下情况:

我们再次从服务器获取了所有这些JavaScript!但是,如果我们已经获取了这些JavaScript,我们就不需要再次获取了。我们只需要获取blog.js页面捆绑包,因为它是页面中唯一新的捆绑包。

为了解决这个问题,我们使用Next提供的一个名为Link的组件。

我们先导入它:

import Link from 'next/link'

然后我们将Link用于包装我们的链接,就像这样:

import Link from 'next/link'

const Index = () => (
 <div>
 <h1>主页</h1>
 <Link href='/blog'>
 <a>博客</a>
 </Link>
 </div>
)

export default Index

现在,如果你重试之前的操作,你将看到移动到博客页面时只加载了blog.js捆绑包:

并且页面加载得比以前快得多,标签页上通常的加载小图标甚至都没有出现。然而,如你所见,URL已经改变了。这是与浏览器的History API无缝工作。

这就是客户端渲染的实际效果。

如果你现在点击返回按钮,就什么也没有被加载,因为浏览器仍然处于就绪状态,准备加载/index路由的旧index.js捆绑包。这一切都是自动完成的!

这不是处理Next.js中的链接的唯一方法,但我认为这是最简单的方法。