- 第4章传送门:Next.js 14 最佳实践系列【来自官方标准】-第4章 创建布局和页面 – 掘金
- 切记:只要能坚持下来,对前端领域的认知会有一个质的飞跃。现在是基础阶段,之所谓万丈高楼平地起,地基很重要。
本章节可以学到:
- 如何使用
next/link
组件 - 使用
usePathname()
hook - 导航在Next.js中是如何工作的
为什么优化导航
传统的页面导航使用<a>
标签,这会使整个页面刷新。现在项目左侧侧边栏使用的正是a标签,可以点击一下查看效果.
组件
在Next.js中,可以使用<Link/>
组件在应用程序中页面之间进行链接。<Link />
组件允许使用JavaScript进行客户端导航
在项目中,打开/app/ui/dashboard/nav-links.tsx
,然后导入组件将a标签进行替换,
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 (
// -----替换<a>标签
<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>
);
})}
</>
);
}
再次运行项目查看效果,会看到页面之间的导航没有刷新整个页面。虽然应用程序在部分内容是在服务器上渲染后呈现出来,但是没有刷新整个页面,看起来就想一个WEB应用。那这是为什么呢?
自动代码分割和预取代码
为了改善导航的体验,Next.js自动按照路由段对应用进行代码分割。这与传统的React SPA不同,浏览器在初始加载时加载所有的应用程序代码
按路由拆分代码意味着页面变得孤立。如果某个页面抛出错误,程序的其余部分还可以工作。
此外,在生产环境中,<Link>
组件出现在浏览器的视口中,Next.js就会自动在后台中预取链接路由的代码。当用户点击链接时,目标页面的代码已经在后台加载,这使得页面转换几乎是同时的。
模式:显示活动链接
显示活动的链接指示用户他们所在的页面,那就需要获取当前路由的路径。Next.js提供可以个usePathname()
的钩子。使用这个钩子需要将nav-links.tsx
转换为客户端组件。注意将React的"use client"
指令添加到文件顶部:
'use client';
import {
UserGroupIcon,
HomeIcon,
InboxIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
// ...
接下来获取pathbane
变量数据:
export default function NavLinks() {
const pathname = usePathname();
// ...
}
可以使用clsx
库,将处于活跃状态的链接加上对应的类名。当link.href
与路径名匹配时,链接以蓝色文本和浅蓝色背景形式
'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>
);
})}
</>
);
}
下一章开始与官网有去区别,教大家如何搭建无头CMS,供我们做接口调用。而不是连接数据库,毕竟数据库这种使用的场景目前来说还不成熟(国内)。
原文链接:https://juejin.cn/post/7343606012582461466 作者:多加胡椒