Chapter 48: Vue Built-in Components
Vue’s Built-in Components.
These are special components that Vue gives you for free — you don’t need to install anything, import anything, or register anything. They are always available in any Vue template, and they solve very common problems in a clean, declarative way.
In Vue 3 (2026 standard), there are 7 main built-in components that you will actually use in real projects. (There are a couple more internal ones, but 99% of the time you only care about these.)
Here they are, in the order of how often you will use them:
- <component :is=”…”> → Dynamic Components
- <Transition> → Single-element enter/leave animations
- <TransitionGroup> → List (v-for) animations
- <KeepAlive> → Cache components (great for tabs/router-view)
- <Teleport> → Move content to another part of the DOM (modals, toasts)
- <Suspense> → Handle async setup / loading states
- <slot> → (technically not a component, but built-in slot syntax)
Let’s go through them one by one — with real, practical examples and when/why you reach for each.
1. <component :is=”…”> – Dynamic Components (Most Used)
This is the king of built-in components — used in almost every medium/large app.
It lets you render a different component at runtime based on a variable.
Realistic example – Tabbed interface
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<template> <div class="tabs-demo"> <div class="tab-buttons"> <button v-for="tab in tabs" :key="tab.name" :class="{ active: activeTab === tab.name }" @click="activeTab = tab.name" > {{ tab.label }} </button> </div> <!-- ★ This is the dynamic magic ★ --> <component :is="currentTabComponent" :key="activeTab" <!-- important for state reset --> /> </div> </template> <script setup lang="ts"> import { ref, computed, defineAsyncComponent } from 'vue' const Overview = () => import('@/components/tabs/Overview.vue') const Analytics = defineAsyncComponent(() => import('@/components/tabs/Analytics.vue')) const Settings = () => import('@/components/tabs/Settings.vue') const tabs = [ { name: 'overview', label: 'Overview', component: Overview }, { name: 'analytics', label: 'Analytics', component: Analytics }, { name: 'settings', label: 'Settings', component: Settings } ] const activeTab = ref('overview') const currentTabComponent = computed(() => { return tabs.find(t => t.name === activeTab.value)?.component || null }) </script> |
When you use <component :is> every week
- Tabbed dashboards / settings pages
- Role-based views (admin vs user dashboard)
- Wizard / multi-step forms
- CMS / page-builder rendering
- A/B testing variants
- Dynamic content from API/JSON
2. <Transition> – Single Element Enter/Leave
Wraps one element that appears/disappears (v-if / v-show / v-if inside router-view).
|
0 1 2 3 4 5 6 7 8 9 10 |
<Transition name="fade"> <div v-if="showModal" class="modal"> Modal content </div> </Transition> |
|
0 1 2 3 4 5 6 7 8 9 10 11 |
.fade-enter-active, .fade-leave-active { transition: opacity 0.4s ease; } .fade-enter-from, .fade-leave-to { opacity: 0; } |
Shorthand names you will see everywhere
- fade → opacity fade
- slide → slide in/out
- scale → zoom in/out
- bounce → fun bounce effect
3. <TransitionGroup> – List Animations (v-for)
This is the one that makes todo lists, cards, search results feel premium.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<TransitionGroup name="list" tag="ul"> <li v-for="item in filteredItems" :key="item.id" > {{ item.name }} </li> </TransitionGroup> |
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.list-enter-active, .list-leave-active, .list-move { transition: all 0.4s ease; } .list-enter-from, .list-leave-to { opacity: 0; transform: translateX(-30px); } .list-leave-active { position: absolute; /* prevents layout jump */ width: 100%; } |
4. <KeepAlive> – Cache & Preserve State
Wraps dynamic components / router-view so they remember state when hidden.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<KeepAlive> <component :is="currentTab" /> </KeepAlive> <!-- or in router-view --> <router-view v-slot="{ Component }"> <KeepAlive> <component :is="Component" /> </KeepAlive> </router-view> |
→ Tabs remember form inputs, scroll position, internal state — huge UX win.
5. <Teleport> – Move Content to Another DOM Location
Renders children in a different part of the DOM tree (usually body).
|
0 1 2 3 4 5 6 7 8 9 10 |
<Teleport to="body"> <div class="modal" v-if="show"> Modal content – appears at end of body </div> </Teleport> |
Perfect for:
- Modals / dialogs
- Toasts / notifications
- Full-screen overlays
- Tooltips that break out of scroll containers
6. <Suspense> – Handle Async Setup / Loading
Shows fallback while child components are loading (async setup or lazy components).
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<Suspense> <template #default> <AsyncHeavyComponent /> </template> <template #fallback> <div class="loading">Loading heavy component...</div> </template> </Suspense> |
Very useful with:
- defineAsyncComponent
- async setup()
- Lazy routes in Vue Router
Quick Reference Table – Vue Built-in Components (2026)
| Component | Primary Purpose | Most Common Wrapper For | Real Frequency (daily use) |
|---|---|---|---|
| <component :is> | Dynamic / runtime component selection | Tabs, role-based UI, wizards | ★★★★★ (every large app) |
| <Transition> | Single enter/leave or state change animation | Modals, alerts, dropdowns, v-if blocks | ★★★★★ |
| <TransitionGroup> | List enter/leave/move animations | Todo lists, cards, search results | ★★★★☆ |
| <KeepAlive> | Cache component state when hidden | Tabs, router-view, dynamic components | ★★★★☆ |
| <Teleport> | Move content to different DOM location | Modals, toasts, popovers | ★★★★☆ |
| <Suspense> | Handle async loading states | Lazy components, async setup | ★★★☆☆ (growing) |
Pro Tips from Real Projects (2026)
- Always add :key when using dynamic :is — prevents state leakage
- Combine <Transition> + <KeepAlive> for animated cached tabs
- Use <Teleport to=”#modals”> + central #modals div in index.html
- <Suspense> + defineAsyncComponent = beautiful lazy-loading DX
- Test animations on mobile — 60Hz vs 120Hz feels very different
- Respect prefers-reduced-motion media query for accessibility
Your mini practice task:
- Build a tabbed interface using <component :is> + <KeepAlive>
- Add <Transition> fade when switching tabs
- Wrap a modal in <Teleport to=”body”>
- Add <TransitionGroup> to a todo list inside one tab
Any part confusing? Want full examples for:
- Animated router-view transitions?
- Real modal system with Teleport + Transition?
- <Suspense> + async setup example?
- Combining all of them in one dashboard page?
Just tell me — we’ll build the next polished, animated feature together 🚀
Happy built-in-component-ing from Hyderabad! 💙
