跳到内容

5

页面间导航

在上一章节中,你创建了仪表盘布局和页面。现在,让我们添加一些链接,以便用户在仪表盘路由之间导航。

本章节...

以下是我们将会涵盖的主题

如何使用 next/link 组件。

如何使用 usePathname() 钩子显示当前激活的链接。

Next.js 中的导航工作原理。

为什么要优化导航?

要链接页面,传统上你会使用 <a> HTML 元素。目前,侧边栏链接使用了 <a> 元素,但请注意当你在浏览器中在首页、发票和客户页面之间导航时会发生什么。

你看到了吗?

每次页面导航都会有完整的页面刷新!

在 Next.js 中,你可以使用 <Link /> 组件来链接你的应用中的页面。<Link> 允许你使用 JavaScript 进行 客户端导航

要使用 <Link /> 组件,打开 /app/ui/dashboard/nav-links.tsx,并从 next/link 导入 Link 组件。然后,将 <a> 标签替换为 <Link>

/app/ui/dashboard/nav-links.tsx
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
 
// ...
 
export default function NavLinks() {
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

正如你所看到的,Link 组件类似于使用 <a> 标签,但你使用的是 <Link href="…"> 而不是 <a href="…">

保存你的更改并检查它是否在你的 localhost 中工作。现在你应该能够在页面之间导航而不会看到完整的刷新。虽然你的应用程序的部分内容是在服务器上渲染的,但没有完整的页面刷新,这使其感觉像一个原生 Web 应用。这是为什么呢?

自动代码分割和预取

为了改善导航体验,Next.js 会自动按路由段分割你的应用程序代码。这与传统的 React SPA 不同,在传统的 React SPA 中,浏览器会在初始页面加载时加载你的所有应用程序代码。

按路由分割代码意味着页面变得隔离。如果某个页面抛出错误,应用程序的其余部分仍然可以工作。这也减少了浏览器需要解析的代码量,从而使你的应用程序更快。

此外,在生产环境中,每当 <Link> 组件出现在浏览器视口中时,Next.js 会自动在后台预取链接路由的代码。当用户点击链接时,目标页面的代码已经加载在后台,这使得页面过渡几乎是瞬间的!

了解更多关于 导航工作原理 的信息。

一个常见的 UI 模式是显示一个激活链接,以指示用户当前所在的页面。要做到这一点,你需要从 URL 获取用户当前的路径。Next.js 提供了一个名为 usePathname() 的钩子,你可以使用它来检查路径并实现此模式。

由于 usePathname() 是一个 React 钩子,你需要将 nav-links.tsx 转换为客户端组件。在文件顶部添加 React 的 "use client" 指令,然后从 next/navigation 导入 usePathname()

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
 
// ...

接下来,在你的 <NavLinks /> 组件内部,将路径赋值给一个名为 pathname 的变量

/app/ui/dashboard/nav-links.tsx
export default function NavLinks() {
  const pathname = usePathname();
  // ...
}

注意nav-links.tsx 不是 Next.js 的特殊文件——你可以随意命名它。如果你重命名它,请确保相应地更新导入语句。

你可以使用 CSS 样式 章节中介绍的 clsx 库,在链接处于激活状态时有条件地应用类名。当 link.hrefpathname 匹配时,链接应以蓝色文本和浅蓝色背景显示。

这是 nav-links.tsx 的最终代码

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
 
// ...
 
export default function NavLinks() {
  const pathname = usePathname();
 
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className={clsx(
              'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
              {
                'bg-sky-100 text-blue-600': pathname === link.href,
              },
            )}
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

保存并检查你的 localhost。现在你应该看到激活的链接以蓝色突出显示。

你已完成章节5

你已经学习了如何在页面之间链接以及在 Next.js 中利用客户端导航。

下一章

6:设置你的数据库

让我们创建一个数据库来开始获取真实数据!