Five components ship with Vue and each has a small API with precise semantics: six transition classes, three KeepAlive props, one Teleport target rule, two Suspense slots. These are the facts to have cold.
v-if, v-show, <component :is> switching, or a change of the key attribute. Wraps one element or component.v-enter-from, v-enter-active, v-enter-to, v-leave-from, v-leave-active, v-leave-to; with name="fade" the prefix becomes fade-. *-active classes are where transition/animation declarations go.animationend; when an element has both a transition and an animation, set type="transition" | "animation" to say which one to wait for.enter-active-class, leave-active-class, …) integrate libraries such as Animate.css. duration (number or { enter, leave }) handles nested transitions whose inner durations Vue cannot detect.@before-enter, @enter(el, done), @after-enter, @enter-cancelled, @before-leave, @leave(el, done), @after-leave, @leave-cancelled; with :css="false" Vue skips CSS detection and you must call done.appear animates the initial render. mode="out-in" | "in-out" orders transitions between elements. Dynamic transitions bind :name. Reusable transitions wrap <Transition> in a component with a slot. Performance advice: animate transform and opacity.tag renders one; modes are not available; every child needs a unique key; classes apply to the children.v-move class (or move-class) animates position changes using FLIP; set position: absolute on leaving items so the rest can move smoothly.data-index and JavaScript hooks (the guide uses GSAP).<component :is>), preserving state instead of destroying them.include / exclude: comma-delimited string, RegExp, or array, matched against the component's name (inferred from the SFC filename since 3.2.34 when using <script setup>). max limits cached instances with an LRU policy.onActivated / onDeactivated; they also fire on initial mount and on unmount, so they can replace mount/unmount hooks for cached components.to is a CSS selector or an element; the target must exist when the Teleport mounts, unless defer (3.5+) is used, which waits until the rest of the application has mounted (the target must still be in the same render tick or earlier).disabled renders in place (useful for mobile layouts). Multiple Teleports to the same target append in order.body).setup() (top-level await in <script setup>) and async components (which then ignore their own loading state).#default and #fallback; the fallback is shown until every dependency in the default slot resolves; on subsequent changes a timeout prop controls how long the old content stays before the fallback shows.pending, resolve, fallback. Errors are not handled by Suspense; use onErrorCaptured in a parent or errorCaptured in the app.RouterView → Transition → KeepAlive → Suspense → component. Nested Suspense (3.3+) uses the suspensible prop on the inner one so its pending state is handled by the parent.<script setup lang="ts">
const show = ref(true)
const items = ref([1, 2, 3])
const tab = ref<'A' | 'B'>('A')
const dialog = ref(false)
const tabs = { A: defineAsyncComponent(() => import('./TabA.vue')), B: defineAsyncComponent(() => import('./TabB.vue')) }
</script>
<template>
<!-- CSS transition, out-in between two elements keyed by content -->
<Transition name="fade" mode="out-in" appear>
<p v-if="show" key="on">On</p>
<p v-else key="off">Off</p>
</Transition>
<!-- List with move transitions; each child keyed -->
<TransitionGroup tag="ul" name="list">
<li v-for="n in items" :key="n">{{ n }}</li>
</TransitionGroup>
<!-- Cached tabs, at most two instances, only names matching /^Tab/ -->
<KeepAlive :include="/^Tab/" :max="2">
<Suspense :timeout="150">
<component :is="tabs[tab]" />
<template #fallback><p>Loading…</p></template>
</Suspense>
</KeepAlive>
<!-- Teleport with defer: the #modals target may render later in this tick -->
<Teleport to="#modals" defer :disabled="!dialog">
<div v-if="dialog" role="dialog">Hello</div>
</Teleport>
</template>
<style scoped>
.fade-enter-active, .fade-leave-active { transition: opacity 0.2s ease; }
.fade-enter-from, .fade-leave-to { opacity: 0; }
.list-move, .list-enter-active, .list-leave-active { transition: all 0.3s ease; }
.list-enter-from, .list-leave-to { opacity: 0; transform: translateX(20px); }
.list-leave-active { position: absolute; } /* lets the remaining items move smoothly */
</style>
Two <p> elements toggled with v-if/v-else are patched in place, so no transition runs. Give them distinct keys so Vue treats them as different elements; the guide calls this out explicitly.
type.KeepAlive with max="1" and log onActivated/onDeactivated while switching three times.defer."Vue toggles six classes: enter-from, enter-active and enter-to when an element appears, and the leave- trio when it goes, each prefixed with the transition's name. The active classes carry the transition or animation declaration; Vue listens for transitionend or animationend to know when to remove them, and type decides which when both exist, duration overrides detection for nested transitions. JavaScript hooks from before-enter to leave-cancelled are for animation libraries: with :css=\"false\" Vue skips CSS detection entirely and waits for the done callback I call from enter and leave."
Nothing yet. Notes filed here show up on this page and the section overview.
Reusability — composables, directives, plugins
The Composables chapter's conventions and restrictions, custom directive hooks and the binding object, and how plugins install through app.use.
Scaling up — SFC, tooling, routing, state, testing, SSR
What the guide says about single-file components and their CSS features, the recommended toolchain, routing and state management at the Vue level, the testing pyramid it proposes, and the SSR chapter's rules for SSR-friendly code.