components 自定义全局组件
无需 import
在 Nuxt3 中会自动导入 components 目录中的所有组件,当你想使用组件时,不需要 import 了,直接使用即可
嵌套目录组件
如果您在嵌套目录中有一个组件,例如:
components/
--| base/
----| foo/
------| Button.vue
<template>
<div>
<button>组件按钮测试</button>
</div>
</template>
组件的名称将基于其自己的路径目录和文件名,并删除重复的段。那么我们可以直接在其它地方使用:
<BaseFooButton />
:::info
为清楚起见,建议组件的文件名与其名称匹配。(因此,在上面的示例中,可以将Button.vue
重命名为BaseFooButton.vue
)
:::
如果只想根据组件的名称而不是路径自动导入组件,可以在 nuxt.config.ts
配置
export default defineNuxtConfig({
components: [
{
path: '~/components',
pathPrefix: false,
},
],
});
配置后上面的组件在使用时无需添加路径名
<Button />
自定义扫描目录 全局组件前缀
默认情况下,仅扫描components
目录。如果要添加其他目录,或更改在components
目录的子文件夹中扫描组件的方式,则可以将其他目录添加到配置中
export default defineNuxtConfig({
srcDir: "src/",
components: [
{
path: "~/components",
extensions: [".vue", "ts"],
pathPrefix: false,
prefix: "Glo",
},
{ path: "~/components/special-components", prefix: "Special" },
],
});
上面的配置中给所有全局组件添加’Glo’前缀,前面例子中的 组件在使用时就要改为
再添加如下文件夹,根据配置,则Name
组件在使用时应该添加 Special 前缀 <SpecialName />
。
动态组件
如果需要使用 Vue 的 <component :is="...">
语法,则需要使用 Vue 提供的 resolveComponent 方法。
🙌🌰:
随便创建几个组件用于测试
组件里随便写点内容
<template>
<div>components A</div>
</template>
使用动态组件示例:
<template>
<component :is="currentComponent ? currentComponent : 'div'" />
<button @click="toggleComponent">切换组件</button>
</template>
<script lang="ts" setup>
const currentComponent = shallowRef<Component | string>('')
const TheA = resolveComponent('GloTheA') // Glo 是自定义的组件前缀
const TheB = resolveComponent('GloTheB')
const TheC = resolveComponent('GloTheC')
const componentList = [TheA, TheB, TheC]
let index = -1
const toggleComponent = () => {
index = index < 2 ? index + 1 : 0
currentComponent.value = componentList[index]
}
</script>
动态导入 (懒加载组件)
态导入组件(也称为懒加载组件),只需在组件名称中添加Lazy前缀。如果不总是需要该组件,可以通过使用Lazy前缀,将组件代码的加载延迟到适当的时间,这有助于优化 JavaScript 包大小。
比较适合一些弹窗组件,通常需要点击事件才会打开弹窗
<template>
<div>
<LazyMyModal v-model:open="isOpen" />
</div>
</template>
手动导入
如果希望或需要绕过 Nuxt 的自动导入功能,还可以显式地从#components
导入组件。
前面动态组件的例子,除了使用 resolveComponent 方法,也可以改为手动导入组件
<template>
<component :is="currentComponent ? currentComponent : 'div'" />
<button @click="toggleComponent">切换组件</button>
</template>
<script lang="ts" setup>
import { GloTheA } from '#components'
const currentComponent = shallowRef<Component | string>('')
// const TheA = resolveComponent('GloTheA')
const TheB = resolveComponent('GloTheB')
const TheC = resolveComponent('GloTheC')
const componentList = [GloTheA, TheB, TheC]
let index = -1
const toggleComponent = () => {
index = index < 2 ? index + 1 : 0
currentComponent.value = componentList[index]
}
</script>
nuxt3 内置组件
客户端组件
Nuxt 提供了
要仅在客户端导入组件,请在仅客户端插件中注册该组件。
<template>
<div>
<ClientOnly>
<!-- 此组件仅在客户端显示 -->
<Comments />
</ClientOnly>
</div>
</template>
路由出口组件
如果需要使用 pages 显示相关页面的话,需要使用
<template>
<div>
<NuxtLayout>
<NuxtPage/>
</NuxtLayout>
</div>
</template>
:::info
由于Nuxt 3在内部使用了
Props
name
type:string
name
帮助 RouterView
在匹配的路由记录的组件选项中使用相应的名称渲染组件。参考Vue Router的命名视图
route
- type:
RouteLocationNormalized
route
是一个路由地址的所有组件都已被解析(如果所有组件都被懒加载)。参考
Nuxt 通过扫描和渲染
pages
目录中的所有 Vue 组件文件,自动解析name
和route
。
- pageKey
type: ‘string’ | ‘function’
pageKey有助于
通过传递 static key,
自定义 Props
未定义Props
的属性则可以通过 Vue 的透传 Attribute $attrs
访问。
透传 Attribute
🙌🌰:
pages/parent.vue
<template>
<div>
<h1>嵌套路由示例 - 父级 parent.vue 页面</h1>
<NuxtPage page-key="static" title="myTitle" foobar="value" />
</div>
</template>
pages/parent/index.vue 或者 pages/parent/child.vue
<template>
<div>
<h1>parent 目录 index.vue 页面 {{ $attrs }}</h1>
</div>
</template>
<script setup>
const props = defineProps({
title: {
type: String,
default: '我是标题'
}
})
console.log('🚀 ~ file: index.vue:13 ~ props:', props)
const attrs = useAttrs()
console.log(attrs)
</script>
template 中可以使用 $attrs.foobar 获得 foobar 的值,script 中使用 vue 的 useAttrs() 方法。
布局组件
通过
<!-- ~/app.vue -->
<template>
<NuxtLayout>
some page content
</NuxtLayout>
</template>
name
prop
<!-- ~/pages/index.vue -->
<template>
<NuxtLayout :name="layout">
<NuxtPage />
</NuxtLayout>
</template>
<script setup>
const layout = 'custom' // 名称对应 layouts/custom.vue
</script>
:::info
布局名称被规范化为kebab-case,如果布局文件被命名为 myLayout.vue,当使用名称属性传递给
Layout and Transition
Nuxt 提供了
使用<NuxtLink>组件链接到应用程序的另一个页面:
<template>
<NuxtLink to="/about">
About page
</NuxtLink>
<!-- <a href="/about">...</a> (+Vue Router & prefetching) -->
</template>
<template>
<NuxtLink to="https://twitter.com/nuxt_js" target="_blank">
Nuxt Twitter
</NuxtLink>
<!-- <a href="https://twitter.com/nuxt_js" target="_blank" rel="noopener noreferrer">...</a> -->
<NuxtLink to="https://discord.nuxtjs.org" target="_blank" rel="noopener">
Nuxt Discord
</NuxtLink>
<!-- <a href="https://discord.nuxtjs.org" target="_blank" rel="noopener">...</a> -->
<NuxtLink to="https://github.com/nuxt" no-rel>
Nuxt GitHub
</NuxtLink>
<!-- <a href="https://github.com/nuxt">...</a> -->
<NuxtLink to="/contact" target="_blank">
Contact page opens in another tab
</NuxtLink>
<!-- <a href="/contact" target="_blank" rel="noopener noreferrer">...</a> -->
</template>
Props
to:任何 URL 或来自 Vue Router 的路由对象
href:to的一个别名。如果和to一起使用,href将被忽略
target:应用于链接的目标属性值
rel:用于链接的rel属性值。对于外部链接,默认为 “noopener noreferrer”。
noRel:如果设置为 “true”,则没有rel属性将被添加到链接上。
activeClass:适用于链接激活时。与 Vue Router 的active-class在内部链接上的作用相同。默认为 Vue Router 的默认值是router-link-active。
exactActiveClass:链接精准激活时,应用于渲染的的 class。与Vue Router在内部链接上的exact-active-class的作用相同。默认为 Vue Router 的默认值是router-link-exact-active”。
replace:与内部链接上的 Vue Router 的replace相同。
ariaCurrentValue:当链接激活时,传递给属性aria-current的值。与内部链接上的 Vue Router 的aria相同。
external:强制将链接视为外部(true)或内部(false)。
custom:<NuxtLink>是否应将其内容包装在<a>元素中。它允许完全控制链接的呈现方式以及单击时导航的工作方式。工作原理与 Vue Router 的custom相同。
自定义
可以通过使用 defineNuxtLink 创建自己的链接组件来覆盖<NuxtLink>默认值。
defineNuxtLink类型:
defineNuxtLink({
componentName?: string; // 定义的<NuxtLink>组件的名称
externalRelAttribute?: string; // 应用于外部链接的默认rel属性值。默认为noopener-noreferrer。将其设置为''以禁用
activeClass?: string; // 适用于链接激活时。与 Vue Router 的active-class在内部链接上的作用相同。默认为 Vue Router 的默认值是router-link-active。
exactActiveClass?: string; // 链接精准激活时,应用于渲染的<a>的 class。与Vue Router在内部链接上的exact-active-class的作用相同。默认为 Vue Router 的默认值是router-link-exact-active"
prefetchedClass?: string;
trailingSlash?: 'append' | 'remove'
}) => Component
在 components/MyNuxtLink.ts 定义自定义的
export default defineNuxtLink({
componentName: 'MyNuxtLink',
externalRelAttribute: '',
activeClass: 'active',
exactActiveClass: 'exact-active'
})
页面加载进度组件
Nuxt 提供
添加
<template>
<NuxtLayout>
<NuxtLoadingIndicator /> <!-- here -->
<NuxtPage />
</NuxtLayout>
</template>
Props
- color:加载条颜色
- height:加载条高度,单位:px,默认值为:3
- duration:加载条加载持续时间,单位:毫秒,默认值为:2000
- throttle:显示加载条之前等待的时间,单位:毫秒,默认值为:200
SEO 相关组件
Nuxt 提供<Title> <Base> <NoScript> <Style> <Meta> <Link> <Body> <Html> <Head>
等内置组件。
这些组件名称与 HTML 元素匹配,因此在模板中将它们大写非常重要 ```vue
{{ title }}
```