{
"title": "10 Essential Prompts for Vue.js and Nuxt: Components, Composables, Routing, and Stores",
"content": "## Introduction\n\nBuilding modern web applications with Vue.js and Nuxt requires more than just mastering the framework's syntax—it demands efficient workflows and reusable patterns. As a frontend developer, you've likely spent hours debugging reactive state, structuring composables, or optimizing component reusability. The right prompts can transform how you interact with AI coding assistants, turning routine tasks into rapid implementations.\n\nThis article provides a curated collection of 10 ready-to-use prompts for Vue.js and Nuxt development, covering components, composables, routing, state management with Pinia, and performance optimization. Each prompt includes a clear use case, a practical example, and expert insights based on official Vue.js documentation (vuejs.org) and Nuxt best practices (nuxt.com). Whether you're a junior developer looking to accelerate learning or a senior architect seeking consistent patterns, these prompts will save you time and improve code quality.\n\n## Why Use Prompts for Vue.js and Nuxt?\n\nPrompt engineering for code generation isn't about replacing developer judgment—it's about automating boilerplate, enforcing conventions, and exploring edge cases quickly. According to the Vue.js official style guide (vuejs.org/style-guide), consistent component naming, prop definitions, and composition API patterns reduce bugs and improve team collaboration. Prompts help you adhere to these standards without manual repetition.\n\nFor Nuxt, where file-based routing, server-side rendering, and auto-imports add complexity, prompts can scaffold entire feature modules in seconds. The Nuxt documentation (nuxt.com/docs) emphasizes that composables should be reusable and testable—a well-crafted prompt ensures your composables follow these principles from the start.\n\n## 10 Essential Prompts for Vue.js and Nuxt\n\n### 1. Generate a Reusable Vue Component with TypeScript Props\n\nTask: Create a Vue 3 component using the Composition API with TypeScript, including typed props, emits, and slots.\n\nPrompt:\n\nGenerate a Vue 3 single-file component named 'UserCard' using the Composition API with TypeScript. Include:\n- Props: id (number), name (string), email (string), avatarUrl (string, optional)\n- Emits: 'update:name' with payload string, 'delete' with payload number\n- A default slot for additional content\n- Scoped styles with a card layout (border, padding, box-shadow)\n- Use defineComponent and defineProps/defineEmits macros\n\n\nExample Output:\nvue\n<script setup lang=\"ts\">\nimport { defineProps, defineEmits } from 'vue'\n\ninterface UserCardProps {\n id: number\n name: string\n email: string\n avatarUrl?: string\n}\n\nconst props = defineProps<UserCardProps>()\nconst emit = defineEmits<{\n 'update:name': [payload: string]\n 'delete': [payload: number]\n}>()\n</script>\n\n<template>\n <div class=\"card\">\n <img v-if=\"props.avatarUrl\" :src=\"props.avatarUrl\" alt=\"avatar\" />\n <div class=\"info\">\n <h3>{{ props.name }}</h3>\n <p>{{ props.email }}</p>\n </div>\n <slot />\n </div>\n</template>\n\n<style scoped>\n.card { border: 1px solid #ccc; padding: 1rem; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n.info { margin-top: 0.5rem; }\n</style>\n\n\nExpert Tip: Always define explicit emits to improve component contract clarity and enable TypeScript validation. The Vue Style Guide recommends this approach for all reusable components.\n\n### 2. Create a Composable for API Data Fetching with Loading and Error States\n\nTask: Build a composable that fetches data from an API, handles loading and error states, and supports cancellation.\n\nPrompt:\n\nWrite a Vue composable called 'useApiFetch' that:\n- Accepts a URL string and an optional options object (method, headers, body)\n- Returns reactive refs: data (null by default), error (null), isLoading (boolean)\n- Uses AbortController to cancel the request on component unmount\n- Automatically unwraps JSON response\n- Includes TypeScript generics for the response type\n- Uses the fetch API (not axios)\n\n\nExample Output:\n```typescript\nimport { ref, onUnmounted } from 'vue'\n\ninterface UseApiFetchOptions extends RequestInit {}\n\nexport function useApiFetch
| null>(null)\n const error = ref {{ product.description }} Unread: {{ unreadCount }}HTTP error! status: ${response.status})\n data.value = await response.json()\n } catch (err) {\n if (err instanceof Error && err.name !== 'AbortError') {\n error.value = err\n }\n } finally {\n isLoading.value = false\n }\n }\n\n onUnmounted(() => controller.abort())\n\n return { data, error, isLoading, execute }\n}\n\n\n**Expert Tip:** In Nuxt, you can extend this composable to use `useAsyncData` or `useFetch` for SSR-friendly data fetching. The Nuxt documentation suggests using the built-in `useFetch` for most cases, but this custom composable gives you full control.\n\n### 3. Build a Dynamic Form with Validation Using VeeValidate or Vuelidate\n\n**Task:** Create a login form component with validation using the Composition API.\n\n**Prompt:**\n\nGenerate a Vue 3 login form component using VeeValidate (v4) with the Composition API. Include:\n- Fields: email (required, valid email format), password (required, min 8 characters)\n- Show validation errors inline below each field\n- Submit button disabled until form is valid\n- On submit, call an async function 'handleLogin' that simulates an API call\n- Use Form and Field components from vee-validate\n- Use yup for schema validation\n\n\n**Example Output:**\nvue\n\n\n\n \n\n\n\n**Expert Tip:** For complex forms, consider using `useForm` from VeeValidate to manage form state outside the template. This keeps your component clean and testable.\n\n### 4. Scaffold a Nuxt Page with Dynamic Route Parameters and SEO Meta\n\n**Task:** Create a Nuxt 3 page that uses dynamic routing and sets SEO meta tags.\n\n**Prompt:**\n\nGenerate a Nuxt 3 page component located at 'pages/products/[id].vue' that:\n- Uses useRoute() to get the product ID from route params\n- Uses useAsyncData to fetch product data from '/api/products/[id]'\n- Sets page title and meta description using useHead()\n- Displays loading state, error state, and product details (name, price, description)\n- Includes a "Back to products" link\n\n\n**Example Output:**\nvue\n\n\n\n {{ product.name }}
\n \n\n**Expert Tip:** Use `definePageMeta` for static meta, but `useHead` is more dynamic and reactive. Nuxt 3's `useHead` is powered by Unhead, which supports advanced features like Open Graph tags and JSON-LD.\n\n### 5. Create a Pinia Store for User Authentication\n\n**Task:** Implement a Pinia store managing user authentication state with login, logout, and token persistence.\n\n**Prompt:**\n\nWrite a Pinia store called 'useAuthStore' that:\n- Uses defineStore with the setup function syntax\n- State: user (null | object), token (string | null), isAuthenticated (computed)\n- Actions: login(email, password) — calls API, stores token in localStorage; logout() — clears state and localStorage\n- Uses a composable 'useApi' for HTTP requests (assume it exists)\n- On store initialization, check localStorage for a token and restore user state\n- Include TypeScript types for User and LoginResponse\n\n\n**Example Output:**\ntypescript\nimport { defineStore } from 'pinia'\nimport { ref, computed } from 'vue'\n\ninterface User {\n id: number\n email: string\n name: string\n}\n\ninterface LoginResponse {\n token: string\n user: User\n}\n\nexport const useAuthStore = defineStore('auth', () => {\n const user = ref\n\n**Expert Tip:** Pinia stores are modular by design. For larger apps, split auth logic into separate stores (e.g., `useAuthStore` for state, `useAuthActions` for API calls). The Pinia documentation (pinia.vuejs.org) recommends this for maintainability.\n\n### 6. Implement a Debounced Search with Composables\n\n**Task:** Build a composable that debounces a search input and performs API calls.\n\n**Prompt:**\n\nCreate a Vue composable 'useDebouncedSearch' that:\n- Takes a search function (async, accepts query string) and debounce delay (default 300ms)\n- Returns: query (ref string), results (ref), isSearching (ref), search (function to trigger immediate)\n- Cancels previous request if new one is triggered before debounce\n- Uses watchEffect to automatically trigger search when query changes\n\n\n**Example Output:**\ntypescript\nimport { ref, watch, type Ref } from 'vue'\n\nexport function useDebouncedSearch\n\n**Expert Tip:** For Nuxt, consider using `useFetch` with `watch` option instead of manual debounce—it supports reactive refs and cancellation out of the box.\n\n### 7. Generate a Reusable Table Component with Sorting and Filtering\n\n**Task:** Create a generic table component that accepts data and column definitions, with client-side sorting and filtering.\n\n**Prompt:**\n\nCreate a Vue 3 component 'DataTable' that:\n- Props: columns (array of { key: string, label: string, sortable?: boolean }), data (array of objects)\n- Emits: 'row-click' with row data\n- Features: click column header to sort ascending/descending, filter input for each column\n- Use computed properties for sorted and filtered data\n- Scoped slots for custom cell rendering\n\n\n**Example Output (abbreviated):**\nvue\n\n\n\n**Expert Tip:** For large datasets (1000+ rows), consider using a virtual scroller like `vue-virtual-scroller` to maintain performance. The table above works well for moderate data sizes.\n\n### 8. Create a Composable for Local State Persistence (localStorage)\n\n**Task:** Build a composable that syncs reactive state with localStorage.\n\n**Prompt:**\n\nWrite a Vue composable 'useLocalStorage' that:\n- Accepts a key (string) and default value (generic type)\n- Returns a ref that is synced with localStorage\n- Updates localStorage on value change using watch\n- Handles JSON serialization/deserialization\n- Throws a warning if localStorage is unavailable (e.g., in SSR)\n\n\n**Example Output:**\ntypescript\nimport { ref, watch, type Ref } from 'vue'\n\nexport function useLocalStorageuseLocalStorage: unable to read key \"${key}\")\n return defaultValue\n }\n })()\n\n const data = refuseLocalStorage: unable to save key \"${key}\", e)\n }\n }, { deep: true })\n\n return data\n}\n\n\n**Expert Tip:** In Nuxt, avoid using localStorage in the setup function because it runs on the server. Use `onMounted` or check `process.client` before accessing browser APIs.\n\n### 9. Scaffold a Nuxt Middleware for Route Protection\n\n**Task:** Create a route middleware that redirects unauthenticated users to the login page.\n\n**Prompt:**\n\nGenerate a Nuxt 3 route middleware named 'auth' that:\n- Checks if the user is authenticated (use useAuthStore)\n- If not authenticated, redirect to '/login'\n- Uses navigateTo for redirection\n- Works for both client and server-side navigation\n- Place the middleware in middleware/auth.ts\n\n\n**Example Output:**\ntypescript\nexport default defineNuxtRouteMiddleware((to, from) => {\n const authStore = useAuthStore()\n \n if (!authStore.isAuthenticated) {\n // Store the original route to redirect back after login\n return navigateTo({\n path: '/login',\n query: { redirect: to.fullPath }\n })\n }\n})\n\n\n**Expert Tip:** For global middleware, name the file `auth.global.ts`. Nuxt automatically applies global middleware to all routes. Use `definePageMeta({ middleware: 'auth' })` for per-page protection.\n\n### 10. Optimize Component Performance with v-memo and shallowRef\n\n**Task:** Optimize a component that renders a large list with frequent updates.\n\n**Prompt:**\n\nRewrite the following Vue component using performance optimizations:\n- Use shallowRef for large arrays of objects to avoid deep reactivity overhead\n- Use v-memo on list items that depend only on item.id and item.updatedAt\n- Use computed for derived data (e.g., filtered list)\n- Explain each optimization\n\nOriginal component: a list of 10,000 items with a toggle button to mark items as read.\n\n\n**Example Output:**\nvue\n\n\n\n ``\n\n**Expert Tip:**v-memo` is a Vue 3.2+ feature that memoizes a template fragment based on its dependency array. It's especially useful in large lists where only a few items change per update.\n\n## Conclusion\n\nThese 10 prompts cover the most common tasks in Vue.js and Nuxt development—from components and composables to routing, state management, and performance. By integrating them into your daily workflow, you can reduce boilerplate, enforce best practices, and accelerate feature delivery.\n\nRemember that prompts are not a replacement for understanding the underlying concepts. Always review generated code against official documentation and your project's specific requirements. The Vue.js ecosystem evolves rapidly, so keep your prompts up-to-date with framework changes.\n\nStart by copying the prompts that solve your immediate pain points, then customize them to match your coding style. Over time, you'll build a personal library of prompts that make you a more efficient Vue.js developer.",
"excerpt": "A practical collection of 10 ready-to-use prompts for Vue.js and Nuxt development, covering components, composables, routing, Pinia stores, and performance optimization. Each prompt includes a clear use case, example output, and expert tips based on official documentation."
}
Comments