vuelisted
Install: claude install-skill zhaojiannet/canon
This skill enforces Vue 3.5+ single-file component conventions. Composition API + `<script setup>` only; type-safe declarations; modern macros (`defineModel` / `useTemplateRef` / `useId`).
Apply only when the project uses `vue ^3.5` or higher. If `package.json` pins `vue ^3.4` or earlier, **STOP** and ask the user — 3.5+ APIs (`useId`, `useTemplateRef`, reactive props destructure, `onWatcherCleanup`) won't work. Do not write 2.x compatibility code.
## Core principles
- **`<script setup>` only**, no Options API (`data()` / `methods` / `computed: {}` / `watch: {}` / `mounted` / `mixins`).
- **TypeScript type declarations for props/emits**, not runtime `defineProps([...])` array or `PropType` imports.
- **`defineModel()` for `v-model`**, not manual `props/emits` pairs.
- **`useTemplateRef()` for template refs** (Vue 3.5+), not the legacy static-ref binding.
- **`useId()` for stable IDs** in form/a11y, not `Math.random()` / module-level counters.
- **Reactive props destructure** (Vue 3.5+) over `withDefaults()` / `props.foo`.
- **Composables for shared logic**, not mixins.
## Required form
```vue
<script setup lang="ts">
import { computed, useTemplateRef, useId } from 'vue'
// Props (type declaration + reactive destructure with defaults)
const { items, selected = [] } = defineProps<{
items: Item[]
selected?: string[]
}>()
// Emits (type declaration)
const emit = defineEmits<{
change: [id: string]
delete: [id: string]
}>()
// v-model (3.4+)
const modelValue = defin