组件注册

一个 Vue 组件在使用前需要先被“注册”,这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式:全局注册和局部注册。

vue 中组件的引用原则:先注册后使用。

image-20251128190935009

全局注册

被全局注册的组件,可以在整个应用的任何组件模板中直接使用,无需再次导入。

通用组件(如按钮、卡片、导航栏等),在多个地方频繁使用等组件一般会使用全局注册的形式,全局注册会增加初始加载体积,所以只在有必要的情况下才使用全局注册

注册方式需要在 Vue 应用实例创建时通过 app.component() 方法注册,示例代码:

1
2
3
4
5
6
7
8
9
10
11
// main.ts 或 main.js
import { createApp } from 'vue'
import App from './App.vue'
import WordCard from './components/WordCard.vue' // 导入你的单词卡片组件

const app = createApp(App)

// 全局注册组件:第一个参数是组件名,第二个参数是组件对象
app.component('WordCard', WordCard)

app.mount('#app')

全局注册后,在任何组件的模板中都可以直接使用:

1
2
3
4
<!-- 任意组件的模板中 -->
<template>
<WordCard :word="someWord" />
</template>

局部注册

被局部注册的组件,只能在当前注册的范围内使用

仅在特定组件中使用的组件一般情况下使用局部注册,避免全局注册导致的资源浪费。

在使用组件的地方通过 import 导入,然后在组件选项中声明(Vue3 组合式 API 中无需额外声明,导入后可直接使用)。

假设在 WordBook.vue 中使用 WordCard 组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- WordBook.vue -->
<template>
<div class="word-book">
<!-- 直接使用导入的组件 -->
<WordCard
v-for="word in words"
:key="word.id"
:word="word"
/>
</div>
</template>

<script setup lang="ts">
import WordCard from './WordCard.vue' // 局部导入组件
import { useWordBookStore } from '../stores/wordbook'

const wordBookStore = useWordBookStore()
const words = wordBookStore.words
</script>
  • 在 Vue3 的 <script setup> 语法中,导入的组件会自动注册为局部组件,无需像 Options API 那样在 components 选项中声明
  • 未导入的组件无法在模板中使用,会被视为普通 HTML 标签(通常会报错)

而这是静态组件,Vue 会在编译时就知道要渲染哪个组件,不需要在运行时做判断

通过 name 属性注册组件

name 属性是组件内部的一个标识,定义在组件选项中,主要有以下作用:

name 属性的定义方式

在 Vue 3 的 <script setup> 中,需要单独通过 <script> 标签定义(因为 <script setup> 是语法糖,不直接支持 name 属性):

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- WordCard.vue 补充 name 属性 -->
<script lang="ts">
// 单独的 script 标签定义 name
export default {
name: 'WordCard'
}
</script>

<script setup lang="ts">
// 原有的 setup 代码...
import { computed } from 'vue'
// ...
</script>

那么,如何在注册组件的时候使用 name 这个名字当组件名,例如

image-20251128192337085

正常全局注册组件是这样写:

1
2
// 直接写死组件名 'MySwiper'
app.component('MySwiper', Swiper)

而用name属性的话,可以简化成:

1
2
// 从组件自身的name属性里取名字(也就是'MySwiper')
app.component(Swiper.name, Swiper)

更简单的说你写了个组件文件Button.vue,里面定义name: 'MyButton',注册时直接用app.component(Button.name, Button),就相当于注册了名为MyButton的组件,在页面里可以用<MyButton/>调用。

Vue Devtools 会显示 name 属性的值,便于在组件树中识别(如你的 WordCard 组件在 Devtools 中会显示为 WordCard

组件注册时命名问题

在进行组件的注册时,定义组件注册名称的方式有两种,分别对应不同的使用场景:

PascalCase 命名法(大驼峰)

  • 定义方式:组件名采用首字母大写的驼峰形式(如 WordCardUserProfile
  • 使用场景
    • 组件文件命名(如你的 WordCard.vue 符合此规范)
    • 代码中导入 / 注册组件时(如 import WordCard from './WordCard.vue'
    • Vue 模板中使用时(支持 `
  • 为什么要用这种
    • 符合 JavaScript/TypeScript 的变量命名规范
    • 与 Vue 单文件组件的文件名保持一致,便于关联查找
    • 在模板中使用时,清晰区分组件和 HTML 原生标签
kebab-case 命名法(短横线分隔)
  • 定义方式:组件名全部小写,单词之间用短横线连接(如 word-carduser-profile
  • 使用场景
    • 模板中引用组件时(<word-card />
    • 全局注册时指定名称(如 app.component('word-card', WordCard)
  • 为什么要用这种
    • 符合 HTML 标签的命名规范(HTML 标签通常为小写)
    • 避免与未来可能出现的 HTML 原生标签冲突

Vue 会自动处理两种命名方式的转换:

  • 当你注册组件时使用 WordCard,在模板中既可以用 <WordCard> 也可以用 <word-card>
  • 当你注册组件时使用 word-card,在模板中只能用 <word-card>(不能用 <WordCard>
1
2
3
4
5
6
7
8
9
10
11
// 全局注册时使用 PascalCase
app.component('WordCard', WordCard)
// 模板中两种方式都可使用
<WordCard :word="word" />
<word-card :word="word" />

// 全局注册时使用 kebab-case
app.component('word-card', WordCard)
// 模板中只能用短横线形式
<word-card :word="word" /> <!-- 正确 -->
<WordCard :word="word" /> <!-- 错误 -->

<script setup> 语法糖

什么是<script setup> 语法糖

Vue 官方文档这么描述这个语法糖:<script setup>是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用单文件组件与组合式 API 时该语法是默认推荐。

简单来说,<script setup> 是 Vue 为了让开发者在单文件组件(.vue 文件)中更简洁、更高效地使用组合式 API(Composition API)而设计的一种语法简化方案。

那么是如何体现其简化的呢?

  • <script setup> 允许在