
vue-engineering
by vinceh
SKILL.md
name: vue-engineering description: Comprehensive guide for Vue 3 application development using modern best practices (2025). Covers Composition API, script setup syntax, reactivity system, composables, component patterns, TypeScript integration, performance optimization, and testing with Vitest. Use when building Vue 3 applications, creating components, writing composables, optimizing performance, or implementing Vue best practices.
Vue 3 Engineering
Overview
To build modern Vue 3 applications, follow industry best practices based on the Composition API, <script setup> syntax, and the 2025 ecosystem (Vite, Vitest, TypeScript). This skill provides comprehensive guidance for Vue 3 development, from component creation to production optimization.
Current Vue Version: Vue 3.5.18 (as of 2025)
Build Tool: Vite (Vue CLI is legacy)
Testing: Vitest (Jest is legacy for Vue)
Standard: Composition API with <script setup> (Options API is legacy)
Decision Tree
User Request → What are you building/fixing?
|
├─ Creating a new component?
│ └─ Use Quick Start: Creating Components (below)
│
├─ Need reusable logic?
│ ├─ Load references/composables-patterns.md
│ └─ Use asset: composable-template.ts
│
├─ State management question (ref vs reactive)?
│ └─ Load references/reactivity-guide.md
│
├─ Component communication (props/emits/slots)?
│ └─ Load references/component-patterns.md
│
├─ Performance issue or optimization?
│ └─ Load references/performance-optimization.md
│
├─ TypeScript setup or typing question?
│ └─ Load references/typescript-integration.md
│
├─ Writing tests?
│ └─ Load references/testing-guide.md
│
├─ Reviewing code or debugging?
│ └─ Load references/anti-patterns.md
│
└─ Learning Composition API basics?
└─ Load references/composition-api-guide.md
Quick Start: Creating Components
Basic Component with <script setup>
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double: {{ double }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<style scoped>
/* Component styles */
</style>
Component with Props and Emits (TypeScript)
<script setup lang="ts">
// Props
const props = defineProps<{
title: string
count?: number
}>()
// Emits
const emit = defineEmits<{
update: [value: number]
close: []
}>()
// Local state
const localCount = ref(props.count ?? 0)
// Methods
function handleUpdate() {
emit('update', localCount.value)
}
</script>
<template>
<div>
<h2>{{ title }}</h2>
<button @click="handleUpdate">Update</button>
</div>
</template>
For a complete component template, use component-template.vue.
Quick Start: Creating Composables
Composables are reusable functions that encapsulate stateful logic.
Basic Composable Pattern
import { ref, computed } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
function decrement() {
count.value--
}
return {
count,
double,
increment,
decrement
}
}
Usage in component:
<script setup>
import { useCounter } from '@/composables/useCounter'
const { count, double, increment } = useCounter(5)
</script>
For a complete composable template, use composable-template.ts.
Core Workflows
Workflow 1: Building a Component
- Create file with
.vueextension - Add
<script setup lang="ts">at top - Define props with
defineProps<T>() - Define emits with
defineEmits<T>() - Add reactive state with
ref()orreactive() - Create computed values for derived state
- Add methods as regular functions
- Use lifecycle hooks (
onMounted,onUnmounted, etc.) - Build template using component state
- Add scoped styles
Workflow 2: Creating a Composable
- Create file in
composables/directory withuse*.tsnaming - Accept options as parameter (single object preferred)
- Create reactive state with
ref()orreactive() - Add computed values for derived state
- Define methods that manipulate state
- Handle cleanup with
onUnmountedif needed - Return refs and methods as object
- Document with JSDoc and TypeScript types
Workflow 3: Optimizing Performance
- Analyze bundle with Vite plugins
- Implement lazy loading for routes and components
- Use
v-showvsv-ifappropriately - Add keys to
v-forlists - Use computed instead of methods for derived data
- Implement virtual scrolling for large lists
- Code split vendor dependencies
- Monitor with Lighthouse and Vue DevTools
Workflow 4: Testing a Component
- Setup Vitest in project
- Create
*.spec.tsfile next to component - Mount component with
@vue/test-utilsor@testing-library/vue - Test user interactions (clicks, inputs, etc.)
- Assert rendered output (not implementation details)
- Test props and emits
- Mock external dependencies
- Run tests with
npm run test
Common Patterns
Pattern 1: Form Handling
<script setup lang="ts">
import { reactive, computed } from 'vue'
interface FormData {
email: string
password: string
}
const form = reactive<FormData>({
email: '',
password: ''
})
const errors = reactive({
email: '',
password: ''
})
const isValid = computed(() => {
return form.email.includes('@') && form.password.length >= 8
})
function validate() {
errors.email = form.email.includes('@') ? '' : 'Invalid email'
errors.password = form.password.length >= 8 ? '' : 'Password too short'
}
async function handleSubmit() {
validate()
if (!isValid.value) return
// Submit form
await api.submit(form)
}
</script>
Pattern 2: API Integration
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const data = ref(null)
const loading = ref(false)
const error = ref(null)
async function fetchData() {
loading.value = true
error.value = null
try {
const response = await fetch('/api/data')
data.value = await response.json()
} catch (e) {
error.value = e.message
} finally {
loading.value = false
}
}
onMounted(() => {
fetchData()
})
</script>
<template>
<div v-if="loading">Loading...</div>
<div v-else-if="error">Error: {{ error }}</div>
<div v-else>{{ data }}</div>
</template>
Pattern 3: Modal/Dialog Component
<script setup lang="ts">
const props = defineProps<{
modelValue: boolean
title: string
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
confirm: []
}>()
function close() {
emit('update:modelValue', false)
}
function confirm() {
emit('confirm')
close()
}
</script>
<template>
<Teleport to="body">
<div v-if="modelValue" class="modal-overlay" @click="close">
<div class="modal-content" @click.stop>
<h2>{{ title }}</h2>
<slot />
<div class="modal-actions">
<button @click="close">Cancel</button>
<button @click="confirm">Confirm</button>
</div>
</div>
</div>
</Teleport>
</template>
Pattern 4: List with Virtual Scrolling
Use virtual scrolling for large lists (1000+ items):
<script setup>
// Use a virtual scrolling library like vue-virtual-scroller
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const items = ref(Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `Item ${i}`
})))
</script>
<template>
<RecycleScroller
:items="items"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div class="item">{{ item.name }}</div>
</RecycleScroller>
</template>
Best Practices (2025)
✅ Do:
- Use
<script setup>for all new components - It's the 2025 standard - Prefer
ref()overreactive()- More consistent and flexible - Extract reusable logic into composables - Keep components lean
- Use TypeScript for medium+ projects - Better DX and fewer bugs
- Test with Vitest - Modern, fast, Vite-integrated
- Lazy load routes and components - Better performance
- Use computed for derived state - Automatic caching
- Clean up side effects in
onUnmounted- Prevent memory leaks - Use Vite for builds - Faster than Webpack
- Follow naming conventions -
use*for composables,PascalCasefor components
❌ Don't:
- Don't use Options API for new projects - Legacy as of 2025
- Don't misuse
v-if/v-show- Wrong choice = 3x slower - Don't prop drill - Use provide/inject or Pinia
- Don't mutate props - Props are read-only
- Don't forget keys in
v-for- Causes rendering bugs - Don't create monolithic components - Break them down
- Don't overuse watchers - Use computed when possible
- Don't skip cleanup - Always clean up in lifecycle hooks
- Don't use Vue CLI - Use Vite + create-vue
- Don't use Jest - Use Vitest for Vue 3
Resources
This skill includes comprehensive reference guides and ready-to-use templates:
references/composition-api-guide.md
Complete guide to Vue 3 Composition API and <script setup> syntax. Covers defineProps, defineEmits, lifecycle hooks, template refs, and combining with normal <script>.
Load when: Learning Composition API, understanding <script setup>, working with props/emits, using lifecycle hooks.
references/reactivity-guide.md
Deep dive into Vue 3's reactivity system. Covers ref() vs reactive(), toRefs(), computed properties, watch() vs watchEffect(), and common reactivity pitfalls.
Load when: Choosing between ref and reactive, managing state, creating computed values, watching for changes, debugging reactivity issues.
references/composables-patterns.md
Comprehensive guide to creating reusable composables. Covers naming conventions, structure patterns, common use cases (API fetching, event listeners), VueUse examples, and testing composables.
Load when: Creating composables, extracting reusable logic, learning from VueUse patterns, testing composables.
references/component-patterns.md
Guide to Vue 3 component design patterns. Covers props (TypeScript + validation), emits (typed events), slots (default, named, scoped), provide/inject, and component composition strategies.
Load when: Designing component APIs, working with props/emits/slots, using provide/inject, composing components.
references/performance-optimization.md
Performance optimization techniques for Vue 3. Covers lazy loading, code splitting, v-show vs v-if, virtual scrolling, computed caching, bundle optimization, and Vue 3.5 performance improvements (56% memory reduction).
Load when: Optimizing performance, reducing bundle size, implementing lazy loading, debugging slow renders, analyzing builds.
references/typescript-integration.md
Complete TypeScript integration guide. Covers project setup with Vite, typing props/emits/refs, generic components, Volar extension setup, and migration from JavaScript.
Load when: Setting up TypeScript, typing components, using Volar, migrating from JavaScript, resolving type errors.
references/testing-guide.md
Testing strategies with Vitest and Testing Library. Covers Vitest setup, component testing, testing props/emits/slots, testing composables, mocking, async testing, and E2E considerations.
Load when: Writing tests, setting up Vitest, testing components/composables, mocking dependencies, debugging tests.
references/anti-patterns.md
Common Vue 3 mistakes and anti-patterns to avoid. Covers 14 anti-patterns including Options API usage, v-if/v-show misuse, prop drilling, reactivity pitfalls, memory leaks, and bundle size issues.
Load when: Reviewing code, debugging issues, learning what to avoid, code review feedback, performance problems.
assets/component-template.vue
Production-ready Vue 3 component template with TypeScript, props, emits, reactive state, computed values, methods, and lifecycle hooks. Includes scoped styles and comprehensive examples.
Use when: Creating new components, need a starting template, teaching component structure.
assets/composable-template.ts
Production-ready composable template with TypeScript, options object, reactive state, computed values, cleanup, and full JSDoc documentation. Includes useCounter example.
Use when: Creating new composables, need a starting template, learning composable structure.
assets/vite.config.template.ts
Complete Vite configuration for Vue 3 projects. Includes Vue plugin setup, path aliases, dev server config, build optimization, chunk splitting, and CSS preprocessing.
Use when: Setting up new project, configuring Vite, optimizing build, adding aliases.
Tips for Success
- Start with
<script setup>- Cleaner syntax, better performance, less boilerplate - Think in composables - Extract logic early, keep components focused on UI
- Use the template files - Don't start from scratch, use provided templates
- Load references as needed - Don't try to memorize everything, use references strategically
- Follow the decision tree - It guides you to the right resource quickly
- Use TypeScript - Even basic typing catches 80% of bugs
- Test with Vitest - Fast feedback loop, great DX
- Optimize early - Lazy load from the start, don't wait for problems
- Learn from VueUse - Study well-written composables
- Keep up with Vue updates - Vue 3.5+ brings significant improvements
Version Notes
This skill is based on:
- Vue 3.5.18 (current as of 2025)
- Composition API as standard (Options API is legacy)
- Vite 6 as build tool (Vue CLI is deprecated)
- Vitest 3 as test runner (Jest is legacy for Vue)
- Volar as IDE extension (Vetur is deprecated)
- TypeScript 5 for type safety
The Vue ecosystem has matured significantly in 2025. The Composition API with <script setup> is now the standard approach for all new Vue development.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon