🧩 1. What Is a Component?
A component in Vue is a reusable building block that encapsulates:
- HTML (template)
- CSS (style)
- JavaScript logic (script)
Each Vue app is built by nesting components together like LEGO pieces.
🟢 2. Creating a Basic Component
✅ Example: HelloWorld.vue
<template>
<h2>Hello, {{ name }}!</h2>
</template>
<script setup>
const name = 'Vue Learner'
</script>
<style scoped>
h2 {
color: #42b983;
}
</style>
🧠Explanation:
- The
<template>defines what appears in the UI. - The
<script setup>block defines logic (state, methods, props, etc.). <style scoped>ensures styles apply only to this component.
🧱 3. Nesting Components
To use a component inside another one:
- Import it
- Register it (if needed)
- Use it in your template
✅ Example: Nesting HelloWorld inside App.vue
App.vue
<template>
<div>
<h1>My Vue App</h1>
<HelloWorld />
</div>
</template>
<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
🧩 Vue automatically recognizes <HelloWorld /> because we imported it.
🟡 4. Passing Data to Child Components (Props)
Props let you send data from parent → child.
✅ Example:
Child.vue
<template>
<p>Hello, {{ username }}!</p>
</template>
<script setup>
defineProps({
username: String
})
</script>
Parent.vue
<template>
<div>
<Child username="Alice" />
</div>
</template>
<script setup>
import Child from './Child.vue'
</script>
🧠Explanation:
- The parent passes
username="Alice". - The child declares
defineProps()to receive it.
🟣 5. Sending Data from Child to Parent (Emits)
To send events up, use emit.
✅ Example:
Counter.vue
<template>
<button @click="increment">Clicked {{ count }} times</button>
</template>
<script setup>
import { ref } from 'vue'
// define events that this component can emit
const emit = defineEmits(['incremented'])
const count = ref(0)
function increment() {
count.value++
emit('incremented', count.value)
}
</script>
App.vue
<template>
<div>
<Counter @incremented="handleCount" />
<p>Last count: {{ lastCount }}</p>
</div>
</template>
<script setup>
import Counter from './Counter.vue'
import { ref } from 'vue'
const lastCount = ref(0)
function handleCount(value) {
lastCount.value = value
}
</script>
🧩 Flow:
- The child emits an event with a value.
- The parent listens with
@incremented="handleCount". - The parent reacts to the child’s event.
🔵 6. Component Hierarchy Example
A real-world structure might look like this:
src/
├── App.vue
├── components/
│ ├── Navbar.vue
│ ├── UserCard.vue
│ └── Footer.vue
└── views/
└── HomeView.vue
App.vueincludes<Navbar />,<HomeView />, and<Footer />.HomeViewcan include<UserCard />and other subcomponents.
🧠7. Dynamic & Nested Components
You can also conditionally render or dynamically switch between components.
✅ Dynamic Example:
<template>
<component :is="currentView"></component>
<button @click="currentView = 'LoginForm'">Login</button>
<button @click="currentView = 'RegisterForm'">Register</button>
</template>
<script setup>
import LoginForm from './LoginForm.vue'
import RegisterForm from './RegisterForm.vue'
import { ref } from 'vue'
const currentView = ref('LoginForm')
</script>
🧠Vue switches components without reloading the page.
🧩 8. Global vs Local Components
- Local registration: imported and used only in one file.
- Global registration: registered in
main.js(available everywhere).
✅ Example: Global Registration (main.js)
import { createApp } from 'vue'
import App from './App.vue'
import HelloWorld from './components/HelloWorld.vue'
const app = createApp(App)
app.component('HelloWorld', HelloWorld)
app.mount('#app')
Now you can use <HelloWorld /> in any component without importing it.
🧠9. Summary Table
| Concept | Direction | Example |
|---|---|---|
| Props | Parent → Child | <Child :username="userName" /> |
| Emit | Child → Parent | emit('update', value) |
| Slots | Parent injects content into child | <slot></slot> |
| Dynamic Components | Swap components dynamically | <component :is="currentView" /> |
| Nested Components | Build hierarchy | <Parent><Child /></Parent> |
