SuperAPI AI Directory

vue

Frontend & websites

View repository

Updated 10-16 15:55

About this skill

Vue 3

Default <script setup> + Composition API. Stacks other than Vue (build tools, CSS, state libraries, TS version) follow the project; do not specify them in this skill.

Do not write APIs from training data. First determine the minor version, then read the corresponding reference.

Determine version

  1. Read the installed vue version.
  2. Take minor(3.4.x → 3.4), open the file in the table below, and write code according to that file.
minor File
3.4 references/3.4.md
3.5 references/3.5.md

For newer minors not listed: start from the highest covered minor, then consult the official changelog / docs for that minor. For older minors: do not use the new APIs in this skill.

Choose reactive APIs

Do not ref for everything. Choose based on whether the whole value is replaced, whether fields are modified in place, and whether deep tracking is needed.

API Use for
ref values that will bewholly replaced: primitive types, toggles, current id, objects replaced as a whole
reactive structures that modify fields in place, especially forms, drafts, and a group of related fields
shallowRef Only care about .value replacement: large lists, third-party instances, immutable snapshots. Internal field changes do not notify
shallowReactive Only care about root properties; treat nested as immutable
markRaw Never tracked
triggerRef When it must notify after modifying the internals of shallowRef (prefer directly replacing .value)
customRef Control track/trigger yourself (e.g., debounce)
computed See the next section,not needed by default
Regular variables Do not drive the view, do not participate in derivation

ref(obj) Internally it also deep-proxies, just with an extra layer of .value. For forms use reactive, not ref({ name, email })。

If a list needs to track element fields, use ref([]); if it only updates when the whole list is replaced, use shallowRef。

computed

Fixed structure with only one reactive segment embedded (such as a propsin config) → pass the object literal by reference, do not wrap it in computed. Otherwise the dependency is attached to the outer layer, and changing the outer layer re-renders the whole page.

const field = { component: Input, label: "姓名", props: form };

Do not { ...form }. Use computed only for a new list after filtering/sorting, or for expensive derivations reused in multiple places.

Components and data flow

  • Do not let a single file grow into a giant (about 500 lines); put orchestration in routes/entry, split UI blocks and useXxx out.
  • Props down, events up. Across layers:provide/inject or the project's existing store.
  • Reactive objects between componentspass directly. Do not copy and then sync them yourself; when reset is needed, save an initial snapshot separately.
  • For child component v-model use defineModel, do not hand-write modelValue + update:modelValue:
const model = defineModel<string>({ required: true });
const title = defineModel<string>("title");
const [value, modifiers] = defineModel({ set: (v) => (modifiers.trim ? v.trim() : v) });
  • Use shorthand for same-name bindings:<img :id :src :alt>。
  • defineOptions / defineSlots / <script setup generic="T"> use directly.
  • For composable parameters use MaybeRefOrGetter, internally toValue(). Clean up side effects in onScopeDispose(do not write only onUnmounted)。

Update cost

  • For list :key use stable ids.
  • Keep props passed to list items as stable as possible: compute active before passing, do not have every item receive a changing activeId。
  • Heavy, rarely used components behind pagination:defineAsyncComponent(For the SSR hydration strategy, see 3.5).
  • Drag / mousemove / Scroll: isolate hot state into small child components or shallowRef, and do not let the entire page template re-run.