Roadmap › Vue.js 3 (with Pinia, Vue Router & Nuxt basics) › Module: Components
Lessons in this course (17)
9. Slots, provide/inject and component communication
Intermediate★ Must knowLesson 9 of 17
vue
<!-- Card.vue -->
<template>
<div class="card">
<header><slot name="title">Default title</slot></header>
<slot /> <!-- default slot -->
<footer><slot name="footer" :total="total" /></footer> <!-- scoped slot passes data up to the parent's template -->
</div>
</template>
<!-- usage -->
<Card>
<template #title><h3>Orders</h3></template>
<p>Body content</p>
<template #footer="{ total }">Total: {{ total }}</template>
</Card>ts
// provide/inject: pass data deep without prop drilling
// Ancestor
provide("theme", readonly(theme));
// Any descendant
const theme = inject("theme", ref("light")); // default value| Communication | How |
|---|---|
| Parent → child | Props |
| Child → parent | Emits (events), v-model |
| Parent calls child | Template ref + defineExpose() in the child |
| Deep descendants | provide / inject |
| Siblings / global | Pinia store (or a shared composable) |
| Routing | Route params/query |
Avoid the old Vue 2 event bus (new Vue() as emitter) — use Pinia or a small mitt emitter if truly needed.