Vue Cookbook
“How would you do X?” — practical, production-ready recipes with the approach, full code, pitfalls and variations.
Vue
- Access child component methods with template refs and defineExposeA parent needs to focus an input or reset a form inside a child component.
- Add SEO metadata and structured data in NuxtProduct pages have generic titles, no social previews and no structured data.
- Build an accessible modal with TeleportModals render inside overflow-hidden containers, trap nobody's focus and can't be closed with Escape.
- Build custom inputs with defineModel and modifiersA custom input component needs v-model support with trimming or number conversion.
- Catch component errors with an error boundaryOne failing widget crashes the whole page with a blank screen.
- Debounce user input with a custom refExpensive work (search requests, validation) runs on every keystroke.
- Fetch data in a composable and cancel stale requestsTyping in a search box fires overlapping requests, and slow old responses overwrite newer results.
- Fetch, refresh and share data with Nuxt useFetchPages refetch data in the browser after SSR, and lists don't update after mutations.
- Implement a dark mode toggle that respects system settingsUsers want light, dark or system theme, remembered across visits, without a flash of the wrong theme.
- Lazy-load and lazily hydrate heavy componentsA chart library and comments widget make the initial page slow, even though they're below the fold.
- Lazy-load routes and keep navigation fastThe initial bundle includes every page, and the first visit to a page shows a blank screen.
- Load more items with infinite scrollA long list should load the next page as users approach the end, without scroll listeners.
- Manage configuration and secrets with Nuxt runtime configAPI keys end up in the client bundle, and changing a URL requires a rebuild.
- Persist a Pinia store to localStorageThe cart or preferences disappear when users reload the page.
- Protect routes with Vue Router navigation guardsLogged-out users can open account pages, and after login they lose the page they wanted.
- Render large lists efficientlyA table with thousands of rows makes typing and scrolling sluggish.
- Share state down the tree with typed provide/injectDeeply nested components need theme or form context without prop drilling.
- Test components with Vitest and Vue Test UtilsUI changes break forms and buttons without anyone noticing until production.
- Validate forms with zod in a composableForm validation logic is scattered across components with inconsistent messages.
- Validate input in Nuxt server routesAPI routes trust request bodies and query strings, returning 500s on bad input.