All quizzesHard
Router Internals — Series 3
Preview — 3 of 10 questions
How does this combination pick a different transition animation depending on which route is being navigated to?
javascript
<router-view v-slot="{ Component, route }">
<transition :name="route.meta.transitionName ?? 'fade'" mode="out-in">
<component :is="Component" />
</transition>
</router-view>A<router-view>'s scoped slot exposes both the resolved Component to render and the matched route itself, letting the surrounding <transition>'s name prop be bound dynamically to that route's own meta.transitionName — so navigating to /settings applies CSS classes prefixed slide-left-, navigating to /profile applies slide-right-, each matched by correspondingly named CSS transition/animation rules, all driven by per-route configuration rather than one fixed transition for the whole app
Bmode="out-in" is what selects the transition name — meta.transitionName is unused decoration with no actual effect
CThis is invalid — <transition>'s name prop must be a static string; binding it dynamically throws a compile error
Droute.meta.transitionName is a built-in Vue Router field with special meaning that Vue Router itself reads to choose an animation — no CSS classes need to be defined manually
Vue Router's routing logic is internally split into a matcher (pure route matching/resolution) and the navigation-triggering router.push/router.replace methods. Why does this separation matter?
AThe matcher's pure resolution logic (given a location, which route record(s) match, and what does the resolved route look like) is functionally independent of the side-effecting parts of navigation (updating browser history, running guards, actually changing what's rendered) — this separation is exactly what makes router.resolve() possible: computing a route's resolved href/params/matched-records for a <router-link> to display, without triggering any actual navigation, guards, or history changes. It also makes the matching logic independently testable without needing a real browser history or mounted app
BIt doesn't — matching and navigation are the same internal operation under different names, with no meaningful boundary between them
CThe matcher is only used internally during server-side rendering; client-side navigation bypasses it entirely and matches routes some other way
Dmatcher.resolve() and router.resolve() are two names for an identical public API with no internal distinction
What does the useLink() composable give you that makes building MyFancyLink possible without duplicating Vue Router's own internal logic?
javascript
<!-- MyFancyLink.vue -->
<script setup>
import { useLink, routerKey } from 'vue-router'
const props = defineProps({ to: { type: [String, Object], required: true } })
const { route, href, isActive, isExactActive, navigate } = useLink(props)
</script>
<template>
<a :href="href" @click="navigate" :class="{ 'fancy-active': isActive }">
<slot />
</a>
</template>AuseLink() is purely for internal use by Vue Router's source code — it's not part of the public, documented API and using it directly is unsupported
BuseLink() requires wrapping the component in <router-link custom> internally — it cannot be used standalone in a component's own setup()
CuseLink(props) exposes the exact same resolved link state and navigate function that <router-link> itself uses internally (via its own custom + v-slot mechanism) — reimplementing a fully custom link component from scratch, with correct href resolution, active-state tracking, and click handling (including respecting modifier-key clicks to let the browser open a new tab), without duplicating any of that matching/resolution logic by hand
DuseLink() only returns href — isActive, isExactActive, and navigate must still be implemented manually for a custom link component
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.