Skip to content

components

components/ 目录是你放置所有 Vue 组件的地方。

Nuxt3 会自动导入该目录中所有组件(以及您可能使用的任何模块注册的组件)

bash
| components/
--| AppHeader.vue
--| AppFooter.vue
  • app.vue
html
<template>
  <div>
    <AppHeader />
    <NuxtPage />
    <AppFooter />
  </div>
</template>

组件名称

如果您在嵌套目录中有一个组件,例如:

组件名称

  • 依据路径结构(引入名称)
bash

| components/
--| base/
----| foo/
------| Button.vue

那么组件的名称将基于其自身的路径目录和文件名,重复的部分将被删除。因此,组件的名称将是

html
<BaseFooButton />
  • 依据文件名称

如果您希望仅根据组件名称而不是路径自动导入组件,则需要使用扩展形式的配置对象将 pathPrefix 选项设置为 false

js
// nuxt.config.ts
export default defineNuxtConfig({
  components: [
    {
      path: '~/components',
+     pathPrefix: false,
    },
  ],
});

例如,~/components/Some/MyComponent.vue 将可用作 <MyComponent> 而不是 <SomeMyComponent>

动态组件

如果您想使用 Vue 的 <component :is="someComputedComponent"> 语法,您需要使用 Vue 提供的 resolveComponent 辅助函数,或直接从 #components 导入组件并将其传递给 is 属性。

html
<script setup lang="ts">
  import { SomeComponent } from "#components";

  const MyButton = resolveComponent("MyButton");
</script>

<template>
  <component :is="clickable ? MyButton : 'div'" />
  <component :is="SomeComponent" />
</template>

INFO

如果您使用 resolveComponent 处理动态组件,请确保仅插入组件名称,它必须是一个字符串而不是一个变量。

另外,虽然不推荐,但您可以全局注册所有组件,这将为所有组件创建异步块,并使它们在整个应用程序中可用。

js
  export default defineNuxtConfig({
    components: {
+     global: true,
+     dirs: ['~/components']
    },
  })

动态导入

要动态导入组件(也称为延迟加载组件),您只需将 Lazy 前缀添加到组件的名称中。如果组件不总是需要,这特别有用。

通过使用 Lazy 前缀,您可以将组件代码的加载延迟到正确的时机,这有助于优化 JavaScript 包的大小。

html
<script setup>
  const show = ref(false);
</script>

<template>
  <div>
    <h1>Mountains</h1>
    <LazyMountainsList v-if="show" />
    <button v-if="!show" @click="show = true">Show List</button>
  </div>
</template>

直接导入

如果需要绕过 Nuxt 的自动导入功能,您还可以从 #components 直接导入组件。

html
<script setup lang="ts">
  import { NuxtLink, LazyMountainsList } from "#components";

  const show = ref(false);
</script>

<template>
  <div>
    <h1>Mountains</h1>
    <LazyMountainsList v-if="show" />
    <button v-if="!show" @click="show = true">Show List</button>
    <NuxtLink to="/">Home</NuxtLink>
  </div>
</template>

自定义目录

默认情况下,只会扫描 ~/components 目录。如果您想添加其他目录,或更改在该目录的子文件夹中如何扫描组件,您可以将其他目录添加到配置中:

js
// nuxt.config.ts
export default defineNuxtConfig({
  components: [
    // ~/calendar-module/components/event/Update.vue => <EventUpdate />
    { path: "~/calendar-module/components" },

    // ~/user-module/components/account/UserDeleteDialog.vue => <UserDeleteDialog />
    { path: "~/user-module/components", pathPrefix: false },

    // ~/components/special-components/Btn.vue => <SpecialBtn />
    { path: "~/components/special-components", prefix: "Special" },

    // 如果您想要覆盖 `~/components` 的子目录,请确保它是最后一个。
    //
    // ~/components/Btn.vue => <Btn />
    // ~/components/base/Btn.vue => <BaseBtn />
    "~/components",
  ],
});

INFO

任何嵌套的目录都需要首先添加,因为它们按顺序扫描。

ClientOnly 组件

Nuxt 提供了 <ClientOnly> 组件,用于仅在客户端渲染组件。

html
<template>
  <div>
    <Sidebar />
    <ClientOnly>
      <!-- 此组件仅在客户端渲染 -->
      <Comments />
    </ClientOnly>
  </div>
</template>

NuxtClientFallback 组件(重点)

Nuxt 提供了 <NuxtClientFallback> 组件,如果其任何子组件在 SSR 中触发错误,则在客户端渲染其内容。

您可以指定 fallbackTag,以便在服务器端无法渲染时渲染特定的标记。

html
<template>
  <div>
    <Sidebar />
    <!-- 此组件将在客户端渲染 -->
    <NuxtClientFallback fallback-tag="span">
      <Comments />
      <BrokeInSSR />
    </NuxtClientFallback>
  </div>
</template>