主题
链接组件
¥Link Component
<Link> 是一个 React 组件,它扩展了 HTML <a> 元素以提供 prefetching 和路由之间的客户端导航。这是在 Next.js 中的路由之间导航的主要方式。
¥<Link> is a React component that extends the HTML <a> element to provide prefetching and client-side navigation between routes. It is the primary way to navigate between routes in Next.js.
基本用法:
¥Basic usage:
tsx
import Link from 'next/link'
export default function Home() {
return <Link href="/dashboard">Dashboard</Link>
}参考
¥Reference
可以将以下 props 传递给 <Link> 组件:
¥The following props can be passed to the <Link> component:
| Prop | 示例 | 类型 | 必需 |
|---|---|---|---|
href | href="/dashboard" | 字符串或对象 | 是 |
as | as="/post/abc" | 字符串或对象 | * |
replace | replace={false} | 布尔值 | * |
scroll | scroll={false} | 布尔值 | * |
prefetch | prefetch={false} | 布尔值 | * |
shallow | shallow={false} | 布尔值 | * |
locale | locale="fr" | 字符串或布尔值 | * |
onNavigate | onNavigate={(e) => {}} | 函数 | * |
需要了解:
<a>标签属性(例如className或target="_blank")可以作为 props 添加到<Link>中,并将传递到底层<a>元素。¥Good to know:
<a>tag attributes such asclassNameortarget="_blank"can be added to<Link>as props and will be passed to the underlying<a>element.
href(必需的)
¥href (required)
要导航到的路径或 URL。
¥The path or URL to navigate to.
tsx
import Link from 'next/link'
// Navigate to /about?name=test
export default function Home() {
return (
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About
</Link>
)
}replace
默认为 false。当 true 时,next/link 会替换当前的历史状态,而不是在 浏览器的历史 堆栈中添加新的 URL。
¥Defaults to false. When true, next/link will replace the current history state instead of adding a new URL into the browser's history stack.
tsx
import Link from 'next/link'
export default function Home() {
return (
<Link href="/dashboard" replace>
Dashboard
</Link>
)
}scroll
默认为 true。Next.js 中 <Link> 的默认滚动行为是保持滚动位置,类似于浏览器处理前后导航的方式。当你导航到新的 页面 时,只要页面在视口中可见,滚动位置就会保持不变。但是,如果页面在视口中不可见,Next.js 将滚动到第一个页面元素的顶部。
¥Defaults to true. The default scrolling behavior of <Link> in Next.js is to maintain scroll position, similar to how browsers handle back and forwards navigation. When you navigate to a new Page, scroll position will stay the same as long as the Page is visible in the viewport. However, if the Page is not visible in the viewport, Next.js will scroll to the top of the first Page element.
当 scroll = {false} 时,Next.js 将不会尝试滚动到第一个 Page 元素。
¥When scroll = {false}, Next.js will not attempt to scroll to the first Page element.
需要了解:Next.js 在管理滚动行为之前检查
scroll: false。如果启用了滚动,它会识别导航的相关 DOM 节点并检查每个顶层元素。所有不可滚动的元素和没有渲染 HTML 的元素都将被绕过,这包括粘性或固定定位的元素,以及不可见的元素(例如使用getBoundingClientRect计算的元素)。Next.js 然后继续遍历同级元素,直到它识别出在视口中可见的可滚动元素。¥Good to know: Next.js checks if
scroll: falsebefore managing scroll behavior. If scrolling is enabled, it identifies the relevant DOM node for navigation and inspects each top-level element. All non-scrollable elements and those without rendered HTML are bypassed, this includes sticky or fixed positioned elements, and non-visible elements such as those calculated withgetBoundingClientRect. Next.js then continues through siblings until it identifies a scrollable element that is visible in the viewport.
tsx
import Link from 'next/link'
export default function Home() {
return (
<Link href="/dashboard" scroll={false}>
Dashboard
</Link>
)
}prefetch
当 <Link /> 组件进入用户的视口(最初或通过滚动)时,会发生预取。Next.js 会在后台预取并加载链接的路由(用 href 表示)和数据,以提高客户端导航的性能。预取仅在生产中启用。
¥Prefetching happens when a <Link /> component enters the user's viewport (initially or through scroll). Next.js prefetches and loads the linked route (denoted by the href) and data in the background to improve the performance of client-side navigation's. Prefetching is only enabled in production.
可以将以下值传递给 prefetch prop:
¥The following values can be passed to the prefetch prop:
true(默认):完整的路由及其数据将被预取。¥
true(default): The full route and its data will be prefetched.false:进入视口时不会进行预取,但鼠标悬停时会发生。如果你还想完全移除悬停时的数据获取,请考虑使用<a>标签或 逐步采用 应用路由,它们也可以禁用悬停时的预获取。¥
false: Prefetching will not happen when entering the viewport, but will happen on hover. If you want to completely remove fetching on hover as well, consider using an<a>tag or incrementally adopting the App Router, which enables disabling prefetching on hover too.
tsx
import Link from 'next/link'
export default function Home() {
return (
<Link href="/dashboard" prefetch={false}>
Dashboard
</Link>
)
}shallow
更新当前页面的路径,无需重新运行 getStaticProps、getServerSideProps 或 getInitialProps。默认为 false。
¥Update the path of the current page without rerunning getStaticProps, getServerSideProps or getInitialProps. Defaults to false.
tsx
import Link from 'next/link'
export default function Home() {
return (
<Link href="/dashboard" shallow={false}>
Dashboard
</Link>
)
}locale
活动语言环境将自动添加到前面。locale 允许提供不同的语言环境。当 false 和 href 必须包含语言环境时,默认行为将被禁用。
¥The active locale is automatically prepended. locale allows for providing a different locale. When false href has to include the locale as the default behavior is disabled.
tsx
import Link from 'next/link'
export default function Home() {
return (
<>
{/* Default behavior: locale is prepended */}
<Link href="/dashboard">Dashboard (with locale)</Link>
{/* Disable locale prepending */}
<Link href="/dashboard" locale={false}>
Dashboard (without locale)
</Link>
{/* Specify a different locale */}
<Link href="/dashboard" locale="fr">
Dashboard (French)
</Link>
</>
)
}as
将显示在浏览器 URL 栏中的路径的可选装饰器。在 Next.js 9.5.3 之前,这用于动态路由,请查看我们的 之前的文档 以了解其工作原理。
¥Optional decorator for the path that will be shown in the browser URL bar. Before Next.js 9.5.3 this was used for dynamic routes, check our previous docs to see how it worked.
当此路径与 href 中提供的路径不同时,将使用之前的 href/as 行为,如 之前的文档 所示。
¥When this path differs from the one provided in href the previous href/as behavior is used as shown in the previous docs.
onNavigate
客户端导航期间调用的事件处理程序。处理程序接收包含 preventDefault() 方法的事件对象,允许你根据需要取消导航。
¥An event handler called during client-side navigation. The handler receives an event object that includes a preventDefault() method, allowing you to cancel the navigation if needed.
tsx
import Link from 'next/link'
export default function Page() {
return (
<Link
href="/dashboard"
onNavigate={(e) => {
// Only executes during SPA navigation
console.log('Navigating...')
// Optionally prevent navigation
// e.preventDefault()
}}
>
Dashboard
</Link>
)
}需要了解:虽然
onClick和onNavigate看起来很相似,但它们的用途不同。onClick会在所有点击事件中执行,而onNavigate仅在客户端导航期间运行。一些主要区别:¥Good to know: While
onClickandonNavigatemay seem similar, they serve different purposes.onClickexecutes for all click events, whileonNavigateonly runs during client-side navigation. Some key differences:
当使用修饰键(
Ctrl/Cmd+ 点击)时,onClick会执行,但onNavigate不会执行,因为 Next.js 会阻止新标签页的默认导航。¥When using modifier keys (
Ctrl/Cmd+ Click),onClickexecutes butonNavigatedoesn't since Next.js prevents default navigation for new tabs.外部 URL 不会触发
onNavigate,因为它仅适用于客户端和同源导航。¥External URLs won't trigger
onNavigatesince it's only for client-side and same-origin navigations.带有
download属性的链接可以在onClick中使用,但不可以在onNavigate中使用,因为浏览器会将链接的 URL 视为下载。¥Links with the
downloadattribute will work withonClickbut notonNavigatesince the browser will treat the linked URL as a download.
示例
¥Examples
以下示例演示了如何在不同场景中使用 <Link> 组件。
¥The following examples demonstrate how to use the <Link> component in different scenarios.
链接到动态路由段
¥Linking to dynamic route segments
对于 动态路由段,使用模板文字来创建链接的路径会很方便。
¥For dynamic route segments, it can be handy to use template literals to create the link's path.
例如,你可以生成指向动态路由 pages/blog/[slug].js 的链接列表。
¥For example, you can generate a list of links to the dynamic route pages/blog/[slug].js
tsx
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}滚动到 id
¥Scrolling to an id
如果你想滚动到导航上的特定 id,你可以在你的 URL 附加 # 哈希链接,或者仅将哈希链接传递给 href 属性。这是可能的,因为 <Link> 渲染到 <a> 元素。
¥If you'd like to scroll to a specific id on navigation, you can append your URL with a # hash link or just pass a hash link to the href prop. This is possible since <Link> renders to an <a> element.
传递 URL 对象
¥Passing a URL Object
Link 也可以接收 URL 对象,并会自动格式化该对象以创建 URL 字符串:
¥Link can also receive a URL object and it will automatically format it to create the URL string:
tsx
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About us
</Link>
</li>
<li>
<Link
href={{
pathname: '/blog/[slug]',
query: { slug: 'my-post' },
}}
>
Blog Post
</Link>
</li>
</ul>
)
}
export default Home以上示例包含指向以下链接:
¥The above example has a link to:
预定义路由:
/about?name=test¥A predefined route:
/about?name=testA 动态路由:
/blog/my-post¥A dynamic route:
/blog/my-post
你可以使用 Node.js URL 模块文档 中定义的每个属性。
¥You can use every property as defined in the Node.js URL module documentation.
替换 URL 而不是推送
¥Replace the URL instead of push
Link 组件的默认行为是将 push 新 URL 放入 history 堆栈中。你可以使用 replace 属性来防止添加新条目,如下例所示:
¥The default behavior of the Link component is to push a new URL into the history stack. You can use the replace prop to prevent adding a new entry, as in the following example:
tsx
import Link from 'next/link'
export default function Home() {
return (
<Link href="/about" replace>
About us
</Link>
)
}禁用滚动到页面顶部
¥Disable scrolling to the top of the page
Link 的默认行为是滚动到页面顶部。当定义了哈希值时,它将滚动到特定的 ID,就像普通的 <a> 标签一样。为防止滚动到顶部/井号,可将 scroll={false} 添加到 Link 中:
¥The default behavior of Link is to scroll to the top of the page. When there is a hash defined it will scroll to the specific id, like a normal <a> tag. To prevent scrolling to the top / hash scroll={false} can be added to Link:
tsx
import Link from 'next/link'
export default function Home() {
return (
<Link href="/#hashid" scroll={false}>
Disables scrolling to the top
</Link>
)
}在代理中预取链接
¥Prefetching links in Proxy
通常将 代理 用于身份验证或涉及将用户重写到不同页面的其他目的。为了使 <Link /> 组件能够通过代理正确预取带有重写规则的链接,你需要同时告知 Next.js 要显示的 URL 和要预取的 URL。这是为了避免不必要的代理请求,从而获取要预取的正确路由。
¥It's common to use Proxy for authentication or other purposes that involve rewriting the user to a different page. In order for the <Link /> component to properly prefetch links with rewrites via Proxy, you need to tell Next.js both the URL to display and the URL to prefetch. This is required to avoid un-necessary fetches to proxy to know the correct route to prefetch.
例如,如果你想要提供一个包含已认证用户和访客视图的 /dashboard 路由,你可以在代理中添加以下内容,将用户重定向到正确的页面:
¥For example, if you want to serve a /dashboard route that has authenticated and visitor views, you can add the following in your Proxy to redirect the user to the correct page:
ts
import { NextResponse } from 'next/server'
export function proxy(request: Request) {
const nextUrl = request.nextUrl
if (nextUrl.pathname === '/dashboard') {
if (request.cookies.authToken) {
return NextResponse.rewrite(new URL('/auth/dashboard', request.url))
} else {
return NextResponse.rewrite(new URL('/public/dashboard', request.url))
}
}
}在这种情况下,你需要在 <Link /> 组件中使用以下代码:
¥In this case, you would want to use the following code in your <Link /> component:
tsx
'use client'
import Link from 'next/link'
import useIsAuthed from './hooks/useIsAuthed' // Your auth hook
export default function Home() {
const isAuthed = useIsAuthed()
const path = isAuthed ? '/auth/dashboard' : '/public/dashboard'
return (
<Link as="/dashboard" href={path}>
Dashboard
</Link>
)
}版本历史记录
¥Version history
| 版本 | 更改 |
|---|---|
v15.4.0 | 将 auto 添加为默认 prefetch 行为的别名。 |
v15.3.0 | 添加 onNavigate API |
v13.0.0 | 不再需要子 <a> 标签。提供 codemod 来自动更新你的代码库。 |
v10.0.0 | 指向动态路由的 href 属性会自动解析,不再需要 as 属性。 |
v8.0.0 | 改进了预取性能。 |
v1.0.0 | next/link 已引入。 |