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 = -1const toggleComponent = () => {index = index < 2 ? index + 1 : 0currentComponent.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 = -1const toggleComponent = () => {index = index < 2 ? index + 1 : 0currentComponent.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:stringname 帮助 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 }}
```
