返回介绍

+ components

发布于 2024-04-18 00:42:19 字数 7715 浏览 0 评论 0 收藏 0

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

components/ 目录是您放置所有 Vue 组件的地方,这些组件随后可以导入到您的页面或其他组件中(了解更多)。

Nuxt 会自动导入 components/ 目录中的所有组件(以及您可能正在使用的任何模块注册的组件)。

bash
| components/
--| TheHeader.vue
--| TheFooter.vue
layouts/default.vue
<template>
  <div>
    <TheHeader />
    <slot />
    <TheFooter />
  </div>
</template>

自定义目录

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

nuxt.config.ts
export default defineNuxtConfig({
  components: [
    { path: '~/components/special-components', prefix: 'Special' },
    '~/components'
  ]
})

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

组件扩展

默认情况下,在 nuxt.config.ts 的扩展键 中指定扩展名的任何文件都被视为组件。 如果需要限制应注册为组件的文件扩展名,可以使用组件目录声明的扩展形式及其 extensions 键:

diff
export default defineNuxtConfig({
  components: [
    {
      path: '~/components',
+     extensions: ['.vue'],
    }
  ]
})

组件名称

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

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

...然后组件的名称将基于其自己的路径目录和文件名,并删除重复的段。 因此,组件的名称将是:

html
<BaseFooButton />

为清楚起见,我们建议组件的文件名与其名称相匹配。 (因此,在上面的示例中,您可以将 Button.vue 重命名为 BaseFooButton.vue。)

如果你想只根据名称而不是路径自动导入组件,那么你需要使用配置对象的扩展形式将 pathPrefix 选项设置为 false

diff
export default defineNuxtConfig({
  components: [
    {
      path: '~/components',
+     pathPrefix: false,
    },
  ],
});

这使用与 Nuxt 2 中使用的相同策略注册组件。例如,~/components/Some/MyComponent.vue 将用作<MyComponent> 而不是<SomeMyComponent>

动态组件

如果你想使用<component :is="someComputedComponent"> 这样的Vue语法,那么你需要使用 Vue 提供的 resolveComponent 助手。

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

<script setup>
const MyButton = resolveComponent('MyButton')
</script>

如果您使用resolveComponent来处理动态组件,请确保除了组件名称之外不要插入任何内容,该名称必须是字符串而不是变量。

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

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

您还可以通过将它们放在 ~/components/global 目录中来选择性地全局注册一些组件。

也可以为每个组件目录设置 global 选项。

动态导入

要动态导入组件(也称为延迟加载组件),您需要做的就是在组件名称中添加Lazy前缀。

layouts/default.vue
<template>
  <div>
    <TheHeader />
    <slot />
    <LazyTheFooter />
  </div>
</template>

如果并不总是需要该组件,这将特别有用。 通过使用 Lazy 前缀,您可以延迟加载组件代码直到合适的时刻,这有助于优化您的 JavaScript 包大小。

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

<script>
export default {
  data() {
    return {
      show: false
    }
  }
}
</script>

显式导入

如果你想或需要绕过 Nuxt 的自动导入功能,你也可以从 #components 显式导入组件。

pages/index.vue
<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>

<script setup>
  import { NuxtLink, LazyMountainsList } from '#components'
  const show = ref(false)
</script>

客户端渲染组件

Nuxt 提供了 <ClientOnly> 组件,目的是只在客户端渲染一个组件。 要仅在客户端导入组件,请在仅客户端插件中注册该组件。

pages/example.vue
<template>
  <div>
    <Sidebar />
    <ClientOnly>
      <!-- 该组件只会在客户端呈现 -->
      <Comments />
    </ClientOnly>
  </div>
</template>

使用插槽作为后备,直到将<ClientOnly>安装在客户端。

pages/example.vue
<template>
  <div>
    <Sidebar />
    <!-- 这会在服务器端呈现“span”元素 -->
    <ClientOnly fallbackTag="span">
      <!-- 该组件只会在客户端呈现 -->
      <Comments />
      <template #fallback>
        <!-- 这将在服务器端呈现 -->
        <p>Loading comments...</p>
      </template>
    </ClientOnly>
  </div>
</template>

客户端专用组件

如果一个组件只打算在客户端呈现,您可以将 .client 后缀添加到您的组件。

bash
| components/
--| Comments.client.vue
pages/example.vue
<template>
  <div>
    <!-- 该组件只会在客户端呈现 -->
    <Comments />
  </div>
</template>

此功能仅适用于 Nuxt 自动导入和 #components 导入。 从它们的真实路径显式导入这些组件不会将它们转换为仅客户端组件。

.client 组件只有在挂载后才会呈现。
要使用 onMounted() 访问呈现的模板,请在 onMounted() 挂钩的回调中添加 await nextTick()

服务端专用组件

.server 组件可以单独使用,也可以与 .client 组件搭配使用。

独立服务端组件

Nuxt 提供了 <DevOnly> 组件来仅在开发期间渲染组件。

内容不会包含在生产构建和 tree-shaking 中。

pages/example.vue
<template>
  <div>
    <Sidebar />
    <DevOnly>
      <!-- 该组件只会在开发期间呈现 -->
      <LazyDebugBar />
    </DevOnly>
  </div>
</template>

客户端回调组件

Nuxt 提供了 <NuxtClientFallback> 组件,用于在 SSR 出现错误时在客户端上渲染其内容。你可以指定 fallbackTag 属性,以便在无法在服务器上渲染时渲染特定的标签。

pages/example.vue
<template>
  <div>
    <Sidebar />
    <!-- 该组件将在客户端呈现 -->
    <NuxtClientFallback fallback-tag="span">
      <Comments />
      <BrokeInSSR />
    </NuxtClientFallback>
  </div>
</template>

库作者

对于库开发者来说,使用 Nuxt 创建自动进行Tree-Shaking和组件注册的 Vue 组件库非常容易。你可以使用components:dirs钩子扩展目录列表,而无需在你的 Nuxt 模块中要求用户进行配置。

假设你有以下目录结构:

bash
| node_modules/
---| awesome-ui/
------| components/
---------| Alert.vue
---------| Button.vue
------| nuxt.js
| pages/
---| index.vue
| nuxt.config.js

然后在 awesome-ui/nuxt.js 中你可以使用 components:dirs 钩子:

ts
import { defineNuxtModule, createResolver } from '@nuxt/kit'

export default defineNuxtModule({
  hooks: {
    'components:dirs': (dirs) => {
      const { resolve } = createResolver(import.meta.url)
      // 将 ./components 目录添加到列表中
      dirs.push({
        path: fileURLToPath(resolve('./components')),
        prefix: 'awesome'
      })
    }
  }
})

就是这样! 现在在您的项目中,您可以将 UI 库作为 Nuxt 模块导入到您的 nuxt.config 文件中:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['awesome-ui/nuxt']
})

...并直接在我们的 pages/index.vue 中使用模块组件(以 awesome- 为前缀):

vue
<template>
  <div>
    My <AwesomeButton>UI button</AwesomeButton>!
    <awesome-alert>Here's an alert!</awesome-alert>
  </div>
</template>

它会仅在使用时自动导入组件,并且在更新 node_modules/awesome-ui/components/ 中的组件时也支持 HMR。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文