Vue App
Core Workflow
- Detect API style and Vue version. Check
package.jsonforvuemajor version and whether@vue/composition-apiis present. Scan changed files for<script setup>(Composition API with<script setup>) vs<script>withexport default { ... }(Options API or plain Composition API). Follow the project's dominant style; do not mix API styles within the same module boundary without explicit justification. - Validate single-file component structure. Each
.vuefile should have a clear<script setup lang="ts">(or<script>) block, a<template>block, and an optional<style scoped>. Confirmscopedor CSS Modules are used to prevent style leakage. Verify that<template>has a single logical root concept and does not contain business logic expressions longer than a single method call. - Enforce props and emits contracts. All components must declare props via
defineProps<T>()with TypeScript interface or runtime validation object. Emits must be declared viadefineEmits<T>()with typed event signatures. Never mutate props directly; usedefineModel()or explicit emit-based update patterns for two-way binding. Verify default values use the factory-function form for object/array types. - Audit reactivity correctness. Confirm
ref()is used for primitives,reactive()for objects when the entire object is the reactive unit. Flag destructuring ofreactive()objects withouttoRefs()— this breaks reactivity. Verifycomputed()getters have no side effects. Confirmwatch()andwatchEffect()callbacks clean up side effects via theonCleanupparameter or by returning cleanup functions. Flag raw.valueaccess inside<template>(auto-unwrapped in templates). - Review composable design. Composables (
use*functions insrc/composables/) must return explicitly typed reactive state and methods. They must not depend on component lifecycle implicitly; if they callonMounted,onUnmounted, orinject, document that requirement. Confirm composables are stateless-by-default or clearly document shared-state semantics. Verify cleanup of event listeners, timers, and subscriptions inonScopeDisposeoronUnmounted. - Validate state management. Pinia stores must define state, getters, and actions with clear types. Confirm
storeToRefs()is used when destructuring store state to preserve reactivity. Verify stores do not hold derived state that should be a getter. Check that actions handle async errors and do not silently swallow failures. If Vuex is present, confirm mutations are synchronous and actions handle async flows. - Check router integration. Verify route definitions in
src/router/use lazy loading (() => import(...)) for non-critical views. Navigation guards (beforeEach,beforeEnter,beforeRouteLeave) must handle bothnext()callback style and return-value style correctly based on vue-router version. Confirm guards do not perform heavy synchronous work. Verify<router-link>usestoprop with named routes or typed route objects rather than raw path strings when the project uses typed routing. - Audit async data loading. Check components using
async setup()or top-levelawaitin<script setup>are wrapped in<Suspense>by their parent with a fallback. Verify loading and error states are handled explicitly. Confirm data-fetching composables cancel in-flight requests on component unmount or parameter change. - Verify forms and v-model usage. Confirm
v-modelon custom components implements themodelValueprop +update:modelValueemit contract (ordefineModel()). Multi-value v-model uses named models (v-model:title). Verify form validation runs on submit and field-blur, and error messages are accessible (aria-describedbylinked to control). - Confirm build and test safety. Run lint, type-check (
vue-tsc), and test commands from the project. Checkvite.config.*orvue.config.*for alias resolution, proxy settings, and plugin order. Verify that environment variables follow theVITE_prefix convention (Vite) orVUE_APP_prefix (Vue CLI) and secrets are not exposed to the client bundle.
Reference Guide
| Topic | Reference | Load When |
|---|---|---|
| Vue delivery checklist | references/checklist.md |
Any Vue component, composable, store, or router change |
Constraints
- Do not mutate props; use emits or
defineModel()for parent-child state updates. - Do not destructure
reactive()objects withouttoRefs()ortoRef(); this silently breaks reactivity tracking. - Do not place side effects inside
computed()getters; usewatchorwatchEffectinstead. - Do not mix Options API and Composition API within the same component without an explicit migration rationale.
- Do not use
ref()on complex nested objects that are always mutated in-place; preferreactive()orshallowRef()to avoid unnecessary deep tracking. - Do not access Pinia store state via raw destructuring; use
storeToRefs()to preserve reactivity. - Do not eagerly import view components in router definitions; use dynamic
() => import()for code splitting. - Do not use
provide/injectas a general-purpose state bus; prefer Pinia stores for cross-component state that outlives the provider tree. - Do not expose secrets via
VITE_orVUE_APP_prefixed environment variables. - Treat changes to
vite.config.*,vue.config.*,src/router/index.*, and global plugin registrations as high-risk; verify they do not break existing routes, aliases, or build output.
Source: Shubchynskyi/garda-agent-orchestrator — distributed by TomeVault.