Nuxt3【组件】2024最新版(含异步组件、动态组件、客户端组件、内置组件、添加组件库等)

Nuxt 中有一些特殊的组件用法

异步组件

加 Lazy 前缀即可

<LazyMountainsList v-if="show" />

动态组件

方式一:使用 Vue 提供的 resolveComponent 函数

<script setup lang="ts">
const Demo1 = resolveComponent("Demo1");
const Demo2 = resolveComponent("Demo2");
const SomeComponent = ref(Demo1);

function change() {
  SomeComponent.value = Demo2;
}
</script>
<template>
  <div>
    <button @click="change">切换到范例组件2</button>
    <component :is="SomeComponent" />
  </div>
</template>

方式二:从 #components 中导入组件(会绕过 Nuxt 的自动导入功能)

<script setup lang="ts">
import { Demo1, Demo2 } from "#components";

const SomeComponent = ref(Demo1);

function change() {
  SomeComponent.value = Demo2;
}
</script>
<template>
  <div>
    <button @click="change">切换到范例组件2</button>
    <component :is="SomeComponent" />
  </div>
</template>

客户端组件

仅在客户端渲染的组件

方式一:在组件名后添加 .client 后缀

Comments.client.vue
  • 若显式导入这些组件( 从 #components 导入除外),则仍是服务端渲染
  • .client 组件仅在挂载后才会渲染。要在 onMounted() 的回调中访问渲染的模板,请在 onMounted() 钩子的回调中添加 await nextTick()。

方式二:使用 Nuxt3 内置的 <ClientOnly> 组件

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

可按下方代码添加服务端渲染的内容 ( 如客户端完成渲染前,显示正在加载 )

<template>
  <div>
    <Sidebar />
    <!-- 这将在服务器端渲染 "span" 元素 -->
    <ClientOnly fallbackTag="span">
      <!-- 此组件仅在客户端渲染 -->
      <Comments />
      <template #fallback>
        <!-- 这将在服务器端渲染 -->
        <p>Loading comments...</p>
      </template>
    </ClientOnly>
  </div>
</template>

#fallback 是插槽写法,也可用 fallback 属性

<template>
  <div>
    <Sidebar />
    <ClientOnly fallback-tag="span" fallback="加载评论中...">
      <Comment />
    </ClientOnly>
  </div>
</template>

内置组件

<NuxtLayout>

用于渲染对应的布局,默认加载 default 布局

  • name 属性可指定需加载的布局
  <NuxtLayout name="custom">
    <NuxtPage />
  </NuxtLayout>
  • 获取布局组件的 ref,需通过 ref.value.layoutRef
<script setup lang="ts">
const layout = ref()

function logFoo () {
  layout.value.layoutRef.foo()
}
</script>

<template>
  <NuxtLayout ref="layout" />
</template>
  • 可向下传递自定义属性
    <NuxtLayout name="custom" title="我是一个自定义布局">
      <-- ... -->
    </NuxtLayout>

具体页面的模板中可以通过 $attrs.title 获取,JS 中可通过 useAttrs().title 获取

  • 为了达到预期的过渡效果,建议 <NuxtLayout /> 不是页面组件的根元素
<template>
  <div>
    <NuxtLayout name="custom">
      <template #header> 页面头部模板内容。 </template>
    </NuxtLayout>
  </div>
</template>

<NuxtPage>

是对 Vue Router 的 <RouterView> 组件的封装,用于渲染路由对应的页面。

  • 通过传递 static 键,NuxtPage 组件在挂载时只会渲染一次
<template>
  <NuxtPage page-key="static" />
</template>
  • 获取页面组件的 ref,需通过 ref.value.pageRef
<script setup lang="ts">
const page = ref()

function logFoo () {
  page.value.pageRef.foo()
}
</script>

<template>
  <NuxtPage ref="page" />
</template>
  • 可向下传递自定义属性
<NuxtPage :foobar="123" />

具体页面的模板中可以通过 $attrs.foobar 获取,JS 中可通过 useAttrs().foobar 获取

<NuxtLink>

是 Vue Router 的 <RouterLink> 组件和 HTML 的 <a> 标签的替代品。它能智能地确定链接是内部链接还是外部链接,并根据可用的优化(预加载、默认属性等)进行渲染。

  <NuxtLink to="/about">
    路由到内部页面
  </NuxtLink>
  <NuxtLink to="https://nuxtjs.org">
    路由到外部网站
  </NuxtLink>

<NuxtLink> 的完整属性列表和自定义<NuxtLink>的方法,详见官网

<NuxtImg>

是原生<img>标签的一个即插即用替代品,功能如下:

  • 使用内置提供商优化本地和远程图像
  • 将src转换为提供商优化的URL
  • 根据width和height自动调整图像大小
  • 在提供sizes选项时生成响应式尺寸
  • 支持原生懒加载以及其他<img>属性

使用前,需先安装

npx nuxi@latest module add image

使用时,和<img>标签一样

<NuxtImg src="/nuxt-icon.png" />

更多功能详见其官网 https://image.nuxt.com/usage/nuxt-img

<NuxtPicture>

是对原生picture标签的一种直接替代方式,在可能的情况下提供现代格式,如webp

用法几乎与 NuxtImg 相同,

<Teleport>

将一个组件传送到DOM中的不同位置,目前只支持传送到 body

<template>
  <button @click="open = true">
    打开模态框
  </button>
  <Teleport to="body">
    <div v-if="open" class="modal">
      <p>来自模态框的问候!</p>
      <button @click="open = false">
        关闭
      </button>
    </div>
  </Teleport>
</template>

对于其他目标的客户端支持需要使用<ClientOnly>包装器。

<template>
  <ClientOnly>
    <Teleport to="#some-selector">
      <!-- 内容 -->
    </Teleport>
  </ClientOnly>
</template>

<NuxtLoadingIndicator>

在页面导航之间显示一个进度条。

  <NuxtLayout>
    <div>
      <NuxtLoadingIndicator /> <!-- 在这里 -->
      <NuxtPage />
    </div>
  </NuxtLayout>

属性如下:

  • color: 进度条的颜色。可以设置为 false 来关闭显式的颜色样式。
  • height: 进度条的高度,以像素为单位(默认为 3)。
  • duration: 进度条的持续时间,以毫秒为单位(默认为 2000)。
  • throttle: 进度条出现和隐藏的节流时间,以毫秒为单位(默认为 200)。

<NuxtErrorBoundary>

处理在其默认插槽中发生的客户端错误。

https://www.nuxt.com.cn/docs/api/components/nuxt-error-boundary

<ClientOnly>

客户端组件中已介绍

<DevOnly>

仅在开发环境中渲染的组件

    <DevOnly>
      <!-- 仅在开发环境中渲染此组件 -->
      <LazyDebugBar />

      <!-- 如果您需要在生产环境中进行替换 -->
      <!-- 请确保使用 `nuxt preview` 进行测试 -->
      <template #fallback>
        <div><!-- 用于 flex.justify-between 的空 div --></div>
      </template>
    </DevOnly>

<NuxtWelcome>

展示 Nuxt 文档、源代码和社交媒体账号的链接,效果如下图

在这里插入图片描述

实验中的内置组件

<NuxtClientFallback>

其任何子组件在 SSR 中触发错误,则在客户端渲染其内容。

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

<NuxtIsland>

渲染一个没有任何客户端JS的非交互式组件

https://www.nuxt.com.cn/docs/api/components/nuxt-island

其他

Nuxt 提供了<Title>、<Base>、<NoScript>、<Style>、<Meta>、<Link>、<Body>、<Html>和<Head>组件,让你可以直接在组件的模板中与元数据进行交互。

<script setup lang="ts">
const title = ref('你好,世界')
</script>

<template>
  <div>
    <Head>
      <Title>{{ title }}</Title>
      <Meta name="description" :content="title" />
      <Style type="text/css" children="body { background-color: green; }" />
    </Head>

    <h1>{{ title }}</h1>
  </div>
</template>

添加组件库

详见官网

  • 22
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Nuxt.js 3 中,全局注册组件是一个常用的功能,它允许你在整个应用中复用组件,而无需每个页面或组件单独引入。这有助于保持代码组织和减少重复。以下是全局注册组件的步骤: 1. **安装并引入**:首先确保你已经安装了 Nuxt 3(使用 `npm install nuxt` 或者 `yarn add nuxt`),然后在项目的根目录下创建一个名为 `components` 的文件夹。 2. **创建组件**:在 `components` 文件夹下创建一个 `.vue` 文件,定义你的全局组件。例如: ```html <template> <div> <h1>My Global Component</h1> <p>{{ message }}</p> </div> </template> <script> export default { props: { message: { type: String, required: true, }, }, }; </script> ``` 3. **在 `nuxt.config.js` 配置**:在 Nuxt 配置文件中,你需要设置 `components` 配置项,告诉 Nuxt 这个文件夹里的所有 `.vue` 文件都是全局可用的。添加以下代码: ```js export default defineNuxtConfig({ // ... components: [ { path: '~/components', filename: 'index.vue' }, // 或者 'glob' 如果你希望导入整个文件夹 ], }); ``` - `path` 指定了组件的路径相对于 `components` 文件夹。 - `filename` 可以是单个组件文件名(如 `index.vue`),也可以是 `'glob'` 表示导入整个文件夹中的所有 .vue 文件。 4. **使用组件**:现在在你的任何页面、组件或布局中,都可以直接使用这个全局组件了: ```html <template> <MyGlobalComponent :message="greetingMessage" /> </template> <script> import MyGlobalComponent from '@/components/MyGlobalComponent.vue'; export default { components: { MyGlobalComponent, }, data() { return { greetingMessage: 'Hello, World!', }; }, }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朝阳39

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值