Defining and Registering Components
A Vue component is a reusable, self-contained unit combining template markup, logic, and (optionally) scoped styling. The most common authoring format is the Single-File Component (SFC) — a .vue file with <template>, <script setup>, and <style> blocks. Before a component can be used in another component's template, it needs to be registered, either locally (available only in the component that imports it) or globally (available in every component in the application without an explicit import).
Cricket analogy: A Vue SFC is like a training drill card bundling the diagram, the coach's notes, and the kit list in one page; before another net session can run it, it must be added to the squad's playbook, locally for one team or globally for the whole academy.
Local registration
With <script setup>, local registration happens implicitly: importing a component makes it immediately available in the template, with no separate components: {} option needed, because the compiler resolves any capitalized tag in the template against the imported bindings in scope. This is the default and recommended approach for the vast majority of components, since it keeps the dependency graph explicit — you can see exactly which components a given file relies on just by reading its imports — and it enables better dead-code elimination during a production build, since unused components aren't referenced anywhere and can be tree-shaken.
Cricket analogy: In <script setup>, importing a component is like a captain naming a player straight onto the team sheet just by writing their name — no separate selection meeting needed — and unused players never travel with the squad to the match.
Global registration
Global registration uses app.component('ComponentName', ComponentDefinition) on the application instance created by createApp(), typically in the project's entry file. Once registered globally, a component can be used in any template throughout the app without an import statement. This convenience comes at a cost: global components are always included in the final bundle regardless of whether a given page actually uses them, and it becomes harder to trace, just by reading a template, where a given component's implementation lives. Global registration is best reserved for a small number of truly ubiquitous components — a base button, a base icon wrapper, a design-system primitive used on nearly every page — not for typical feature components.
Cricket analogy: Global registration with app.component() is like naming a player a permanent squad fixture available to every match on the calendar, not just one game; useful for a genuine all-format star, wasteful if every fringe player got that treatment.
<!-- BaseCard.vue: a reusable presentational component -->
<script setup>
defineProps({
title: { type: String, required: true }
})
</script>
<template>
<div class="base-card">
<h3>{{ title }}</h3>
<slot />
</div>
</template>
<style scoped>
.base-card {
border: 1px solid #e2e2e2;
border-radius: 8px;
padding: 1rem;
}
</style>
<!-- Dashboard.vue: locally registers BaseCard via import -->
<script setup>
import BaseCard from './BaseCard.vue'
</script>
<template>
<BaseCard title="Revenue">
<p>$42,500 this month</p>
</BaseCard>
</template>This local-vs-global tradeoff mirrors React's default pattern of importing every component explicitly (equivalent to Vue's local registration) versus a global context provider or a design-system library re-exported from a barrel file that's imported everywhere implicitly. Vue simply formalizes the 'available everywhere' option as a first-class API (app.component) rather than leaving it to a convention.
Component names should be multi-word (e.g. BaseCard, not Card) to avoid clashing with existing and future native HTML elements, a rule enforced by Vue's official ESLint config. Additionally, remember that when referencing a component in the template, PascalCase names like <UserProfile /> and kebab-case names like <user-profile /> are both valid and refer to the same component in an SFC template, but PascalCase is the idiomatic convention because it visually distinguishes components from native HTML tags at a glance.
- SFCs (
.vuefiles) combine template, script, and style in one file, and are the standard way to author Vue 3 components. - With
<script setup>, importing a component automatically makes it available in the template — no explicitcomponents: {}option is needed. - Global registration via
app.component()makes a component available app-wide without imports, at the cost of always being bundled and harder traceability. - Reserve global registration for a small number of ubiquitous base/primitive components, not typical feature components.
- Component names should be multi-word to avoid colliding with current or future native HTML elements.
- PascalCase component tags (
<UserCard />) are the idiomatic convention, visually distinguishing components from native HTML elements.
Practice what you learned
1. In a `<script setup>` SFC, how is a component locally registered?
2. What is the main tradeoff of global component registration via app.component()?
3. Why should component names be multi-word (e.g., BaseCard instead of Card)?
4. Which registration approach benefits most from build-time tree-shaking of unused components?
5. What is the idiomatic casing convention for referencing a component in an SFC template?
Was this page helpful?
You May Also Like
Props Explained
Explains how props pass data from parent to child components in Vue, covering declaration, validation, defaults, and the one-way data flow rule.
Slots and Content Distribution
Explore how Vue slots let parent components inject markup into a child's template, covering default, named, and scoped slots.
Emitting Custom Events
Learn how child components communicate upward to parents using Vue's custom event system, including typed emits and the defineEmits macro.
The setup() Function and <script setup>
Learn the entry point of the Composition API — the setup() function — and how <script setup> compiles away its boilerplate.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics