如何在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.js
和blog.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中的链接的唯一方法,但我认为这是最简单的方法。