Lazy Loading & Transitions — Series 3

Preview — 3 of 10 questions

Given a navigation from /settings to /admin/users (a completely different, nested route), in what order do these run: the outgoing components `beforeRouteLeave`, the global `router.beforeEach`, the new routes beforeEnter, the entering component's beforeRouteEnter, and the global router.beforeResolve?

AbeforeRouteLeave (leaving component) → beforeEach (global) → beforeEnter (route-level, for each matched record in order) → beforeRouteEnter (entering component) → beforeResolve (global) → navigation confirmed → afterEach
BAll guards across every phase run simultaneously, and navigation proceeds once every single one has called next() or resolved
CbeforeEach (global) always runs first, before Vue even checks whether any component wants to prevent leaving
DbeforeRouteEnter (entering component) fires before beforeEnter (route-level), since the component itself takes priority over route configuration

Given a route /users/:id reused across navigations (/users/1/users/2), beforeRouteUpdate is the recommended way to react without remounting. When might <router-view :key="route.params.id" /> (forcing a full remount instead) genuinely be the better choice despite the extra cost?

javascript
<router-view v-slot="{ Component, route }">
  <component :is="Component" :key="route.params.id" />
</router-view>
ANever — beforeRouteUpdate is strictly better in every case, and forcing a remount via :key should be considered a bug whenever it's used
BOnly when the route has no dynamic params at all — for parameterized routes, :key has no effect either way
CWhen the component's internal state (local refs, third-party widget instances, animation state, scroll position within the component) genuinely needs to fully reset between different :id values, and there's no single clean place to manually reset every piece of that state inside beforeRouteUpdate — a full remount guarantees a clean slate by construction, trading the cost of re-running setup()/re-mounting for not having to enumerate and manually reset every piece of local state by hand
D:key="route.params.id" and beforeRouteUpdate cannot be used on the same route at all — they're mutually exclusive approaches enforced by the router

What does createAuthGuard let call sites do that a single hardcoded guard function couldn't?

javascript
function createAuthGuard(requiredRole) {
  return (to, from) => {
    if (!authStore.isLoggedIn) {
      return { path: '/login', query: { redirect: to.fullPath } }
    }
    if (requiredRole && !authStore.hasRole(requiredRole)) {
      return { path: '/forbidden' }
    }
  }
}

const routes = [
  { path: '/admin', component: AdminPanel, beforeEnter: createAuthGuard('admin') },
  { path: '/billing', component: Billing, beforeEnter: createAuthGuard('billing-manager') },
  { path: '/dashboard', component: Dashboard, beforeEnter: createAuthGuard() },
]
AcreateAuthGuard must be called fresh inside beforeEnter on every single navigation — calling it once outside, as shown, and reusing the returned function is a bug
BThis factory pattern lets each route configure exactly which role (if any) it requires, while sharing one single implementation of the underlying auth-check logic — instead of writing three near-identical guard functions (or one big function riddled with per-route conditionals), each route just calls the factory with its own specific requirement and gets back a ready-to-use guard closed over that value
CThis is functionally identical to writing beforeEnter: checkAuth on every route, just with more code
DGuard factories like this can only be used with route-level beforeEnter, never with the global router.beforeEach

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.