跳到主要内容

<NuxtIsland>

Nuxt 提供了 <NuxtIsland> 组件,用于渲染无客户端 JS 的非交互式组件。

渲染 island 组件时,该组件的内容是静态的,因此客户端不会下载任何 JS。

更改 island 组件的 props 会触发重新获取该 island 组件以再次渲染。

应用的全局样式会随响应一起发送。 :

服务端专用组件底层使用了 <NuxtIsland> :

Props

  • name:要渲染的组件名称。
    • 类型string
    • 必填
  • lazy:使组件变为非阻塞。
    • 类型boolean
    • 默认值false
  • props:传给要渲染组件的 props。
    • 类型Record<string, any>
  • source:调用 island 渲染的远程源。
    • 类型string
  • dangerouslyLoadClientComponents:用于从远程源加载客户端组件。
    • 类型boolean
    • 默认值false

远程 island 需要在你的 nuxt.config 中将 experimental.componentIslands 设为 'local+remote'。 :

使用 source prop 从远程服务器渲染内容本质上是有风险的。当你指定一个远程 source 时,你完全信任该服务器会提供安全的 HTML 内容,这些内容将直接渲染到你的应用中。

这类似于对外部内容使用 v-html——远程服务器可以注入任何 HTML,包括潜在的恶意内容。仅对你能完全信任并控制的服务器使用 source

dangerouslyLoadClientComponents prop 控制着额外的一层风险:是否也要从远程源下载并执行客户端组件。即使 dangerouslyLoadClientComponents 被禁用(默认),你仍然在信任远程服务器的 HTML 输出。 :

组件 props 和上下文会作为 GET 查询参数发送,以便启用缓存。查询参数可能会在服务器访问日志、CDN 缓存和 HTTP Referer 请求头中可见。 :

默认情况下,组件 island 会从 ~/components/islands/ 目录扫描。所以 ~/components/islands/MyIsland.vue 组件可以用 <NuxtIsland name="MyIsland" /> 渲染。 :

已知限制

island 与服务端组件中的 useId

每个 island 在服务端自己的 Vue 应用中渲染,因此 Vue 的 useId 计数器会在每个 island 中重新计数。因此,island 内生成的 id 可能与同一页面上其他 island 或应用其余部分生成的 id 冲突。

解决方案:基于 island 上下文 id,从服务端插件中为 island 的 Vue 应用设置一个不同的 idPrefix

plugins/island-id-prefix.server.ts
export default defineNuxtPlugin((nuxtApp) => {
  const islandContext = nuxtApp.ssrContext?.islandContext
  if (islandContext) {
    nuxtApp.vueApp.config.idPrefix = `${islandContext.id}-v`
  }
})
  • 相同的 island 仍会共享相同的 id。 用相同名称、props 和上下文渲染的同一个 island 的两个实例会共享一次服务端渲染(以及 payload 条目),因此它们的 HTML——包括任何 useId 生成的 id——是相同的,用作前缀的 island 上下文 id 也是相同的。这会在 DOM 中产生重复的 id 属性,从而可能破坏 aria-* 引用以及两个实例之间的 <label for> 关联。目前这种情况没有解决方案。
  • useId 在 island 内的交互式组件中不起作用。nuxt-client 属性 加载的组件在服务端于 island 的应用内渲染,但在主客户端应用中进行 hydration,因此 useId 在客户端和服务端返回不同的值,导致 hydration 不匹配。

Slots

如果声明了插槽,可以将插槽传给 island 组件。

每个插槽都是可交互的,因为提供它的是父组件。

某些插槽被 NuxtIsland 保留用于特殊情况。

  • #fallback:指定在 island 加载之前(如果组件是懒加载的)或 NuxtIsland 获取组件失败时渲染的内容。

Ref

  • refresh()
    • 类型() => Promise<void>
    • 描述:通过重新获取来强制重新拉取服务端组件。

Events

  • error
    • 参数
      • error
        • 类型unknown
    • 描述:当 NuxtIsland 获取新 island 失败时触发。