Skip to content

Commit 5892b5d

Browse files
chore: install vue-best-practices skill
1 parent 4917554 commit 5892b5d

27 files changed

+5058
-0
lines changed

.agents/skills/vue-best-practices/AGENTS.md

Lines changed: 2430 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
name: vue-best-practices
3+
description: Vue.js performance optimization guidelines for building fast, maintainable applications. This skill should be used when writing, reviewing, or refactoring Vue.js code to ensure optimal performance patterns. Triggers on tasks involving Vue components, reactivity, Composition API, state management, or performance improvements.
4+
license: MIT
5+
metadata:
6+
author: vinayakkulkarni
7+
version: "1.0.0"
8+
---
9+
10+
# Vue Best Practices
11+
12+
Comprehensive performance optimization guide for Vue.js applications. Contains 40+ rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.
13+
14+
## When to Apply
15+
16+
Reference these guidelines when:
17+
- Writing new Vue components
18+
- Implementing reactive state and computed properties
19+
- Reviewing code for performance issues
20+
- Refactoring existing Vue code
21+
- Optimizing rendering and re-renders
22+
- Working with Composition API or Options API
23+
24+
## Rule Categories by Priority
25+
26+
| Priority | Category | Impact | Prefix |
27+
|----------|----------|--------|--------|
28+
| 1 | Reactivity Fundamentals | CRITICAL | `reactivity-` |
29+
| 2 | Component Performance | CRITICAL | `component-` |
30+
| 3 | Computed & Watchers | HIGH | `computed-` |
31+
| 4 | Template Optimization | MEDIUM-HIGH | `template-` |
32+
| 5 | Composition API Patterns | MEDIUM | `composable-` |
33+
| 6 | State Management | MEDIUM | `state-` |
34+
| 7 | Async & Data Fetching | LOW-MEDIUM | `async-` |
35+
| 8 | Advanced Patterns | LOW | `advanced-` |
36+
37+
## Quick Reference
38+
39+
### 1. Reactivity Fundamentals (CRITICAL)
40+
41+
- `reactivity-ref-vs-reactive` - Use ref() for primitives, reactive() for objects
42+
- `reactivity-avoid-destructure` - Don't destructure reactive objects
43+
- `reactivity-toRefs` - Use toRefs() when destructuring is needed
44+
- `reactivity-shallowRef` - Use shallowRef() for large non-reactive data
45+
- `reactivity-raw-values` - Use toRaw() for read-only operations on large data
46+
47+
### 2. Component Performance (CRITICAL)
48+
49+
- `component-v-once` - Use v-once for static content
50+
- `component-v-memo` - Use v-memo for expensive list items
51+
- `component-async` - Use defineAsyncComponent for heavy components
52+
- `component-keep-alive` - Cache component state with KeepAlive
53+
- `component-functional` - Prefer functional components for stateless UI
54+
55+
### 3. Computed & Watchers (HIGH)
56+
57+
- `computed-cache` - Use computed() for derived values, not methods
58+
- `computed-getter-only` - Avoid setters in computed when possible
59+
- `computed-dependencies` - Minimize computed dependencies
60+
- `watch-immediate` - Avoid immediate watchers, use computed instead
61+
- `watch-deep-avoid` - Avoid deep watchers on large objects
62+
- `watch-cleanup` - Always cleanup async watchers
63+
64+
### 4. Template Optimization (MEDIUM-HIGH)
65+
66+
- `template-v-show-vs-if` - v-show for frequent toggles, v-if for rare
67+
- `template-key-attribute` - Always use unique keys in v-for
68+
- `template-avoid-v-if-v-for` - Never use v-if and v-for on same element
69+
- `template-static-hoisting` - Let compiler hoist static content
70+
- `template-event-modifiers` - Use event modifiers instead of JS handlers
71+
72+
### 5. Composition API Patterns (MEDIUM)
73+
74+
- `composable-single-responsibility` - One concern per composable
75+
- `composable-return-refs` - Return refs, not reactive objects
76+
- `composable-cleanup` - Handle cleanup in composables
77+
- `composable-lazy-init` - Lazy initialize expensive resources
78+
- `composable-provide-inject` - Use provide/inject for deep prop drilling
79+
80+
### 6. State Management (MEDIUM)
81+
82+
- `state-pinia-stores` - Split stores by domain
83+
- `state-getters` - Use getters for computed state
84+
- `state-actions-mutations` - Keep mutations simple, logic in actions
85+
- `state-subscription-cleanup` - Cleanup store subscriptions
86+
87+
### 7. Async & Data Fetching (LOW-MEDIUM)
88+
89+
- `async-suspense` - Use Suspense for async component loading
90+
- `async-error-boundaries` - Handle async errors gracefully
91+
- `async-stale-while-revalidate` - Implement SWR pattern for data fetching
92+
- `async-abort-controller` - Cancel pending requests on unmount
93+
94+
### 8. Advanced Patterns (LOW)
95+
96+
- `advanced-custom-directives` - Create directives for DOM manipulation
97+
- `advanced-render-functions` - Use render functions for dynamic templates
98+
- `advanced-teleport` - Use Teleport for modals and overlays
99+
- `advanced-transition-groups` - Optimize list transitions
100+
101+
## How to Use
102+
103+
Read individual rule files for detailed explanations and code examples:
104+
105+
```
106+
rules/reactivity-ref-vs-reactive.md
107+
rules/component-v-memo.md
108+
rules/_sections.md
109+
```
110+
111+
Each rule file contains:
112+
- Brief explanation of why it matters
113+
- Incorrect code example with explanation
114+
- Correct code example with explanation
115+
- Additional context and references
116+
117+
## Full Compiled Document
118+
119+
For the complete guide with all rules expanded: `AGENTS.md`
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "vue-best-practices",
3+
"version": "1.2.1",
4+
"description": "Vue.js performance optimization best practices for AI agents",
5+
"author": {
6+
"name": "Vinayak Kulkarni",
7+
"email": "inbox.vinayak@gmail.com",
8+
"url": "https://vinayakkulkarni.dev"
9+
},
10+
"license": "MIT",
11+
"scripts": {
12+
"build": "bun run scripts/build.ts",
13+
"validate": "bun run scripts/validate.ts"
14+
}
15+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
---
2+
title: Use defineAsyncComponent for Heavy Components
3+
impact: CRITICAL
4+
impactDescription: Reduces initial bundle size, improves load time
5+
tags: component, async, lazy-loading, code-splitting
6+
---
7+
8+
## Use defineAsyncComponent for Heavy Components
9+
10+
Heavy components that aren't needed immediately should be loaded asynchronously to reduce initial bundle size.
11+
12+
**Incorrect (everything in main bundle):**
13+
14+
```vue
15+
<script setup>
16+
// BAD: All components loaded upfront
17+
import HeavyChart from './HeavyChart.vue'
18+
import RichTextEditor from './RichTextEditor.vue'
19+
import DataGrid from './DataGrid.vue'
20+
import PdfViewer from './PdfViewer.vue'
21+
</script>
22+
23+
<template>
24+
<div>
25+
<HeavyChart v-if="showChart" :data="chartData" />
26+
<RichTextEditor v-if="showEditor" v-model="content" />
27+
<DataGrid v-if="showGrid" :rows="rows" />
28+
<PdfViewer v-if="showPdf" :url="pdfUrl" />
29+
</div>
30+
</template>
31+
```
32+
33+
**Correct (lazy load heavy components):**
34+
35+
```vue
36+
<script setup>
37+
import { defineAsyncComponent, ref } from 'vue'
38+
39+
// Lazy load - only fetched when rendered
40+
const HeavyChart = defineAsyncComponent(() =>
41+
import('./HeavyChart.vue')
42+
)
43+
44+
const RichTextEditor = defineAsyncComponent(() =>
45+
import('./RichTextEditor.vue')
46+
)
47+
48+
const DataGrid = defineAsyncComponent(() =>
49+
import('./DataGrid.vue')
50+
)
51+
52+
const PdfViewer = defineAsyncComponent(() =>
53+
import('./PdfViewer.vue')
54+
)
55+
</script>
56+
57+
<template>
58+
<div>
59+
<HeavyChart v-if="showChart" :data="chartData" />
60+
<RichTextEditor v-if="showEditor" v-model="content" />
61+
<DataGrid v-if="showGrid" :rows="rows" />
62+
<PdfViewer v-if="showPdf" :url="pdfUrl" />
63+
</div>
64+
</template>
65+
```
66+
67+
**With loading and error states:**
68+
69+
```vue
70+
<script setup>
71+
import { defineAsyncComponent } from 'vue'
72+
import LoadingSpinner from './LoadingSpinner.vue'
73+
import ErrorDisplay from './ErrorDisplay.vue'
74+
75+
const HeavyChart = defineAsyncComponent({
76+
loader: () => import('./HeavyChart.vue'),
77+
loadingComponent: LoadingSpinner,
78+
errorComponent: ErrorDisplay,
79+
delay: 200, // Show loading after 200ms
80+
timeout: 10000 // Timeout after 10s
81+
})
82+
</script>
83+
```
84+
85+
**With Suspense (Vue 3.3+):**
86+
87+
```vue
88+
<template>
89+
<Suspense>
90+
<template #default>
91+
<HeavyChart :data="chartData" />
92+
</template>
93+
<template #fallback>
94+
<LoadingSpinner />
95+
</template>
96+
</Suspense>
97+
</template>
98+
99+
<script setup>
100+
import { defineAsyncComponent } from 'vue'
101+
102+
const HeavyChart = defineAsyncComponent(() =>
103+
import('./HeavyChart.vue')
104+
)
105+
</script>
106+
```
107+
108+
**Route-level code splitting (Vue Router):**
109+
110+
```typescript
111+
// router/index.ts
112+
const routes = [
113+
{
114+
path: '/dashboard',
115+
// Lazy load entire route
116+
component: () => import('@/views/Dashboard.vue')
117+
},
118+
{
119+
path: '/analytics',
120+
component: () => import('@/views/Analytics.vue'),
121+
// Webpack magic comment for chunk naming
122+
// component: () => import(/* webpackChunkName: "analytics" */ '@/views/Analytics.vue')
123+
}
124+
]
125+
```
126+
127+
**When to use async components:**
128+
129+
| Component Type | Async Load? |
130+
|---------------|-------------|
131+
| Heavy charting libraries (Chart.js, ECharts) | Yes |
132+
| Rich text editors (TipTap, Quill) | Yes |
133+
| PDF viewers | Yes |
134+
| Code editors (Monaco, CodeMirror) | Yes |
135+
| Modal content rarely opened | Yes |
136+
| Core layout components | No |
137+
| Small utility components | No |
138+
139+
Reference: [Async Components](https://vuejs.org/guide/components/async.html)

0 commit comments

Comments
 (0)