
Vue
Generate and refactor Vue 3 single-file components with correct Composition API, props, emits, and naming conventions in Nuxt-style projects.
Overview
Vue (Nuxt skills) is an agent skill for the Build phase that teaches Vue 3 Composition API component patterns—defineProps, defineEmits, defineModel, and naming—for script-setup SFCs.
Install
npx skills add https://github.com/onmax/nuxt-skills --skill vueWhat is this skill?
- Composition API with script setup: defineProps, defineEmits, defineModel, and slot shorthand (#header)
- Vue 3.5+ destructured props with defaults and getter-wrapped watch patterns
- PascalCase vs kebab-case file naming and general-to-specific component composition order
- Quick-reference table for props, emits, two-way binding, and template syntax
- Nuxt-skills repo context for Vue patterns alongside the broader Nuxt toolchain
Adoption & trust: 6.2k installs on skills.sh; 674 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps writing Vue components with broken prop reactivity, wrong watch usage, or inconsistent naming that does not match your Nuxt frontend conventions.
Who is it for?
Indie builders on Vue 3 or Nuxt who want agent-generated UI code to match modern Composition API standards.
Skip if: Pure React or Svelte stacks, or teams still standardized on Vue 2 Options API without migration intent.
When should I use this skill?
Implementing or reviewing Vue 3 SFCs with Composition API, props, emits, v-model, or Nuxt-aligned component structure.
What do I get? / Deliverables
Components follow typed script-setup patterns, correct destructuring and watch getters, and documented naming so features integrate cleanly into the app tree.
- Vue components matching documented props/emits/model and naming rules
Recommended Skills
Journey fit
How it compares
Reference skill for SFC structure—not a full Nuxt routing, server, or deployment playbook.
Common Questions / FAQ
Who is vue for?
Solo and small-team frontend builders using Vue 3 with script setup, especially in Nuxt-oriented repos.
When should I use vue?
In the build phase while creating or refactoring .vue components, wiring props and emits, or fixing reactivity bugs around destructured props.
Is vue safe to install?
It is documentation-only procedural guidance with no runtime hooks; review the Security Audits panel on this page like any third-party skill package.
SKILL.md
READMESKILL.md - Vue
# Vue Components Patterns for Vue 3 components using Composition API with `<script setup>`. ## Quick Reference | Pattern | Syntax | | --------------------- | --------------------------------------------------------------- | | Props (destructured) | `const { name = 'default' } = defineProps<{ name?: string }>()` | | Props (template-only) | `defineProps<{ name: string }>()` | | Emits | `const emit = defineEmits<{ click: [id: number] }>()` | | Two-way binding | `const model = defineModel<string>()` | | Slots shorthand | `<template #header>` not `<template v-slot:header>` | ## Naming **Files:** PascalCase (`UserProfile.vue`) OR kebab-case (`user-profile.vue`) - be consistent **Component names in code:** Always PascalCase **Composition:** General → Specific: `SearchButtonClear.vue` not `ClearSearchButton.vue` ## Props **Destructure with defaults (Vue 3.5+)** when used in script or need defaults: ```ts const { count = 0, message = 'Hello' } = defineProps<{ count?: number message?: string required: boolean }>() // Use directly - maintains reactivity console.log(count + 1) // ⚠️ When passing to watchers/functions, wrap in getter: watch(() => count, (newVal) => { ... }) // ✅ Correct watch(count, (newVal) => { ... }) // ❌ Won't work ``` **Non-destructured** only if props ONLY used in template: ```ts defineProps<{ count: number }>() // Template: {{ count }} ``` **Same-name shorthand (Vue 3.4+):** `:count` instead of `:count="count"` ```vue <MyComponent :count :user :items /> <!-- Same as: :count="count" :user="user" :items="items" --> ``` [Reactive destructuring docs](https://vuejs.org/guide/components/props#reactive-props-destructure) ## Emits Type-safe event definitions: ```ts const emit = defineEmits<{ update: [id: number, value: string] // multiple args close: [] // no args }>() // Usage emit('update', 123, 'new value') emit('close') ``` **Template syntax:** kebab-case (`@update-item`) vs camelCase in script (`updateItem`) ## Slots **Always use shorthand:** `<template #header>` not `<template v-slot:header>` **Always explicit `<template>` tags** for all slots ```vue <template> <Card> <template #header> <h2>Title</h2> </template> <template #default> Content </template> </Card> </template> ``` ## defineModel() - Two-Way Binding Replaces manual `modelValue` prop + `update:modelValue` emit. ### Basic ```vue <script setup lang="ts"> const title = defineModel<string>() </script> <template> <input v-model="title"> </template> ``` ### With Options ```vue <script setup lang="ts"> const [title, modifiers] = defineModel<string>({ default: 'default value', required: true, get: (value) => value.trim(), set: (value) => { if (modifiers.capitalize) { return value.charAt(0).toUpperCase() + value.slice(1) } return value }, }) </script> ``` **⚠️ Warning:** When using `default` without parent providing a value, parent and child can de-sync (parent `undefined`, child has default). Always provide matching defaults in parent or make prop required. **Prevent double-emit with `required: true`:** ```ts // ❌ Without required - emits twice (undefined then value) const model = defineModel<Item>() // ✅ With required - single emit const model = defineModel<Item>({ required: true }) ``` Use `required: true` when the model should always have a value to avoid the double-emit issue during initialization. ### Multiple Models Default assumes `modelValue` prop. For multiple bindings, use explicit names: ```vue <script setup lang="ts"> const firstName = defineModel<string>('firstName') const age = defineModel<number>('age') </script> <!-- Usage --> <UserForm v-model:first-name="user.firstName" v-model:age="user.age" /> ``` [v-model modifiers docs](https://vuejs.org/guide/compon