跳到主要内容

<NuxtLink>

Nuxt 提供了 <NuxtLink> 组件来处理应用内的各类链接。

<NuxtLink> 是 Vue Router 的 <RouterLink> 组件和 HTML 的 <a> 标签的即用替换组件。它会智能判断链接是_内部_还是_外部_链接,并使用可用的优化(预取、默认属性等)相应地渲染。 :

内部路由

在此示例中,我们使用 <NuxtLink> 组件链接到应用的另一个页面。

app/pages/index.vue
<template>
  <NuxtLink to="/about">关于页面</NuxtLink>
</template>
(Renders as) index.html
<!-- (Vue Router & 智能预取) -->
<a href="/about">关于页面</a>

:

向动态路由传递参数

在此示例中,我们将 id 参数传递给路由 ~/pages/posts/[id].vue

app/pages/index.vue
<template>
  <NuxtLink :to="{ name: 'posts-id', params: { id: 123 } }">
    Post 123
  </NuxtLink>
</template>
(Renders as) index.html
<a href="/posts/123">Post 123</a>

:

打开 Nuxt DevTools 中的 Pages 面板,查看路由名称以及它可能接受的参数。 :

当你向 to prop 传入一个对象时,<NuxtLink> 会继承 Vue Router 对查询参数的处理方式。键和值会被自动编码,因此你无需手动调用 encodeURIencodeURIComponent。 :

处理静态文件与跨应用链接

默认情况下,<NuxtLink> 对相对路由使用 Vue Router 的客户端导航。当链接到 /public 目录中的静态文件,或链接到托管在同一域名下的另一个应用时,可能会因为不属于客户端路由而导致意外的 404 错误。在这种情况下,你可以对 <NuxtLink> 使用 external prop 来绕过 Vue Router 的内部路由机制。

external prop 显式表明该链接是外部的。<NuxtLink> 会将链接渲染为标准 HTML <a> 标签。这确保了链接行为正确,绕过 Vue Router 的逻辑并直接指向资源。

链接到静态文件

对于 /public 目录中的静态文件(如 PDF 或图片),使用 external prop 确保链接正确解析。

app/pages/index.vue
<template>
  <NuxtLink
    to="/example-report.pdf"
    external
  >
    下载报告
  </NuxtLink>
</template>

链接到跨应用 URL

当指向同一域名下的不同应用时,使用 external prop 可确保行为正确。

app/pages/index.vue
<template>
  <NuxtLink
    to="/another-app"
    external
  >
    前往另一个应用
  </NuxtLink>
</template>

使用 external prop 或依赖自动处理可确保正确的导航,避免意外的路由问题,并提高与静态资源或跨应用场景的兼容性。

外部路由

在此示例中,我们使用 <NuxtLink> 组件链接到一个网站。

app/app.vue
<template>
  <NuxtLink to="https://nuxtjs.org">
    Nuxt 网站
  </NuxtLink>
  <!-- <a href="https://nuxtjs.org" rel="noopener noreferrer">...</a> -->
</template>

relnoRel 属性

默认情况下,rel 属性 noopener noreferrer 会应用于带有 target 属性的链接,或者绝对链接(例如以 http://https://// 开头的链接)。

  • noopener 解决了旧浏览器中的一个 安全 bug
  • noreferrer 通过不向被链接站点发送 Referer 请求头来提高用户的隐私。

这些默认值对 SEO 没有负面影响,并被认为是 最佳实践

当你需要覆盖此行为时,可以使用 relnoRel props。

app/app.vue
<template>
  <NuxtLink to="https://twitter.com/nuxt_js">
    Nuxt Twitter
  </NuxtLink>
  <!-- <a href="https://twitter.com/nuxt_js" rel="noopener noreferrer">...</a> -->

  <NuxtLink
    to="https://discord.nuxtjs.org"
    rel="noopener"
  >
    Nuxt Discord
  </NuxtLink>
  <!-- <a href="https://discord.nuxtjs.org" rel="noopener">...</a> -->

  <NuxtLink
    to="/about"
    target="_blank"
  >关于页面</NuxtLink>
  <!-- <a href="/about" target="_blank" rel="noopener noreferrer">...</a> -->
</template>

noRel prop 可用于阻止向绝对链接添加默认的 rel 属性。

app/app.vue
<template>
  <NuxtLink
    to="https://github.com/nuxt"
    no-rel
  >
    Nuxt GitHub
  </NuxtLink>
  <!-- <a href="https://github.com/nuxt">...</a> -->
</template>

noRelrel 不能同时使用。若同时设置,rel 会被忽略。 :

预取链接

Nuxt 自动包含智能预取。这意味着它会检测链接何时可见(默认情况下,在视口内或滚动时)并预取这些页面的 JavaScript,以便在用户点击链接时准备就绪。Nuxt 只在浏览器不繁忙时才加载资源,并且在连接离线或仅有 2g 连接时跳过预取。

当使用 custom prop 时,<NuxtLink> 不会自动附加预取处理器。你可以自己在自定义插槽中调用 prefetch

app/pages/index.vue
<NuxtLink to="/about" no-prefetch>
不预取的关于页面
</NuxtLink>

<NuxtLink to="/about" :prefetch="false">
不预取的关于页面
</NuxtLink>

自定义预取触发器

我们在 v3.13.0 之后支持 <NuxtLink> 的自定义预取触发器。你可以使用 prefetchOn prop 来控制何时预取链接。

<template>
  <NuxtLink prefetch-on="visibility">
    当可见时预取(默认)
  </NuxtLink>

  <NuxtLink prefetch-on="interaction">
    当悬停或获得焦点时预取
  </NuxtLink>
</template>
  • visibility:当链接在视口中可见时预取。使用 Intersection Observer API 监视元素与视口的交叉。当元素滚动进入视图时触发预取。
  • interaction:当链接被悬停或获得焦点时预取。这种方式监听 pointerenterfocus 事件,在用户表现出交互意图时主动预取资源。

你也可以使用对象来配置 prefetchOn

<template>
  <NuxtLink :prefetch-on="{ interaction: true }">
    当悬停或获得焦点时预取
  </NuxtLink>
</template>

你可能不希望两者都启用!

<template>
  <NuxtLink :prefetch-on="{ visibility: true, interaction: true }">
    当悬停/聚焦时 - 或当可见时预取
  </NuxtLink>
</template>

这种配置会监视元素进入视口,同时监听 pointerenterfocus 事件。由于两个触发器在不同条件下都能预取相同的资源,这可能导致不必要的资源使用或重复预取。

当使用 custom 时,预取由你的插槽实现控制 v4.5

<template>
  <NuxtLink
    v-slot="{ href, navigate, prefetch, shouldPrefetch }"
    to="/about"
    custom
  >
    <a
      :href="href"
      @click="navigate"
      @pointerenter="shouldPrefetch('interaction') && prefetch()"
      @focus="shouldPrefetch('interaction') && prefetch()"
    >
      关于页面
    </a>
  </NuxtLink>
</template>

启用跨域预取

要启用跨域预取,你可以在 nuxt.config 中设置 crossOriginPrefetch 选项。这将使用 Speculation Rules API 启用跨域预取。

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    crossOriginPrefetch: true,
  },
})

全局禁用预取

也可以为你的应用全局启用/禁用所有链接的预取。

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    defaults: {
      nuxtLink: {
        prefetch: false,
      },
    },
  },
})

Props

当不使用 external 时,<NuxtLink> 支持 Vue Router 所有 RouterLink props

  • to:任何 URL 或来自 Vue Router 的 路由位置对象
  • custom<NuxtLink> 是否应该将其内容包裹在 <a> 元素中。它允许完全控制链接的渲染方式以及点击时的导航行为。与 Vue Router 的 custom prop 工作方式相同
  • exactActiveClass:应用于精确激活链接的类。与 Vue Router 的 exactActiveClass prop 在内部链接上的工作方式相同。默认为 Vue Router 的默认值("router-link-exact-active"
  • activeClass:应用于激活链接的类。与 Vue Router 的 activeClass prop 在内部链接上的工作方式相同。默认为 Vue Router 的默认值("router-link-active"
  • replace:与 Vue Router 的 replace prop 在内部链接上的工作方式相同
  • ariaCurrentValue:应用于精确激活链接的 aria-current 属性值。与 Vue Router 的 ariaCurrentValue prop 在内部链接上的工作方式相同
  • hrefto 的别名。如果与 to 一起使用,href 将被忽略
  • noRel:如果设为 true,不会向外部链接添加 rel 属性
  • external:强制将链接渲染为 <a> 标签,而不是 Vue Router 的 RouterLink
  • prefetch:启用后将预取视口内链接的中间件、布局和 payload(当使用 payloadExtraction 时)。被实验性的 crossOriginPrefetch 配置使用。
  • prefetchOn:允许自定义控制何时预取链接。可选项为 interactionvisibility(默认)。你也可以传入一个对象以获得完全控制,例如:{ interaction: true, visibility: true }。该 prop 仅在 prefetch 启用(默认)且未设置 noPrefetch 时使用。
  • noPrefetch:禁用预取。
  • prefetchedClass:应用于已预取链接的类。

使用 custom prop 时,prefetchprefetchOnprefetchedClass 不会自动附加处理器或类。请使用自定义插槽的 prefetchprefetchedshouldPrefetch 值来实现此行为。 :

Anchor

  • target:应用于链接的 target 属性值。
  • rel:应用于链接的 rel 属性值。对外部链接默认值为 "noopener noreferrer"

默认值可以被覆盖,如果你想更改它们,请参见 覆盖默认值。 :

覆盖默认值

在 Nuxt Config 中

你可以在 nuxt.config 中覆盖一些 <NuxtLink> 的默认值

这些选项未来可能会移到别处,例如移到 app.configapp/ 目录中。 :

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    defaults: {
      nuxtLink: {
        // 默认值
        componentName: 'NuxtLink',
        externalRelAttribute: 'noopener noreferrer',
        activeClass: 'router-link-active',
        exactActiveClass: 'router-link-exact-active',
        prefetchedClass: undefined, // 可以是任何有效的字符串类名
        trailingSlash: undefined, // 可以是 'append' 或 'remove'
        prefetch: true,
        prefetchOn: { visibility: true },
      },
    },
  },
})

自定义链接组件

你可以通过使用 defineNuxtLink 创建自己的链接组件来覆盖 <NuxtLink> 的默认值。

app/components/MyNuxtLink.ts
export default defineNuxtLink({
  componentName: 'MyNuxtLink',
  /* 更多参数见下面的签名 */
})

该组件会以其文件名自动导入,因此你可以像往常一样使用 <MyNuxtLink />,并应用你的新默认值。componentName 仅设置组件的内部名称(如 Vue DevTools 中所示);它不会改变组件在模板中的使用方式。

interface NuxtLinkOptions {
  componentName?: string
  externalRelAttribute?: string
  activeClass?: string
  exactActiveClass?: string
  trailingSlash?: 'append' | 'remove'
  prefetch?: boolean
  prefetchedClass?: string
  prefetchOn?: Partial<{
    visibility: boolean
    interaction: boolean
  }>
}
function defineNuxtLink (options: NuxtLinkOptions): Component {}
  • componentName:组件的内部名称,如 Vue DevTools 中所示。它不会改变模板中使用的名称(那来自组件的文件名)。默认为 NuxtLink
  • externalRelAttribute:应用于外部链接的默认 rel 属性值。默认为 "noopener noreferrer"。设为 "" 可禁用
  • activeClass:应用于激活链接的默认类。与 Vue Router 的 linkActiveClass 选项 工作方式相同。默认为 Vue Router 的默认值("router-link-active"
  • exactActiveClass:应用于精确激活链接的默认类。与 Vue Router 的 linkExactActiveClass 选项 工作方式相同。默认为 Vue Router 的默认值("router-link-exact-active"
  • trailingSlash:用于在 href 中添加或移除尾部斜杠的选项。如果未设置或不匹配有效值 appendremove,将被忽略。
  • prefetch:是否默认预取链接。
  • prefetchOn:用于默认应用哪些预取策略的细粒度控制。
  • prefetchedClass:应用于已预取链接的默认类。
查看示例