
vue-best-practices
热门MUST be used for Vue.js tasks. Strongly recommends Composition API with `<script setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.
MUST be used for Vue.js tasks. Strongly recommends Composition API with `<script setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.
Vue 3 best practices, common gotchas, and performance optimization.
Reactivity
- Accessing ref() values without .value in scripts → See ref-value-access
- Destructuring reactive() objects, losing reactivity → See reactive-destructuring
- Choosing between ref() and reactive() for state → See prefer-ref-over-reactive
- Accessing refs inside arrays and collections → See refs-in-collections-need-value
- Large objects or external library data overhead → See shallow-ref-for-performance
- Using nested refs in template expressions → See template-ref-unwrapping-top-level
- Comparing reactive objects with === operator → See reactivity-proxy-identity-hazard
- Library instances breaking in reactive state → See reactivity-markraw-for-non-reactive
- Expecting watchers to fire for each state change → See reactivity-same-tick-batching
- Integrating external state management libraries → See reactivity-external-state-integration
- Deriving state with watchEffect instead of computed → See reactivity-computed-over-watcheffect-mutations
Computed
- Computed getter is making API calls or mutations → See computed-no-side-effects
- Mutating computed values causes lost changes unexpectedly → See computed-return-value-readonly
- Computed property doesn't update when expected → See computed-conditional-dependencies
- Sorting or reversing arrays destroys original data → See computed-array-mutation
- Expensive operations running too frequently every render → See computed-vs-methods-caching
- Trying to pass arguments to computed properties → See computed-no-parameters
- Complex conditions bloating inline class bindings → See computed-properties-for-class-logic
Watchers
- Need to watch a reactive object property → See watch-reactive-property-getter
- Large nested data structures causing performance issues → See watch-deep-performance
- Dependencies accessed after await not tracking → See watcheffect-async-dependency-tracking
- Need to access updated DOM in watchers → See watch-flush-timing
- Uncertain whether to use watch or watchEffect → See watch-vs-watcheffect
- Duplicating initial calls and watch callbacks → See watch-immediate-option
- Can't compare old and new values correctly → See watch-deep-same-object-reference
- Template refs appearing null or stale → See watcheffect-flush-post-for-refs
Components
- Prop values being changed from a child component → See props-are-read-only
- Grandparent can't listen to grandchild emitted events → See component-events-dont-bubble
- Distinguishing Vue components from native elements → See component-naming-pascalcase
- Recursive component needs to reference itself → See self-referencing-component-name
- Bundle includes components that aren't used → See prefer-local-component-registration
- Tight coupling through component ref access → See prefer-props-emit-over-component-refs
Props & Emits
- Boolean prop not parsing as expected → See prop-boolean-casting-order
- Composable doesn't update when props change → See prop-composable-reactivity-loss
- Destructured props not updating watchers → See prop-destructured-watch-getter
- Prop validation needs component instance data → See prop-validation-before-instance
- Event name inconsistency in templates and scripts → See emit-kebab-case-in-templates
- Event payloads need validation during development → See emit-validation-for-complex-payloads
Templates
- Rendering untrusted user content as HTML → See v-html-xss-security
- Filtering or conditionally hiding list items → See no-v-if-with-v-for
- Functions in templates modifying data unexpectedly → See template-functions-no-side-effects
- Performance issues with filtered or sorted lists → See v-for-use-computed-for-filtering
- Deciding between v-if and v-show for conditionals → See v-if-vs-v-show-performance
Forms & v-model
- Need to handle v-model modifiers in child → See definemodel-hidden-modifier-props
- Need to use updated value immediately after change → See definemodel-value-next-tick
- Migrating Vue 2 components to Vue 3 → See v-model-vue3-breaking-changes
Events & Modifiers
- Need to handle same event only one time → See event-once-modifier-for-single-use
- Keyboard shortcuts fire with unintended modifier combinations → See exact-modifier-for-precise-shortcuts
- Using left-handed mouse or non-standard input devices → See mouse-button-modifiers-intent
- Preventing default browser action and scroll performance together → See no-passive-with-prevent
Lifecycle
- Lifecycle hooks don't execute asynchronously → See lifecycle-hooks-synchronous-registration
- Expensive operations slow performance drastically → See updated-hook-performance
Slots
- Accessing child component data in slot content → See slot-render-scope-parent-only
- Mixing named and scoped slots together → See slot-named-scoped-explicit-default
- Using v-slot on native HTML elements → See slot-v-slot-on-components-or-templates-only
- Empty wrapper elements rendering unnecessarily → See slot-conditional-rendering-with-slots
- Scoped slot props lack TypeScript type safety → See slot-define-slots-for-typescript
- Rendering empty component slots without defaults → See slot-fallback-content-default-values
- Confused about which slot content goes where → See slot-implicit-default-content
- Expecting name property in scoped slot props → See slot-name-reserved-prop
- Choosing between renderless components and composables → See slot-renderless-components-vs-composables
Provide/Inject
- String keys collide in large applications → See provide-inject-symbol-keys
- State mutations scattered across components → See provide-inject-mutations-in-provider
- Passing props through many component layers → See avoid-prop-drilling-use-provide-inject
Attrs
- Accessing hyphenated attributes in JavaScript code → See attrs-hyphenated-property-access
- Watching fallthrough attributes for changes with watch() → See attrs-not-reactive
Composables
- Composable has unexpected side effects affecting external state → See composable-avoid-hidden-side-effects
- Building complex logic from smaller focused composables → See composable-composition-pattern
- Inconsistent composable names or destructuring loses reactivity → See composable-naming-return-pattern
- Composable has many optional parameters or confusing argument order → See composable-options-object-pattern
- Need to prevent uncontrolled mutations of composable state → See composable-readonly-state
- Unsure whether logic belongs in composable or utility function → See composable-vs-utility-functions
Composition API
- Optimizing production bundle size and performance → See composition-api-bundle-size-minification
- Composition API code becoming scattered and hard to maintain → See composition-api-code-organization
- Fixing naming conflicts and unclear data origins in mixins → See composition-api-mixins-replacement
- Applying functional patterns incorrectly to Vue state → See composition-api-not-functional-programming
- Gradually migrating large Options API codebase → See composition-api-options-api-coexistence
- Coming from React, over-engineering Vue patterns unnecessarily → See composition-api-vs-react-hooks-differences
Directives
- Storing state across directive hooks → See directive-arguments-read-only
- Applying custom directives to Vue components → See directive-avoid-on-components
- Creating intervals or event listeners in directives → See directive-cleanup-in-unmounted
- Simplifying directives with identical behavior → See directive-function-shorthand
- Using custom directives in script setup → See directive-naming-v-prefix
- Choosing between custom and built-in directives → See directive-prefer-declarative-templating
- Deciding between directives and components → See directive-vs-component-decision
- Migrating Vue 2 directives to Vue 3 → See directive-vue2-migration-hooks
Transitions
- Wrapping multiple elements or components in transitions → See transition-single-element-slot
- Transitioning between same element types without animation → See transition-key-for-same-element
- Using JavaScript animations without calling done callback → See transition-js-hooks-done-callback
- Animating lists with TransitionGroup without unique keys → See transition-group-key-requirement
- Performance problems with janky list animations → See transition-animate-transform-opacity
- Move animations failing on inline list elements → See transition-group-flip-inline-elements
- List items jumping instead of smoothly animating → See transition-group-move-animation-position-absolute
- Vue 2 to Vue 3 transition layout breaks unexpectedly → See transition-group-no-default-wrapper-vue3
- Trying to sequence list animations with mode prop → See transition-group-no-mode-prop
- Creating cascading delays for list item animations → See transition-group-staggered-animations
- Overlapping elements or layout jumping during transitions → See transition-mode-out-in
- Nested transition animations cutting off prematurely → See transition-nested-duration
- Reusable transition components with scoped styles breaking → See transition-reusable-scoped-style
- RouterView transitions unexpectedly animating on page load → See transition-router-view-appear
- Mixing CSS transitions and animations causing timing issues → See transition-type-when-mixed
- Component cleanup not firing during fast transition replacements → See transition-unmount-hook-timing
Animation
- Need to animate elements staying in DOM → See animation-class-based-technique
- Animations not triggering on content changes → See animation-key-for-rerender
- Building interactive animations with user input → See animation-state-driven-technique
- Animating list changes causing noticeable lag → See animation-transitiongroup-performance
KeepAlive
- Using KeepAlive without proper cache limits or cleanup → See keepalive-memory-management
- KeepAlive include/exclude props not matching cached components → See keepalive-component-name-requirement
- Need to programmatically remove component from KeepAlive cache → See keepalive-no-cache-removal-vue3
- Users see stale cached content when expecting fresh page data → See keepalive-router-fresh-vs-cached
- Child components mount twice with nested Vue Router routes → See keepalive-router-nested-double-mount
- Memory grows when combining KeepAlive with Transition animations → See keepalive-transition-memory-leak
- Dynamic component state resets when switching between them → See dynamic-components-with-keepalive
Async Components
- Setting up Vue Router route component loading → See async-component-vue-router
- Async component options ignored by parent Suspense → See async-component-suspense-control
- Improving Time to Interactive with SSR apps → See async-component-hydration-strategies
- Loading spinner flashing on fast networks → See async-component-loading-delay
Render Functions
- Render function from setup doesn't update reactively → See rendering-render-function-return-from-setup
- Same vnode appearing multiple times in tree → See render-function-vnodes-must-be-unique
- Rendering lists in render functions without keys → See render-function-v-for-keys-required
- Implementing .stop, .prevent in render functions → See render-function-event-modifiers
- Two-way binding on components in render functions → See render-function-v-model-implementation
- Using string names for components in render functions → See rendering-resolve-component-for-string-names
- Accessing vnode internals like el or shapeFlag → See render-function-avoid-internal-vnode-properties
- Creating simple stateless presentational components → See render-function-functional-components
- Applying custom directives in render functions → See render-function-custom-directives
- Excessive rerenders from watchers or deep watchers → See rendering-excessive-rerenders-watch-vs-computed
- Choosing render functions over templates → See rendering-prefer-templates-over-render-functions
- Migrating Vue 2 render functions to Vue 3 → See rendering-render-function-h-import-vue3
- Passing slot content to h() incorrectly → See rendering-render-function-slots-as-functions
- Understanding Vue's vdom optimization blocks → See rendering-understand-vdom-block-structure
Teleport
- Modal breaks with parent CSS transforms → See teleport-css-positioning-issues
- Content needs different layout on mobile → See teleport-disabled-for-responsive
- Unsure if props/events work through teleport → See teleport-logical-hierarchy-preserved
- Multiple modals targeting same container → See teleport-multiple-to-same-target
- Scoped styles not applying to teleported content → See teleport-scoped-styles-limitation
Suspense
- Want to track Suspense loading states programmatically → See suspense-events-for-state-tracking
- Planning Suspense usage in production applications → See suspense-experimental-api-stability
- Fallback not showing when content changes → See suspense-fallback-not-immediate-on-revert
- Nesting Suspense components together → See suspense-nested-suspensible-prop
- Combining Suspense with Router, Transition, KeepAlive → See suspense-nesting-order-with-router
- Nested async component not showing loading indicator → See suspense-revert-only-on-root-change
- Multiple async components in single Suspense → See suspense-single-child-requirement
TypeScript
- Declaring props with TypeScript in composition API components → See ts-defineprops-type-based-declaration
- Providing default values to mutable prop types → See ts-withdefaults-mutable-factory-function
- Typing reactive state with ref unwrapping concerns → See ts-reactive-no-generic-argument
- Accessing DOM elements after component mounts → See ts-template-ref-null-handling
- Typing refs to child Vue components → See ts-component-ref-typeof-instancetype
- Using custom directives with TypeScript support → See ts-custom-directive-type-augmentation
- Declaring component events with full type safety → See ts-defineemits-type-based-syntax
- Handling optional boolean props in TypeScript → See ts-defineprops-boolean-default-false
- Using imported types safely in defineProps → See ts-defineprops-imported-types-limitations
- Handling DOM events with strict TypeScript checking → See ts-event-handler-explicit-typing
- Sharing data between components with type safety → See ts-provide-inject-injection-key
- Storing Vue components in reactive state → See ts-shallowref-for-dynamic-components
- Working with union types in Vue templates → See ts-template-type-casting
SSR
- User data leaking between server requests → See state-ssr-cross-request-pollution
- Code runs on both server and browser environments → See ssr-platform-specific-apis
- Custom directives not displaying on server-rendered HTML → See ssr-custom-directive-getssrprops
Performance
- Many list items re-rendering unnecessarily during state changes → See perf-props-stability-update-optimization
- Rendering hundreds or thousands of items causing DOM performance issues → See perf-virtualize-large-lists
- Static content re-evaluated on every parent component update → See perf-v-once-v-memo-directives
- List performance degrading from deeply nested component structure → See perf-avoid-component-abstraction-in-lists
- Computed properties returning objects triggering effects unexpectedly → See perf-computed-object-stability
- Page load metrics suffering from client-side JavaScript execution delay → See perf-ssr-ssg-for-page-load
SFC (Single File Components)
- Starting a Vue project with a build setup → See sfc-recommended-for-build-projects
- Styling child component elements with scoped CSS → See sfc-scoped-css-child-component-styling
- Styling content added dynamically with v-html → See sfc-scoped-css-dynamic-content
- Optimizing scoped CSS selector performance → See sfc-scoped-css-performance
- Styling content passed through component slots → See sfc-scoped-css-slot-content
- Organizing component template, logic, and styles → See sfc-separation-of-concerns-colocate
- Binding inline styles with property names → See style-binding-camelcase
- Building Tailwind classes with string concatenation → See tailwind-dynamic-class-generation
Plugins
- Global properties not available in setup function → See plugin-prefer-provide-inject-over-global-properties
- Creating a new Vue plugin from scratch → See plugin-structure-install-method
- Preventing collisions between multiple plugins → See plugin-symbol-injection-keys
- Global properties missing TypeScript autocomplete support → See plugin-typescript-type-augmentation
App Configuration
- Need to chain app configuration methods after mount → See mount-return-value
- Vue only controlling specific page sections → See multiple-app-instances
- Migrating dynamic component registration to Vite → See dynamic-component-registration-vite
You Might Also Like
Related Skills

coding-agent
Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.
openclaw
add-uint-support
Add unsigned integer (uint) type support to PyTorch operators by updating AT_DISPATCH macros. Use when adding support for uint16, uint32, uint64 types to operators, kernels, or when user mentions enabling unsigned types, barebones unsigned types, or uint support.
pytorch
at-dispatch-v2
Convert PyTorch AT_DISPATCH macros to AT_DISPATCH_V2 format in ATen C++ code. Use when porting AT_DISPATCH_ALL_TYPES_AND*, AT_DISPATCH_FLOATING_TYPES*, or other dispatch macros to the new v2 API. For ATen kernel files, CUDA kernels, and native operator implementations.
pytorch
skill-writer
Guide users through creating Agent Skills for Claude Code. Use when the user wants to create, write, author, or design a new Skill, or needs help with SKILL.md files, frontmatter, or skill structure.
pytorch
implementing-jsc-classes-cpp
Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or constructors.
oven-sh
implementing-jsc-classes-zig
Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.
oven-sh