Vue Components
Build interfaces from focused, reusable Vue components.
Overview
Components divide a large interface into smaller building blocks. Each Vue component can own its template, JavaScript logic, and styles, making features easier to understand, reuse, test, and maintain. Together, parent and child components form the application's UI hierarchy.
Key concepts
- Components encapsulate focused UI responsibilities
- Single-File Components use .vue files
- Parent components render child components
- Reusable components reduce duplicated markup and behavior
What are Components?
A component is a reusable piece of the user interface. Rather than creating one enormous page, you assemble focused components such as a header, navigation menu, sidebar, product card, cart, and footer.
Application
├── Header
├── Navigation
├── Main Content
│ ├── Sidebar
│ └── Product List
└── FooterWhy do we need Components?
Every product in an online store displays similar information: an image, name, price, and action button. A ProductCard component defines that structure once and receives different product data for every use.
- Reduces duplicate code
- Keeps features organized
- Makes updates consistent
- Speeds up development
- Supports testing and teamwork
Structure of a Vue Component
A Single-File Component is normally stored in a .vue file containing template, script, and optional style sections.
<template>
<h2>{{ message }}</h2>
</template>
<script setup>
const message = "Hello Vue!";
</script>
<style scoped>
h2 {
color: blue;
}
</style>| Section | Purpose |
|---|---|
| template | Declares the component's rendered UI |
| script | Contains state, behavior, props, events, and imports |
| style | Defines the component's CSS |
The scoped attribute limits generated style selectors to the current component's rendered elements. It is useful for local styling but does not make CSS completely isolated from every global rule.
Creating a Component
Create WelcomeMessage.vue inside src/components.
<template>
<h2>Welcome to DevBrainBox!</h2>
</template>Using a Component with script setup
Importing a component in script setup makes it available to the template automatically.
<script setup>
import WelcomeMessage from "./components/WelcomeMessage.vue";
</script>
<template>
<WelcomeMessage />
</template>Using a Component with the Options API
In a traditional script block, locally imported components are registered in the components option.
<script>
import WelcomeMessage from "./components/WelcomeMessage.vue";
export default {
components: {
WelcomeMessage
}
};
</script>
<template>
<WelcomeMessage />
</template>Reusing Components
The same component type can appear many times. Each rendered instance has its own local state while sharing the same component definition.
<ProductCard />
<ProductCard />
<ProductCard />Reusable Components with Props
Props let a parent customize each instance rather than hard-coding identical content.
<script setup>
defineProps({
name: String,
price: Number
});
</script>
<template>
<article class="product-card">
<h2>{{ name }}</h2>
<p>₹{{ price }}</p>
</article>
</template><ProductCard name="Keyboard" :price="2499" />
<ProductCard name="Mouse" :price="799" />Parent and Child Components
A component that renders another component is its parent. The rendered component is a child. Vue applications form a tree from these relationships.
App
├── Header
├── Sidebar
├── ProductList
│ ├── ProductCard
│ ├── ProductCard
│ └── ProductCard
└── FooterParents generally pass data down with props. Children communicate changes upward by emitting events. The Communication lesson explores this data flow in detail.
Local and Global Registration
Local registration makes dependencies explicit and supports tree-shaking. Global registration can suit truly application-wide primitives, but registering many components globally makes ownership and usage harder to trace.
import { createApp } from "vue";
import App from "./App.vue";
import BaseButton from "./components/BaseButton.vue";
const app = createApp(App);
app.component("BaseButton", BaseButton);
app.mount("#app");Component Naming
- Use PascalCase for imported component identifiers
- Choose descriptive multi-word names
- Name reusable primitives consistently, such as BaseButton
- Match file names to component names
- Avoid vague names such as Item or Box when the domain is known
Real-life example
A blog can contain Header, SearchBar, BlogCard, CategoryList, CommentList, and Footer components. BlogCard is reused for each article while props provide the unique title, image, and summary.
Benefits of Components
- Reusable code
- Clear project organization
- Focused debugging
- Faster feature development
- Simpler maintenance
- Independent testing
- Improved collaboration
When to create a Component
- The same UI pattern appears repeatedly
- A section has a clear responsibility
- A large template is difficult to understand
- Logic and markup belong to one feature
- The section benefits from independent testing or reuse
Common beginner mistakes
- Creating components that are too large
- Splitting every tiny element without a useful boundary
- Forgetting to import or register a child
- Using unclear names
- Duplicating markup instead of using props
- Mutating parent-owned data directly
- Putting unrelated responsibilities in one component
Best practices
- Give each component a focused responsibility
- Use meaningful PascalCase names
- Prefer local imports
- Use props and events for clear data flow
- Keep reusable components independent of page-specific assumptions
- Extract repeated UI deliberately
- Co-locate component-specific tests and styles when practical
Key takeaways
- Components are reusable UI building blocks
- Single-File Components group template, logic, and styles
- Imported children form a component hierarchy
- Props customize component instances
- Each instance owns its local state
- Thoughtful component boundaries reduce duplication
- Focused components improve scalability and maintenance