{"id":"0958def4-b421-4287-a629-b9d4213fae60","shortId":"7JfJK5","kind":"skill","title":"vue","tagline":"Auto-activate for .vue files, vue.config.js. Expert knowledge for Vue 3 development with TypeScript. Use when: building Vue components (`.vue` files), using Composition API (`<script setup>`), or managing Vue SFC state. Not for React (see react), Svelte (see svelte), or Vue 2 Opt","description":"# Vue 3 Framework Skill\n\n<workflow>\n\n## Quick Reference\n\n### Composition API Component\n\n<example>\n\n```vue\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\n\ninterface Props {\n  title: string;\n  items: Item[];\n}\n\nconst props = defineProps<Props>();\nconst emit = defineEmits<{\n  select: [item: Item];\n}>();\n\nconst selected = ref<Item | null>(null);\nconst count = computed(() => props.items.length);\n\nfunction handleSelect(item: Item) {\n  selected.value = item;\n  emit('select', item);\n}\n\nonMounted(() => {\n  console.log('Component mounted');\n});\n</script>\n\n<template>\n  <div>\n    <h2>{{ title }} ({{ count }})</h2>\n    <ul>\n      <li\n        v-for=\"item in items\"\n        :key=\"item.id\"\n        @click=\"handleSelect(item)\"\n      >\n        {{ item.name }}\n      </li>\n    </ul>\n  </div>\n</template>\n```\n\n</example>\n\n### Composables\n\n<example>\n\n```ts\n// composables/useFetch.ts\nimport { ref, watchEffect, type Ref } from 'vue';\n\nexport function useFetch<T>(url: Ref<string> | string) {\n  const data = ref<T | null>(null) as Ref<T | null>;\n  const loading = ref(true);\n  const error = ref<Error | null>(null);\n\n  watchEffect(async () => {\n    loading.value = true;\n    error.value = null;\n\n    try {\n      const urlValue = typeof url === 'string' ? url : url.value;\n      const res = await fetch(urlValue);\n      if (!res.ok) throw new Error(`HTTP ${res.status}`);\n      data.value = await res.json();\n    } catch (e) {\n      error.value = e instanceof Error ? e : new Error(String(e));\n    } finally {\n      loading.value = false;\n    }\n  });\n\n  return { data, loading, error };\n}\n```\n\n</example>\n\n### Provide/Inject Pattern\n\n<example>\n\n```ts\n// context/theme.ts\nimport { provide, inject, ref, type InjectionKey, type Ref } from 'vue';\n\ntype Theme = 'light' | 'dark';\nconst ThemeKey: InjectionKey<{\n  theme: Ref<Theme>;\n  toggle: () => void;\n}> = Symbol('theme');\n\nexport function provideTheme() {\n  const theme = ref<Theme>('light');\n  const toggle = () => {\n    theme.value = theme.value === 'light' ? 'dark' : 'light';\n  };\n  provide(ThemeKey, { theme, toggle });\n}\n\nexport function useTheme() {\n  const context = inject(ThemeKey);\n  if (!context) throw new Error('useTheme requires ThemeProvider');\n  return context;\n}\n```\n\n</example>\n\n### v-model with Components\n\n<example>\n\n```vue\n<script setup lang=\"ts\">\nconst model = defineModel<string>({ required: true });\n\n// Or with options\nconst count = defineModel<number>('count', { default: 0 });\n</script>\n\n<template>\n  <input v-model=\"model\" />\n</template>\n```\n\n</example>\n\n### Async Components\n\n<example>\n\n```ts\nimport { defineAsyncComponent } from 'vue';\n\nconst AsyncModal = defineAsyncComponent({\n  loader: () => import('./Modal.vue'),\n  loadingComponent: LoadingSpinner,\n  delay: 200,\n  errorComponent: ErrorDisplay,\n});\n```\n\n</example>\n\n</workflow>\n\n## Best Practices\n\n- Use `<script setup>` for cleaner syntax\n- Prefer Composition API over Options API\n- Use TypeScript with `defineProps<T>()` and `defineEmits<T>()`\n- Extract reusable logic into composables\n- Use `shallowRef` for large objects that don't need deep reactivity\n- Avoid mutating props directly\n\n## References Index\n\n- **[Litestar-Vite Integration](references/litestar_vite.md)** — Backend integration with Litestar-Vite plugin.\n\n## Deployment\n\n### Build Production\n\nVue applications are built into static assets using Vite.\n\n```bash\nvite build\n```\n\n### Strategy\n\nDeploy to static runners or reverse proxies. For Inertia apps, bundle assets inside the backend build directory for joint deployment.\n\n---\n\n## CI/CD Actions\n\n<example>\n\nExample GitHub Actions workflow for building:\n\n```yaml\nname: Vue CI\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - name: Setup Node\n        uses: actions/setup-node@v4\n        with:\n          node-version: '22'\n          cache: 'npm'\n\n      - run: npm ci\n      - run: npm run build\n```\n\n</example>\n\n## Official References\n\n- <https://vuejs.org/guide/introduction.html>\n- <https://vuejs.org/guide/typescript/overview.html>\n- <https://vuejs.org/guide/components/v-model.html>\n- <https://github.com/vuejs/core/releases>\n- <https://vite.dev/guide/>\n- <https://inertiajs.com/docs/v2/installation/client-side-setup>\n\n## Shared Styleguide Baseline\n\n- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n- [General Principles](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)\n- [Vue](https://github.com/cofin/flow/blob/main/templates/styleguides/frameworks/vue.md)\n- [TypeScript](https://github.com/cofin/flow/blob/main/templates/styleguides/languages/typescript.md)\n- Keep this skill focused on tool-specific workflows, edge cases, and integration details.\n\n<guardrails>\n## Guardrails\n\n- **Always use `<script setup>` with TypeScript** -- This is the modern standard for Vue 3; provides better IDE support and less boilerplate.\n- **Never mutate props directly** -- Props are read-only; use `emit` to notify the parent of changes or use `computed` with a setter.\n- **Prefer Composables for shared logic** -- Avoid Mixins or global state; extract logic into reusable `use*` functions to keep components focused on UI.\n- **Use `defineProps` and `defineEmits` macros** -- These are compiler macros; do not import them. Use the type-based declaration for best DX.\n- **Avoid direct DOM manipulation** -- Use `ref` for DOM elements only when necessary; prefer Vue's declarative directives (`v-bind`, `v-if`, `v-for`).\n</guardrails>\n\n<validation>\n## Validation Checkpoint\n\n- [ ] Component uses `<script setup lang=\"ts\">`\n- [ ] Props and Emits are defined using type-based declarations (`defineProps<T>()`)\n- [ ] No direct mutations of props are present\n- [ ] Reusable logic is extracted into a composable if it exceeds 30-40 lines\n- [ ] `v-for` elements have a unique and stable `:key`\n- [ ] No direct DOM manipulation (e.g., `document.querySelector`) is used where Vue directives suffice\n</validation>","tags":["vue","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-vue","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/vue","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (6,005 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T07:03:21.082Z","embedding":null,"createdAt":"2026-04-23T13:04:02.825Z","updatedAt":"2026-04-24T07:03:21.082Z","lastSeenAt":"2026-04-24T07:03:21.082Z","tsv":"'/modal.vue':205 '200':209 '3':13 'activ':4 'api':26 'async':79,193 'asyncmod':201 'auto':3 'auto-activ':2 'await':94,105 'best':212 'build':19 'catch':107 'click':38 'compon':21,191,194 'compos':42 'composables/usefetch.ts':44 'composit':25 'const':58,68,72,85,92,143,155,159,173,200 'context':174,178,186 'context/theme.ts':128 'count':28 'dark':142,164 'data':59,122 'data.value':104 'defineasynccompon':197,202 'delay':208 'develop':14 'e':108,110,113,117 'error':73,75,101,112,115,124,181 'error.value':82,109 'errorcompon':210 'errordisplay':211 'expert':9 'export':52,152,170 'fals':120 'fetch':95 'file':7,23 'final':118 'function':53,153,171 'handleselect':39 'http':102 'import':45,129,196,204 'inject':131,175 'injectionkey':134,145 'instanceof':111 'item':33,35,40 'item.id':37 'item.name':41 'key':36 'knowledg':10 'li':29 'light':141,158,163,165 'load':69,123 'loader':203 'loading.value':80,119 'loadingcompon':206 'loadingspinn':207 'model':189 'new':100,114,180 'null':62,63,67,76,77,83 'pattern':126 'practic':213 'provid':130,166 'provide/inject':125 'providethem':154 'ref':46,49,56,60,65,70,74,132,136,147,157 'requir':183 'res':93 'res.json':106 'res.ok':98 'res.status':103 'return':121,185 'skill' 'skill-vue' 'source-cofin' 'string':57,89,116 'symbol':150 'theme':140,146,151,156,168 'theme.value':161,162 'themekey':144,167,176 'themeprovid':184 'throw':99,179 'titl':27 'toggl':148,160,169 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'tri':84 'true':71,81 'ts':43,127,195 'type':48,133,135,139 'typeof':87 'typescript':16 'url':55,88,90 'url.value':91 'urlvalu':86,96 'use':17,24,214 'usefetch':54 'usethem':172,182 'v':31,188 'v-for':30 'v-model':187 'void':149 'vue':1,6,12,20,22,51,138,192,199 'vue.config.js':8 'watcheffect':47,78","prices":[{"id":"764b09d6-3c5b-4bd3-ac67-12a539eacc14","listingId":"0958def4-b421-4287-a629-b9d4213fae60","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:04:02.825Z"}],"sources":[{"listingId":"0958def4-b421-4287-a629-b9d4213fae60","source":"github","sourceId":"cofin/flow/vue","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/vue","isPrimary":false,"firstSeenAt":"2026-04-23T13:04:02.825Z","lastSeenAt":"2026-04-24T07:03:21.082Z"}],"details":{"listingId":"0958def4-b421-4287-a629-b9d4213fae60","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"vue","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-19T23:22:27Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"5b1ba547a46132eddbdb5cf3f5e4e6eb8aef1ad2","skill_md_path":"skills/vue/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/vue"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"vue","description":"Auto-activate for .vue files, vue.config.js. Expert knowledge for Vue 3 development with TypeScript. Use when: building Vue components (`.vue` files), using Composition API (`<script setup>`), or managing Vue SFC state. Not for React (see react), Svelte (see svelte), or Vue 2 Options API."},"skills_sh_url":"https://skills.sh/cofin/flow/vue"},"updatedAt":"2026-04-24T07:03:21.082Z"}}