devskill 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -0
- package/README.vn.md +104 -0
- package/SKILL_GUIDE.vn.md +252 -0
- package/bin/devskill.js +11 -0
- package/meta.ts +123 -0
- package/package.json +21 -0
- package/publish.sh +50 -0
- package/scripts/cli.ts +556 -0
- package/skills/builderx_api-contexts/SKILL.md +63 -0
- package/skills/builderx_api-contexts/references/core-multi-outbox.md +57 -0
- package/skills/builderx_api-controllers/SKILL.md +49 -0
- package/skills/builderx_api-controllers/references/core-fallback.md +62 -0
- package/skills/builderx_api-schemas/SKILL.md +76 -0
- package/skills/builderx_api-schemas/references/core-schema.md +78 -0
- package/skills/builderx_spa-api/SKILL.md +67 -0
- package/skills/builderx_spa-api/references/base-api.md +97 -0
- package/skills/builderx_spa-api/references/fetch.md +70 -0
- package/skills/builderx_spa-design/SKILL.md +82 -0
- package/skills/builderx_spa-design/references/core-text-design.md +64 -0
- package/skills/builderx_spa-design/references/features-feedback-actions.md +76 -0
- package/skills/builderx_spa-design/references/features-forms.md +91 -0
- package/skills/builderx_spa-design/references/features-layout-navigation.md +121 -0
- package/skills/builderx_spa-permission/SKILL.md +38 -0
- package/skills/builderx_spa-permission/references/has-permission.md +34 -0
- package/skills/composition-patterns/AGENTS.md +946 -0
- package/skills/composition-patterns/README.md +60 -0
- package/skills/composition-patterns/SKILL.md +89 -0
- package/skills/composition-patterns/SYNC.md +5 -0
- package/skills/composition-patterns/metadata.json +11 -0
- package/skills/composition-patterns/rules/_sections.md +29 -0
- package/skills/composition-patterns/rules/_template.md +24 -0
- package/skills/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills/composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills/composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills/composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills/composition-patterns/rules/state-context-interface.md +191 -0
- package/skills/composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills/composition-patterns/rules/state-lift-state.md +125 -0
- package/skills/deploy-to-vercel/Archive.zip +0 -0
- package/skills/deploy-to-vercel/SKILL.md +296 -0
- package/skills/deploy-to-vercel/SYNC.md +5 -0
- package/skills/deploy-to-vercel/resources/deploy-codex.sh +301 -0
- package/skills/deploy-to-vercel/resources/deploy.sh +301 -0
- package/skills/pinia/SKILL.md +105 -0
- package/skills/pinia/references/api-in-composables.md +139 -0
- package/skills/pinia/references/setup-stores.md +105 -0
- package/skills/pinia/references/using-in-components.md +91 -0
- package/skills/pinia-options/SKILL.md +72 -0
- package/skills/pinia-options/references/core-option-stores.md +149 -0
- package/skills/pinia-options/references/using-in-options-api.md +105 -0
- package/skills/react-best-practices/AGENTS.md +3373 -0
- package/skills/react-best-practices/README.md +123 -0
- package/skills/react-best-practices/SKILL.md +143 -0
- package/skills/react-best-practices/SYNC.md +5 -0
- package/skills/react-best-practices/metadata.json +15 -0
- package/skills/react-best-practices/rules/_sections.md +46 -0
- package/skills/react-best-practices/rules/_template.md +28 -0
- package/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/skills/react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/skills/react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/react-best-practices/rules/server-hoist-static-io.md +142 -0
- package/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/react-native-skills/AGENTS.md +2897 -0
- package/skills/react-native-skills/README.md +165 -0
- package/skills/react-native-skills/SKILL.md +121 -0
- package/skills/react-native-skills/SYNC.md +5 -0
- package/skills/react-native-skills/metadata.json +16 -0
- package/skills/react-native-skills/rules/_sections.md +86 -0
- package/skills/react-native-skills/rules/_template.md +28 -0
- package/skills/react-native-skills/rules/animation-derived-value.md +53 -0
- package/skills/react-native-skills/rules/animation-gesture-detector-press.md +95 -0
- package/skills/react-native-skills/rules/animation-gpu-properties.md +65 -0
- package/skills/react-native-skills/rules/design-system-compound-components.md +66 -0
- package/skills/react-native-skills/rules/fonts-config-plugin.md +71 -0
- package/skills/react-native-skills/rules/imports-design-system-folder.md +68 -0
- package/skills/react-native-skills/rules/js-hoist-intl.md +61 -0
- package/skills/react-native-skills/rules/list-performance-callbacks.md +44 -0
- package/skills/react-native-skills/rules/list-performance-function-references.md +132 -0
- package/skills/react-native-skills/rules/list-performance-images.md +53 -0
- package/skills/react-native-skills/rules/list-performance-inline-objects.md +97 -0
- package/skills/react-native-skills/rules/list-performance-item-expensive.md +94 -0
- package/skills/react-native-skills/rules/list-performance-item-memo.md +82 -0
- package/skills/react-native-skills/rules/list-performance-item-types.md +104 -0
- package/skills/react-native-skills/rules/list-performance-virtualize.md +67 -0
- package/skills/react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
- package/skills/react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
- package/skills/react-native-skills/rules/navigation-native-navigators.md +188 -0
- package/skills/react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
- package/skills/react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
- package/skills/react-native-skills/rules/react-state-dispatcher.md +91 -0
- package/skills/react-native-skills/rules/react-state-fallback.md +56 -0
- package/skills/react-native-skills/rules/react-state-minimize.md +65 -0
- package/skills/react-native-skills/rules/rendering-no-falsy-and.md +74 -0
- package/skills/react-native-skills/rules/rendering-text-in-text-component.md +36 -0
- package/skills/react-native-skills/rules/scroll-position-no-state.md +82 -0
- package/skills/react-native-skills/rules/state-ground-truth.md +80 -0
- package/skills/react-native-skills/rules/ui-expo-image.md +66 -0
- package/skills/react-native-skills/rules/ui-image-gallery.md +104 -0
- package/skills/react-native-skills/rules/ui-measure-views.md +78 -0
- package/skills/react-native-skills/rules/ui-menus.md +174 -0
- package/skills/react-native-skills/rules/ui-native-modals.md +77 -0
- package/skills/react-native-skills/rules/ui-pressable.md +61 -0
- package/skills/react-native-skills/rules/ui-safe-area-scroll.md +65 -0
- package/skills/react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
- package/skills/react-native-skills/rules/ui-styling.md +87 -0
- package/skills/slidev/LICENSE.md +21 -0
- package/skills/slidev/README.md +61 -0
- package/skills/slidev/SKILL.md +189 -0
- package/skills/slidev/SYNC.md +5 -0
- package/skills/slidev/references/animation-click-marker.md +37 -0
- package/skills/slidev/references/animation-drawing.md +68 -0
- package/skills/slidev/references/animation-rough-marker.md +53 -0
- package/skills/slidev/references/api-slide-hooks.md +37 -0
- package/skills/slidev/references/build-og-image.md +36 -0
- package/skills/slidev/references/build-pdf.md +40 -0
- package/skills/slidev/references/build-remote-assets.md +34 -0
- package/skills/slidev/references/build-seo-meta.md +43 -0
- package/skills/slidev/references/code-groups.md +64 -0
- package/skills/slidev/references/code-import-snippet.md +55 -0
- package/skills/slidev/references/code-line-highlighting.md +50 -0
- package/skills/slidev/references/code-line-numbers.md +46 -0
- package/skills/slidev/references/code-magic-move.md +57 -0
- package/skills/slidev/references/code-max-height.md +37 -0
- package/skills/slidev/references/code-twoslash.md +42 -0
- package/skills/slidev/references/core-animations.md +196 -0
- package/skills/slidev/references/core-cli.md +140 -0
- package/skills/slidev/references/core-components.md +197 -0
- package/skills/slidev/references/core-exporting.md +148 -0
- package/skills/slidev/references/core-frontmatter.md +195 -0
- package/skills/slidev/references/core-global-context.md +155 -0
- package/skills/slidev/references/core-headmatter.md +188 -0
- package/skills/slidev/references/core-hosting.md +152 -0
- package/skills/slidev/references/core-layouts.md +286 -0
- package/skills/slidev/references/core-syntax.md +155 -0
- package/skills/slidev/references/diagram-latex.md +55 -0
- package/skills/slidev/references/diagram-mermaid.md +44 -0
- package/skills/slidev/references/diagram-plantuml.md +45 -0
- package/skills/slidev/references/editor-monaco-run.md +44 -0
- package/skills/slidev/references/editor-monaco-write.md +24 -0
- package/skills/slidev/references/editor-monaco.md +50 -0
- package/skills/slidev/references/editor-prettier.md +40 -0
- package/skills/slidev/references/editor-side.md +23 -0
- package/skills/slidev/references/editor-vscode.md +55 -0
- package/skills/slidev/references/layout-canvas-size.md +25 -0
- package/skills/slidev/references/layout-draggable.md +57 -0
- package/skills/slidev/references/layout-global-layers.md +50 -0
- package/skills/slidev/references/layout-slots.md +75 -0
- package/skills/slidev/references/layout-transform.md +33 -0
- package/skills/slidev/references/layout-zoom.md +39 -0
- package/skills/slidev/references/presenter-notes-ruby.md +35 -0
- package/skills/slidev/references/presenter-recording.md +30 -0
- package/skills/slidev/references/presenter-remote.md +40 -0
- package/skills/slidev/references/presenter-timer.md +34 -0
- package/skills/slidev/references/style-direction.md +34 -0
- package/skills/slidev/references/style-icons.md +46 -0
- package/skills/slidev/references/style-scoped.md +50 -0
- package/skills/slidev/references/syntax-block-frontmatter.md +39 -0
- package/skills/slidev/references/syntax-frontmatter-merging.md +49 -0
- package/skills/slidev/references/syntax-importing-slides.md +60 -0
- package/skills/slidev/references/syntax-mdc.md +51 -0
- package/skills/slidev/references/tool-eject-theme.md +27 -0
- package/skills/tsdown/LICENSE.md +22 -0
- package/skills/tsdown/README.md +77 -0
- package/skills/tsdown/SKILL.md +407 -0
- package/skills/tsdown/SYNC.md +5 -0
- package/skills/tsdown/references/README.md +139 -0
- package/skills/tsdown/references/advanced-benchmark.md +8 -0
- package/skills/tsdown/references/advanced-ci.md +89 -0
- package/skills/tsdown/references/advanced-hooks.md +363 -0
- package/skills/tsdown/references/advanced-plugins.md +381 -0
- package/skills/tsdown/references/advanced-programmatic.md +378 -0
- package/skills/tsdown/references/advanced-rolldown-options.md +117 -0
- package/skills/tsdown/references/guide-getting-started.md +178 -0
- package/skills/tsdown/references/guide-introduction.md +42 -0
- package/skills/tsdown/references/guide-migrate-from-tsup.md +189 -0
- package/skills/tsdown/references/option-cjs-default.md +98 -0
- package/skills/tsdown/references/option-cleaning.md +275 -0
- package/skills/tsdown/references/option-config-file.md +281 -0
- package/skills/tsdown/references/option-css.md +301 -0
- package/skills/tsdown/references/option-dependencies.md +385 -0
- package/skills/tsdown/references/option-dts.md +251 -0
- package/skills/tsdown/references/option-entry.md +211 -0
- package/skills/tsdown/references/option-exe.md +120 -0
- package/skills/tsdown/references/option-lint.md +127 -0
- package/skills/tsdown/references/option-log-level.md +91 -0
- package/skills/tsdown/references/option-minification.md +177 -0
- package/skills/tsdown/references/option-output-directory.md +270 -0
- package/skills/tsdown/references/option-output-format.md +181 -0
- package/skills/tsdown/references/option-package-exports.md +320 -0
- package/skills/tsdown/references/option-platform.md +256 -0
- package/skills/tsdown/references/option-root.md +88 -0
- package/skills/tsdown/references/option-shims.md +299 -0
- package/skills/tsdown/references/option-sourcemap.md +301 -0
- package/skills/tsdown/references/option-target.md +222 -0
- package/skills/tsdown/references/option-tree-shaking.md +335 -0
- package/skills/tsdown/references/option-unbundle.md +310 -0
- package/skills/tsdown/references/option-watch-mode.md +261 -0
- package/skills/tsdown/references/recipe-react.md +338 -0
- package/skills/tsdown/references/recipe-solid.md +46 -0
- package/skills/tsdown/references/recipe-svelte.md +54 -0
- package/skills/tsdown/references/recipe-vue.md +387 -0
- package/skills/tsdown/references/recipe-wasm.md +125 -0
- package/skills/tsdown/references/reference-cli.md +472 -0
- package/skills/turborepo/LICENSE.md +7 -0
- package/skills/turborepo/SKILL.md +951 -0
- package/skills/turborepo/SYNC.md +5 -0
- package/skills/turborepo/command/turborepo.md +70 -0
- package/skills/turborepo/references/best-practices/RULE.md +241 -0
- package/skills/turborepo/references/best-practices/dependencies.md +246 -0
- package/skills/turborepo/references/best-practices/packages.md +335 -0
- package/skills/turborepo/references/best-practices/structure.md +297 -0
- package/skills/turborepo/references/boundaries/RULE.md +126 -0
- package/skills/turborepo/references/caching/RULE.md +153 -0
- package/skills/turborepo/references/caching/gotchas.md +190 -0
- package/skills/turborepo/references/caching/remote-cache.md +127 -0
- package/skills/turborepo/references/ci/RULE.md +79 -0
- package/skills/turborepo/references/ci/github-actions.md +162 -0
- package/skills/turborepo/references/ci/patterns.md +145 -0
- package/skills/turborepo/references/ci/vercel.md +103 -0
- package/skills/turborepo/references/cli/RULE.md +100 -0
- package/skills/turborepo/references/cli/commands.md +297 -0
- package/skills/turborepo/references/configuration/RULE.md +235 -0
- package/skills/turborepo/references/configuration/global-options.md +239 -0
- package/skills/turborepo/references/configuration/gotchas.md +368 -0
- package/skills/turborepo/references/configuration/tasks.md +325 -0
- package/skills/turborepo/references/environment/RULE.md +123 -0
- package/skills/turborepo/references/environment/gotchas.md +175 -0
- package/skills/turborepo/references/environment/modes.md +101 -0
- package/skills/turborepo/references/filtering/RULE.md +148 -0
- package/skills/turborepo/references/filtering/patterns.md +152 -0
- package/skills/turborepo/references/watch/RULE.md +99 -0
- package/skills/vercel-cli-with-tokens/SKILL.md +328 -0
- package/skills/vercel-cli-with-tokens/SYNC.md +5 -0
- package/skills/vue/SKILL.md +90 -0
- package/skills/vue/references/composables.md +54 -0
- package/skills/vue/references/lifecycle.md +31 -0
- package/skills/vue/references/props-emits.md +62 -0
- package/skills/vue/references/provide-inject.md +47 -0
- package/skills/vue/references/state.md +65 -0
- package/skills/vue-antdv-tailwind/SKILL.md +33 -0
- package/skills/vue-antdv-tailwind/references/styling-rules.md +61 -0
- package/skills/vue-best-practices/LICENSE.md +21 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/SYNC.md +5 -0
- package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
- package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
- package/skills/vue-best-practices/references/component-async.md +97 -0
- package/skills/vue-best-practices/references/component-data-flow.md +307 -0
- package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
- package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
- package/skills/vue-best-practices/references/component-slots.md +216 -0
- package/skills/vue-best-practices/references/component-suspense.md +228 -0
- package/skills/vue-best-practices/references/component-teleport.md +108 -0
- package/skills/vue-best-practices/references/component-transition-group.md +128 -0
- package/skills/vue-best-practices/references/component-transition.md +125 -0
- package/skills/vue-best-practices/references/composables.md +290 -0
- package/skills/vue-best-practices/references/directives.md +162 -0
- package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
- package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
- package/skills/vue-best-practices/references/plugins.md +166 -0
- package/skills/vue-best-practices/references/reactivity.md +344 -0
- package/skills/vue-best-practices/references/render-functions.md +201 -0
- package/skills/vue-best-practices/references/sfc.md +310 -0
- package/skills/vue-best-practices/references/state-management.md +135 -0
- package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
- package/skills/vue-jsx-best-practices/LICENSE.md +21 -0
- package/skills/vue-jsx-best-practices/SKILL.md +12 -0
- package/skills/vue-jsx-best-practices/SYNC.md +5 -0
- package/skills/vue-jsx-best-practices/reference/render-function-jsx-vue-vs-react.md +141 -0
- package/skills/vue-options/SKILL.md +98 -0
- package/skills/vue-options/references/lifecycle.md +107 -0
- package/skills/vue-options/references/mixins.md +96 -0
- package/skills/vue-options/references/props-emits.md +106 -0
- package/skills/vue-options/references/provide-inject.md +92 -0
- package/skills/vue-options/references/state.md +115 -0
- package/skills/vue-options-api-best-practices/LICENSE.md +21 -0
- package/skills/vue-options-api-best-practices/SKILL.md +23 -0
- package/skills/vue-options-api-best-practices/SYNC.md +5 -0
- package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-lifecycle-hooks.md +95 -0
- package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-methods.md +68 -0
- package/skills/vue-options-api-best-practices/reference/stateful-methods-lifecycle.md +61 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-arrow-functions-validators.md +141 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-computed-return-types.md +192 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-proptype-complex-types.md +212 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-provide-inject-limitations.md +135 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-type-event-handlers.md +202 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-use-definecomponent.md +172 -0
- package/skills/vue-options-api-best-practices/reference/ts-strict-mode-options-api.md +197 -0
- package/skills/vue-pinia-best-practices/LICENSE.md +21 -0
- package/skills/vue-pinia-best-practices/SKILL.md +21 -0
- package/skills/vue-pinia-best-practices/SYNC.md +5 -0
- package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
- package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
- package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
- package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
- package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
- package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
- package/skills/vue-router-best-practices/LICENSE.md +21 -0
- package/skills/vue-router-best-practices/SKILL.md +23 -0
- package/skills/vue-router-best-practices/SYNC.md +5 -0
- package/skills/vue-router-best-practices/reference/router-beforeenter-no-param-trigger.md +167 -0
- package/skills/vue-router-best-practices/reference/router-beforerouteenter-no-this.md +176 -0
- package/skills/vue-router-best-practices/reference/router-guard-async-await-pattern.md +227 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-infinite-loop.md +187 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md +150 -0
- package/skills/vue-router-best-practices/reference/router-param-change-no-lifecycle.md +181 -0
- package/skills/vue-router-best-practices/reference/router-simple-routing-cleanup.md +209 -0
- package/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md +183 -0
- package/skills/vue-testing-best-practices/LICENSE.md +21 -0
- package/skills/vue-testing-best-practices/SKILL.md +29 -0
- package/skills/vue-testing-best-practices/SYNC.md +5 -0
- package/skills/vue-testing-best-practices/reference/async-component-testing.md +163 -0
- package/skills/vue-testing-best-practices/reference/teleport-testing-complexity.md +158 -0
- package/skills/vue-testing-best-practices/reference/testing-async-await-flushpromises.md +175 -0
- package/skills/vue-testing-best-practices/reference/testing-browser-vs-node-runners.md +208 -0
- package/skills/vue-testing-best-practices/reference/testing-component-blackbox-approach.md +144 -0
- package/skills/vue-testing-best-practices/reference/testing-composables-helper-wrapper.md +238 -0
- package/skills/vue-testing-best-practices/reference/testing-e2e-playwright-recommended.md +242 -0
- package/skills/vue-testing-best-practices/reference/testing-no-snapshot-only.md +197 -0
- package/skills/vue-testing-best-practices/reference/testing-pinia-store-setup.md +228 -0
- package/skills/vue-testing-best-practices/reference/testing-suspense-async-components.md +229 -0
- package/skills/vue-testing-best-practices/reference/testing-vitest-recommended-for-vue.md +204 -0
- package/skills/vueuse-functions/LICENSE.md +21 -0
- package/skills/vueuse-functions/SKILL.md +419 -0
- package/skills/vueuse-functions/SYNC.md +5 -0
- package/skills/vueuse-functions/references/computedAsync.md +195 -0
- package/skills/vueuse-functions/references/computedEager.md +62 -0
- package/skills/vueuse-functions/references/computedInject.md +137 -0
- package/skills/vueuse-functions/references/computedWithControl.md +98 -0
- package/skills/vueuse-functions/references/createEventHook.md +86 -0
- package/skills/vueuse-functions/references/createGenericProjection.md +25 -0
- package/skills/vueuse-functions/references/createGlobalState.md +95 -0
- package/skills/vueuse-functions/references/createInjectionState.md +215 -0
- package/skills/vueuse-functions/references/createProjection.md +31 -0
- package/skills/vueuse-functions/references/createRef.md +54 -0
- package/skills/vueuse-functions/references/createReusableTemplate.md +357 -0
- package/skills/vueuse-functions/references/createSharedComposable.md +42 -0
- package/skills/vueuse-functions/references/createTemplatePromise.md +306 -0
- package/skills/vueuse-functions/references/createUnrefFn.md +51 -0
- package/skills/vueuse-functions/references/extendRef.md +76 -0
- package/skills/vueuse-functions/references/from.md +80 -0
- package/skills/vueuse-functions/references/get.md +30 -0
- package/skills/vueuse-functions/references/injectLocal.md +35 -0
- package/skills/vueuse-functions/references/isDefined.md +31 -0
- package/skills/vueuse-functions/references/logicAnd.md +40 -0
- package/skills/vueuse-functions/references/logicNot.md +36 -0
- package/skills/vueuse-functions/references/logicOr.md +40 -0
- package/skills/vueuse-functions/references/makeDestructurable.md +41 -0
- package/skills/vueuse-functions/references/onClickOutside.md +221 -0
- package/skills/vueuse-functions/references/onElementRemoval.md +88 -0
- package/skills/vueuse-functions/references/onKeyStroke.md +211 -0
- package/skills/vueuse-functions/references/onLongPress.md +227 -0
- package/skills/vueuse-functions/references/onStartTyping.md +53 -0
- package/skills/vueuse-functions/references/provideLocal.md +37 -0
- package/skills/vueuse-functions/references/reactify.md +144 -0
- package/skills/vueuse-functions/references/reactifyObject.md +62 -0
- package/skills/vueuse-functions/references/reactiveComputed.md +34 -0
- package/skills/vueuse-functions/references/reactiveOmit.md +86 -0
- package/skills/vueuse-functions/references/reactivePick.md +106 -0
- package/skills/vueuse-functions/references/refAutoReset.md +46 -0
- package/skills/vueuse-functions/references/refDebounced.md +81 -0
- package/skills/vueuse-functions/references/refDefault.md +36 -0
- package/skills/vueuse-functions/references/refManualReset.md +44 -0
- package/skills/vueuse-functions/references/refThrottled.md +99 -0
- package/skills/vueuse-functions/references/refWithControl.md +146 -0
- package/skills/vueuse-functions/references/set.md +30 -0
- package/skills/vueuse-functions/references/syncRef.md +195 -0
- package/skills/vueuse-functions/references/syncRefs.md +128 -0
- package/skills/vueuse-functions/references/templateRef.md +86 -0
- package/skills/vueuse-functions/references/toObserver.md +38 -0
- package/skills/vueuse-functions/references/toReactive.md +41 -0
- package/skills/vueuse-functions/references/toRef.md +75 -0
- package/skills/vueuse-functions/references/toRefs.md +81 -0
- package/skills/vueuse-functions/references/tryOnBeforeMount.md +34 -0
- package/skills/vueuse-functions/references/tryOnBeforeUnmount.md +32 -0
- package/skills/vueuse-functions/references/tryOnMounted.md +34 -0
- package/skills/vueuse-functions/references/tryOnScopeDispose.md +31 -0
- package/skills/vueuse-functions/references/tryOnUnmounted.md +32 -0
- package/skills/vueuse-functions/references/unrefElement.md +54 -0
- package/skills/vueuse-functions/references/until.md +161 -0
- package/skills/vueuse-functions/references/useAbs.md +31 -0
- package/skills/vueuse-functions/references/useActiveElement.md +85 -0
- package/skills/vueuse-functions/references/useAnimate.md +181 -0
- package/skills/vueuse-functions/references/useArrayDifference.md +84 -0
- package/skills/vueuse-functions/references/useArrayEvery.md +59 -0
- package/skills/vueuse-functions/references/useArrayFilter.md +63 -0
- package/skills/vueuse-functions/references/useArrayFind.md +50 -0
- package/skills/vueuse-functions/references/useArrayFindIndex.md +59 -0
- package/skills/vueuse-functions/references/useArrayFindLast.md +52 -0
- package/skills/vueuse-functions/references/useArrayIncludes.md +63 -0
- package/skills/vueuse-functions/references/useArrayJoin.md +74 -0
- package/skills/vueuse-functions/references/useArrayMap.md +59 -0
- package/skills/vueuse-functions/references/useArrayReduce.md +81 -0
- package/skills/vueuse-functions/references/useArraySome.md +59 -0
- package/skills/vueuse-functions/references/useArrayUnique.md +76 -0
- package/skills/vueuse-functions/references/useAsyncQueue.md +136 -0
- package/skills/vueuse-functions/references/useAsyncState.md +185 -0
- package/skills/vueuse-functions/references/useAsyncValidator.md +70 -0
- package/skills/vueuse-functions/references/useAuth.md +123 -0
- package/skills/vueuse-functions/references/useAverage.md +36 -0
- package/skills/vueuse-functions/references/useAxios.md +325 -0
- package/skills/vueuse-functions/references/useBase64.md +136 -0
- package/skills/vueuse-functions/references/useBattery.md +78 -0
- package/skills/vueuse-functions/references/useBluetooth.md +175 -0
- package/skills/vueuse-functions/references/useBreakpoints.md +172 -0
- package/skills/vueuse-functions/references/useBroadcastChannel.md +74 -0
- package/skills/vueuse-functions/references/useBrowserLocation.md +83 -0
- package/skills/vueuse-functions/references/useCached.md +52 -0
- package/skills/vueuse-functions/references/useCeil.md +31 -0
- package/skills/vueuse-functions/references/useChangeCase.md +79 -0
- package/skills/vueuse-functions/references/useClamp.md +85 -0
- package/skills/vueuse-functions/references/useClipboard.md +123 -0
- package/skills/vueuse-functions/references/useClipboardItems.md +94 -0
- package/skills/vueuse-functions/references/useCloned.md +91 -0
- package/skills/vueuse-functions/references/useColorMode.md +172 -0
- package/skills/vueuse-functions/references/useConfirmDialog.md +159 -0
- package/skills/vueuse-functions/references/useCookies.md +162 -0
- package/skills/vueuse-functions/references/useCountdown.md +105 -0
- package/skills/vueuse-functions/references/useCounter.md +86 -0
- package/skills/vueuse-functions/references/useCssSupports.md +35 -0
- package/skills/vueuse-functions/references/useCssVar.md +50 -0
- package/skills/vueuse-functions/references/useCurrentElement.md +61 -0
- package/skills/vueuse-functions/references/useCycleList.md +75 -0
- package/skills/vueuse-functions/references/useDark.md +144 -0
- package/skills/vueuse-functions/references/useDateFormat.md +145 -0
- package/skills/vueuse-functions/references/useDebounceFn.md +100 -0
- package/skills/vueuse-functions/references/useDebouncedRefHistory.md +40 -0
- package/skills/vueuse-functions/references/useDeviceMotion.md +86 -0
- package/skills/vueuse-functions/references/useDeviceOrientation.md +62 -0
- package/skills/vueuse-functions/references/useDevicePixelRatio.md +44 -0
- package/skills/vueuse-functions/references/useDevicesList.md +90 -0
- package/skills/vueuse-functions/references/useDisplayMedia.md +71 -0
- package/skills/vueuse-functions/references/useDocumentVisibility.md +45 -0
- package/skills/vueuse-functions/references/useDraggable.md +317 -0
- package/skills/vueuse-functions/references/useDrauu.md +65 -0
- package/skills/vueuse-functions/references/useDropZone.md +83 -0
- package/skills/vueuse-functions/references/useElementBounding.md +131 -0
- package/skills/vueuse-functions/references/useElementByPoint.md +48 -0
- package/skills/vueuse-functions/references/useElementHover.md +79 -0
- package/skills/vueuse-functions/references/useElementSize.md +78 -0
- package/skills/vueuse-functions/references/useElementVisibility.md +123 -0
- package/skills/vueuse-functions/references/useEventBus.md +101 -0
- package/skills/vueuse-functions/references/useEventListener.md +226 -0
- package/skills/vueuse-functions/references/useEventSource.md +204 -0
- package/skills/vueuse-functions/references/useExtractedObservable.md +198 -0
- package/skills/vueuse-functions/references/useEyeDropper.md +71 -0
- package/skills/vueuse-functions/references/useFavicon.md +67 -0
- package/skills/vueuse-functions/references/useFetch.md +546 -0
- package/skills/vueuse-functions/references/useFileDialog.md +91 -0
- package/skills/vueuse-functions/references/useFileSystemAccess.md +162 -0
- package/skills/vueuse-functions/references/useFirestore.md +129 -0
- package/skills/vueuse-functions/references/useFloor.md +31 -0
- package/skills/vueuse-functions/references/useFocus.md +99 -0
- package/skills/vueuse-functions/references/useFocusTrap.md +245 -0
- package/skills/vueuse-functions/references/useFocusWithin.md +57 -0
- package/skills/vueuse-functions/references/useFps.md +28 -0
- package/skills/vueuse-functions/references/useFullscreen.md +75 -0
- package/skills/vueuse-functions/references/useFuse.md +107 -0
- package/skills/vueuse-functions/references/useGamepad.md +222 -0
- package/skills/vueuse-functions/references/useGeolocation.md +85 -0
- package/skills/vueuse-functions/references/useIDBKeyval.md +93 -0
- package/skills/vueuse-functions/references/useIdle.md +88 -0
- package/skills/vueuse-functions/references/useImage.md +86 -0
- package/skills/vueuse-functions/references/useInfiniteScroll.md +157 -0
- package/skills/vueuse-functions/references/useIntersectionObserver.md +118 -0
- package/skills/vueuse-functions/references/useInterval.md +112 -0
- package/skills/vueuse-functions/references/useIntervalFn.md +50 -0
- package/skills/vueuse-functions/references/useIpcRenderer.md +144 -0
- package/skills/vueuse-functions/references/useIpcRendererInvoke.md +58 -0
- package/skills/vueuse-functions/references/useIpcRendererOn.md +52 -0
- package/skills/vueuse-functions/references/useJwt.md +57 -0
- package/skills/vueuse-functions/references/useKeyModifier.md +87 -0
- package/skills/vueuse-functions/references/useLastChanged.md +63 -0
- package/skills/vueuse-functions/references/useLocalStorage.md +41 -0
- package/skills/vueuse-functions/references/useMagicKeys.md +245 -0
- package/skills/vueuse-functions/references/useManualRefHistory.md +204 -0
- package/skills/vueuse-functions/references/useMath.md +47 -0
- package/skills/vueuse-functions/references/useMax.md +36 -0
- package/skills/vueuse-functions/references/useMediaControls.md +571 -0
- package/skills/vueuse-functions/references/useMediaQuery.md +53 -0
- package/skills/vueuse-functions/references/useMemoize.md +175 -0
- package/skills/vueuse-functions/references/useMemory.md +71 -0
- package/skills/vueuse-functions/references/useMin.md +36 -0
- package/skills/vueuse-functions/references/useMounted.md +38 -0
- package/skills/vueuse-functions/references/useMouse.md +113 -0
- package/skills/vueuse-functions/references/useMouseInElement.md +123 -0
- package/skills/vueuse-functions/references/useMousePressed.md +112 -0
- package/skills/vueuse-functions/references/useMutationObserver.md +61 -0
- package/skills/vueuse-functions/references/useNProgress.md +78 -0
- package/skills/vueuse-functions/references/useNavigatorLanguage.md +57 -0
- package/skills/vueuse-functions/references/useNetwork.md +106 -0
- package/skills/vueuse-functions/references/useNow.md +79 -0
- package/skills/vueuse-functions/references/useObjectUrl.md +55 -0
- package/skills/vueuse-functions/references/useObservable.md +91 -0
- package/skills/vueuse-functions/references/useOffsetPagination.md +199 -0
- package/skills/vueuse-functions/references/useOnline.md +41 -0
- package/skills/vueuse-functions/references/usePageLeave.md +42 -0
- package/skills/vueuse-functions/references/useParallax.md +58 -0
- package/skills/vueuse-functions/references/useParentElement.md +54 -0
- package/skills/vueuse-functions/references/usePerformanceObserver.md +48 -0
- package/skills/vueuse-functions/references/usePermission.md +79 -0
- package/skills/vueuse-functions/references/usePointer.md +89 -0
- package/skills/vueuse-functions/references/usePointerLock.md +60 -0
- package/skills/vueuse-functions/references/usePointerSwipe.md +80 -0
- package/skills/vueuse-functions/references/usePrecision.md +49 -0
- package/skills/vueuse-functions/references/usePreferredColorScheme.md +42 -0
- package/skills/vueuse-functions/references/usePreferredContrast.md +42 -0
- package/skills/vueuse-functions/references/usePreferredDark.md +41 -0
- package/skills/vueuse-functions/references/usePreferredLanguages.md +41 -0
- package/skills/vueuse-functions/references/usePreferredReducedMotion.md +42 -0
- package/skills/vueuse-functions/references/usePreferredReducedTransparency.md +42 -0
- package/skills/vueuse-functions/references/usePrevious.md +40 -0
- package/skills/vueuse-functions/references/useProjection.md +38 -0
- package/skills/vueuse-functions/references/useQRCode.md +53 -0
- package/skills/vueuse-functions/references/useRTDB.md +83 -0
- package/skills/vueuse-functions/references/useRafFn.md +68 -0
- package/skills/vueuse-functions/references/useRefHistory.md +285 -0
- package/skills/vueuse-functions/references/useResizeObserver.md +109 -0
- package/skills/vueuse-functions/references/useRound.md +31 -0
- package/skills/vueuse-functions/references/useRouteHash.md +27 -0
- package/skills/vueuse-functions/references/useRouteParams.md +38 -0
- package/skills/vueuse-functions/references/useRouteQuery.md +79 -0
- package/skills/vueuse-functions/references/useSSRWidth.md +47 -0
- package/skills/vueuse-functions/references/useScreenOrientation.md +96 -0
- package/skills/vueuse-functions/references/useScreenSafeArea.md +60 -0
- package/skills/vueuse-functions/references/useScriptTag.md +116 -0
- package/skills/vueuse-functions/references/useScroll.md +238 -0
- package/skills/vueuse-functions/references/useScrollLock.md +66 -0
- package/skills/vueuse-functions/references/useSessionStorage.md +41 -0
- package/skills/vueuse-functions/references/useShare.md +68 -0
- package/skills/vueuse-functions/references/useSortable.md +235 -0
- package/skills/vueuse-functions/references/useSorted.md +90 -0
- package/skills/vueuse-functions/references/useSpeechRecognition.md +94 -0
- package/skills/vueuse-functions/references/useSpeechSynthesis.md +105 -0
- package/skills/vueuse-functions/references/useStepper.md +137 -0
- package/skills/vueuse-functions/references/useStorage.md +278 -0
- package/skills/vueuse-functions/references/useStorageAsync.md +136 -0
- package/skills/vueuse-functions/references/useStyleTag.md +131 -0
- package/skills/vueuse-functions/references/useSubject.md +77 -0
- package/skills/vueuse-functions/references/useSubscription.md +33 -0
- package/skills/vueuse-functions/references/useSum.md +36 -0
- package/skills/vueuse-functions/references/useSupported.md +29 -0
- package/skills/vueuse-functions/references/useSwipe.md +75 -0
- package/skills/vueuse-functions/references/useTemplateRefsList.md +37 -0
- package/skills/vueuse-functions/references/useTextDirection.md +75 -0
- package/skills/vueuse-functions/references/useTextSelection.md +40 -0
- package/skills/vueuse-functions/references/useTextareaAutosize.md +97 -0
- package/skills/vueuse-functions/references/useThrottleFn.md +57 -0
- package/skills/vueuse-functions/references/useThrottledRefHistory.md +47 -0
- package/skills/vueuse-functions/references/useTimeAgo.md +154 -0
- package/skills/vueuse-functions/references/useTimeAgoIntl.md +117 -0
- package/skills/vueuse-functions/references/useTimeout.md +113 -0
- package/skills/vueuse-functions/references/useTimeoutFn.md +51 -0
- package/skills/vueuse-functions/references/useTimeoutPoll.md +47 -0
- package/skills/vueuse-functions/references/useTimestamp.md +89 -0
- package/skills/vueuse-functions/references/useTitle.md +113 -0
- package/skills/vueuse-functions/references/useToNumber.md +54 -0
- package/skills/vueuse-functions/references/useToString.md +34 -0
- package/skills/vueuse-functions/references/useToggle.md +103 -0
- package/skills/vueuse-functions/references/useTransition.md +265 -0
- package/skills/vueuse-functions/references/useTrunc.md +33 -0
- package/skills/vueuse-functions/references/useUrlSearchParams.md +121 -0
- package/skills/vueuse-functions/references/useUserMedia.md +1138 -0
- package/skills/vueuse-functions/references/useVModel.md +182 -0
- package/skills/vueuse-functions/references/useVModels.md +67 -0
- package/skills/vueuse-functions/references/useVibrate.md +87 -0
- package/skills/vueuse-functions/references/useVirtualList.md +182 -0
- package/skills/vueuse-functions/references/useWakeLock.md +50 -0
- package/skills/vueuse-functions/references/useWebNotification.md +176 -0
- package/skills/vueuse-functions/references/useWebSocket.md +299 -0
- package/skills/vueuse-functions/references/useWebWorker.md +60 -0
- package/skills/vueuse-functions/references/useWebWorkerFn.md +102 -0
- package/skills/vueuse-functions/references/useWindowFocus.md +46 -0
- package/skills/vueuse-functions/references/useWindowScroll.md +61 -0
- package/skills/vueuse-functions/references/useWindowSize.md +76 -0
- package/skills/vueuse-functions/references/useZoomFactor.md +53 -0
- package/skills/vueuse-functions/references/useZoomLevel.md +53 -0
- package/skills/vueuse-functions/references/watchArray.md +53 -0
- package/skills/vueuse-functions/references/watchAtMost.md +55 -0
- package/skills/vueuse-functions/references/watchDebounced.md +101 -0
- package/skills/vueuse-functions/references/watchDeep.md +54 -0
- package/skills/vueuse-functions/references/watchExtractedObservable.md +192 -0
- package/skills/vueuse-functions/references/watchIgnorable.md +120 -0
- package/skills/vueuse-functions/references/watchImmediate.md +44 -0
- package/skills/vueuse-functions/references/watchOnce.md +41 -0
- package/skills/vueuse-functions/references/watchPausable.md +86 -0
- package/skills/vueuse-functions/references/watchThrottled.md +108 -0
- package/skills/vueuse-functions/references/watchTriggerable.md +98 -0
- package/skills/vueuse-functions/references/watchWithFilter.md +54 -0
- package/skills/vueuse-functions/references/whenever.md +100 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/skills/web-design-guidelines/SYNC.md +5 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Fix "No Active Pinia" Error - Store Setup Timing
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Using Pinia stores before app.use(pinia) causes "getActivePinia was called but there was no active Pinia" error
|
|
5
|
+
type: gotcha
|
|
6
|
+
tags: [vue3, pinia, state-management, setup, initialization, error]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Fix "No Active Pinia" Error - Store Setup Timing
|
|
10
|
+
|
|
11
|
+
**Impact: HIGH** - The error "getActivePinia() was called but there was no active Pinia" is one of the most common Pinia errors. It occurs when you try to use a store before Pinia has been installed on the Vue app, causing your application to crash.
|
|
12
|
+
|
|
13
|
+
## Task Checklist
|
|
14
|
+
|
|
15
|
+
- [ ] Ensure `app.use(pinia)` is called before `app.mount()`
|
|
16
|
+
- [ ] Ensure `app.use(pinia)` is called before `app.use(router)` if router guards use stores
|
|
17
|
+
- [ ] Never call `useXxxStore()` in module-level (top-level) code
|
|
18
|
+
- [ ] Only call `useXxxStore()` inside setup functions, composables, or after app initialization
|
|
19
|
+
- [ ] Check for `<script setup>` vs `<script>` - the latter runs too early
|
|
20
|
+
|
|
21
|
+
## The Error
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
[🍍]: "getActivePinia()" was called but there was no active Pinia.
|
|
25
|
+
Did you forget to install pinia?
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Common Cause 1: Wrong Plugin Order
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
// main.js - WRONG ORDER
|
|
32
|
+
import { createApp } from 'vue'
|
|
33
|
+
import { createPinia } from 'pinia'
|
|
34
|
+
import router from './router' // Router uses a store in navigation guard
|
|
35
|
+
import App from './App.vue'
|
|
36
|
+
|
|
37
|
+
const app = createApp(App)
|
|
38
|
+
|
|
39
|
+
// WRONG: Router is installed first, but its guards use stores
|
|
40
|
+
app.use(router) // Router guard calls useAuthStore() - FAILS!
|
|
41
|
+
app.use(createPinia())
|
|
42
|
+
app.mount('#app')
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Fix: Install Pinia first:**
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
// main.js - CORRECT ORDER
|
|
49
|
+
import { createApp } from 'vue'
|
|
50
|
+
import { createPinia } from 'pinia'
|
|
51
|
+
import router from './router'
|
|
52
|
+
import App from './App.vue'
|
|
53
|
+
|
|
54
|
+
const app = createApp(App)
|
|
55
|
+
|
|
56
|
+
// CORRECT: Pinia installed before anything that uses stores
|
|
57
|
+
app.use(createPinia())
|
|
58
|
+
app.use(router) // Now router guards can safely use stores
|
|
59
|
+
app.mount('#app')
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Common Cause 2: Store Used at Module Level
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
// api.js - WRONG: Module-level store usage
|
|
66
|
+
import { useAuthStore } from '@/stores/auth'
|
|
67
|
+
|
|
68
|
+
// This runs immediately when the module is imported!
|
|
69
|
+
const authStore = useAuthStore() // ERROR: No active Pinia yet
|
|
70
|
+
|
|
71
|
+
export function fetchUser() {
|
|
72
|
+
return fetch('/api/user', {
|
|
73
|
+
headers: {
|
|
74
|
+
Authorization: `Bearer ${authStore.token}`
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Fix: Call useStore inside functions:**
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
// api.js - CORRECT: Store used inside function
|
|
84
|
+
import { useAuthStore } from '@/stores/auth'
|
|
85
|
+
|
|
86
|
+
export function fetchUser() {
|
|
87
|
+
// Store is accessed when function is called, not when module loads
|
|
88
|
+
const authStore = useAuthStore()
|
|
89
|
+
|
|
90
|
+
return fetch('/api/user', {
|
|
91
|
+
headers: {
|
|
92
|
+
Authorization: `Bearer ${authStore.token}`
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Common Cause 3: Script Tag Missing "setup"
|
|
99
|
+
|
|
100
|
+
```vue
|
|
101
|
+
<!-- WRONG: <script> runs before component setup -->
|
|
102
|
+
<script>
|
|
103
|
+
import { useUserStore } from '@/stores/user'
|
|
104
|
+
|
|
105
|
+
// This runs too early, before the component is set up
|
|
106
|
+
const userStore = useUserStore() // ERROR!
|
|
107
|
+
|
|
108
|
+
export default {
|
|
109
|
+
// ...
|
|
110
|
+
}
|
|
111
|
+
</script>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Fix: Use `<script setup>` or move to setup function:**
|
|
115
|
+
|
|
116
|
+
```vue
|
|
117
|
+
<!-- CORRECT: <script setup> runs at the right time -->
|
|
118
|
+
<script setup>
|
|
119
|
+
import { useUserStore } from '@/stores/user'
|
|
120
|
+
|
|
121
|
+
// This runs during component setup, Pinia is active
|
|
122
|
+
const userStore = useUserStore() // Works!
|
|
123
|
+
</script>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```vue
|
|
127
|
+
<!-- CORRECT: Options API with setup function -->
|
|
128
|
+
<script>
|
|
129
|
+
import { useUserStore } from '@/stores/user'
|
|
130
|
+
|
|
131
|
+
export default {
|
|
132
|
+
setup() {
|
|
133
|
+
// Called during component initialization
|
|
134
|
+
const userStore = useUserStore() // Works!
|
|
135
|
+
return { userStore }
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
</script>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Common Cause 4: mapStores with Parentheses
|
|
142
|
+
|
|
143
|
+
```vue
|
|
144
|
+
<script>
|
|
145
|
+
import { mapStores } from 'pinia'
|
|
146
|
+
import { useProductsStore } from '@/stores/products'
|
|
147
|
+
|
|
148
|
+
export default {
|
|
149
|
+
computed: {
|
|
150
|
+
// WRONG: Called the function instead of passing it
|
|
151
|
+
...mapStores(useProductsStore()) // ERROR!
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
</script>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Fix: Pass the function reference, not the result:**
|
|
158
|
+
|
|
159
|
+
```vue
|
|
160
|
+
<script>
|
|
161
|
+
import { mapStores } from 'pinia'
|
|
162
|
+
import { useProductsStore } from '@/stores/products'
|
|
163
|
+
|
|
164
|
+
export default {
|
|
165
|
+
computed: {
|
|
166
|
+
// CORRECT: Pass the function without calling it
|
|
167
|
+
...mapStores(useProductsStore) // No parentheses!
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
</script>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Common Cause 5: Router Guards Before Pinia
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
// router/index.js - WRONG
|
|
177
|
+
import { createRouter } from 'vue-router'
|
|
178
|
+
import { useAuthStore } from '@/stores/auth'
|
|
179
|
+
|
|
180
|
+
const router = createRouter({ /* ... */ })
|
|
181
|
+
|
|
182
|
+
// This guard is registered immediately
|
|
183
|
+
router.beforeEach((to) => {
|
|
184
|
+
// When this runs during app startup, Pinia might not be ready
|
|
185
|
+
const authStore = useAuthStore() // May fail!
|
|
186
|
+
|
|
187
|
+
if (to.meta.requiresAuth && !authStore.isLoggedIn) {
|
|
188
|
+
return '/login'
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Fix: Use lazy store access or ensure plugin order:**
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
// router/index.js - CORRECT
|
|
197
|
+
import { createRouter } from 'vue-router'
|
|
198
|
+
|
|
199
|
+
const router = createRouter({ /* ... */ })
|
|
200
|
+
|
|
201
|
+
router.beforeEach((to) => {
|
|
202
|
+
// Dynamically import to avoid module-level execution
|
|
203
|
+
const { useAuthStore } = await import('@/stores/auth')
|
|
204
|
+
const authStore = useAuthStore()
|
|
205
|
+
|
|
206
|
+
if (to.meta.requiresAuth && !authStore.isLoggedIn) {
|
|
207
|
+
return '/login'
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
// OR ensure main.js has correct order:
|
|
212
|
+
// app.use(pinia)
|
|
213
|
+
// app.use(router)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Debugging Checklist
|
|
217
|
+
|
|
218
|
+
When you see "No active Pinia":
|
|
219
|
+
|
|
220
|
+
1. **Check main.js order**: Is `app.use(pinia)` before other plugins?
|
|
221
|
+
2. **Search for top-level useStore calls**: Any store usage outside functions/setup?
|
|
222
|
+
3. **Check script tags**: Using `<script>` instead of `<script setup>`?
|
|
223
|
+
4. **Check mapStores usage**: Using `useStore()` instead of `useStore`?
|
|
224
|
+
5. **Check import chains**: Does an early import trigger store usage?
|
|
225
|
+
|
|
226
|
+
## Safe Pattern: Conditional Store Access
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
// For code that might run before Pinia is ready
|
|
230
|
+
import { getActivePinia } from 'pinia'
|
|
231
|
+
|
|
232
|
+
export function safelyUseStore() {
|
|
233
|
+
const pinia = getActivePinia()
|
|
234
|
+
|
|
235
|
+
if (!pinia) {
|
|
236
|
+
console.warn('Pinia not initialized yet')
|
|
237
|
+
return null
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const { useUserStore } = await import('@/stores/user')
|
|
241
|
+
return useUserStore()
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Reference
|
|
246
|
+
- [Vue Land FAQ - No Active Pinia](https://vue-land.github.io/faq/no-active-pinia)
|
|
247
|
+
- [Pinia - Using a Store Outside of a Component](https://pinia.vuejs.org/core-concepts/outside-component-usage.html)
|
|
248
|
+
- [Pinia - Getting Started](https://pinia.vuejs.org/getting-started.html)
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Return All State Properties in Pinia Setup Stores
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Not returning state properties in setup stores breaks SSR, DevTools, and plugin compatibility
|
|
5
|
+
type: gotcha
|
|
6
|
+
tags: [vue3, pinia, state-management, setup-stores, ssr, devtools]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Return All State Properties in Pinia Setup Stores
|
|
10
|
+
|
|
11
|
+
**Impact: HIGH** - When using Pinia's setup store syntax (Composition API style), you MUST return all state properties from the setup function. Private state that isn't returned will break Server-Side Rendering (SSR), Vue DevTools inspection, and Pinia plugins.
|
|
12
|
+
|
|
13
|
+
This is a critical gotcha that can cause silent failures in production.
|
|
14
|
+
|
|
15
|
+
## Task Checklist
|
|
16
|
+
|
|
17
|
+
- [ ] Return ALL reactive state properties from setup stores
|
|
18
|
+
- [ ] Do not create "private" state by omitting it from the return
|
|
19
|
+
- [ ] If you need private state, use a prefix convention instead (e.g., `_internal`)
|
|
20
|
+
- [ ] Test stores with DevTools to verify all state is visible
|
|
21
|
+
- [ ] Verify SSR hydration includes all necessary state
|
|
22
|
+
|
|
23
|
+
## The Problem: Private State in Setup Stores
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
// stores/user.js - WRONG: Private state breaks SSR/DevTools
|
|
27
|
+
import { defineStore } from 'pinia'
|
|
28
|
+
import { ref, computed } from 'vue'
|
|
29
|
+
|
|
30
|
+
export const useUserStore = defineStore('user', () => {
|
|
31
|
+
// Public state
|
|
32
|
+
const name = ref('')
|
|
33
|
+
const email = ref('')
|
|
34
|
+
|
|
35
|
+
// "Private" state - NOT returned
|
|
36
|
+
const authToken = ref('') // Won't be serialized for SSR!
|
|
37
|
+
const lastFetchTime = ref(null) // Won't appear in DevTools!
|
|
38
|
+
|
|
39
|
+
const isLoggedIn = computed(() => !!authToken.value)
|
|
40
|
+
|
|
41
|
+
async function login(credentials) {
|
|
42
|
+
const response = await fetch('/api/login', {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
body: JSON.stringify(credentials)
|
|
45
|
+
})
|
|
46
|
+
const data = await response.json()
|
|
47
|
+
|
|
48
|
+
authToken.value = data.token // This state won't transfer to client in SSR!
|
|
49
|
+
name.value = data.name
|
|
50
|
+
email.value = data.email
|
|
51
|
+
lastFetchTime.value = Date.now()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// WRONG: Not returning authToken and lastFetchTime
|
|
55
|
+
return {
|
|
56
|
+
name,
|
|
57
|
+
email,
|
|
58
|
+
isLoggedIn,
|
|
59
|
+
login
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**What breaks:**
|
|
65
|
+
|
|
66
|
+
1. **SSR Hydration**: `authToken` and `lastFetchTime` won't be serialized and sent to the client
|
|
67
|
+
2. **DevTools**: These properties won't appear in the store inspector
|
|
68
|
+
3. **Plugins**: Persistence plugins won't save these properties
|
|
69
|
+
4. **Time-travel debugging**: Can't track changes to hidden state
|
|
70
|
+
|
|
71
|
+
## The Solution: Return Everything
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
// stores/user.js - CORRECT: All state returned
|
|
75
|
+
import { defineStore } from 'pinia'
|
|
76
|
+
import { ref, computed } from 'vue'
|
|
77
|
+
|
|
78
|
+
export const useUserStore = defineStore('user', () => {
|
|
79
|
+
// All state properties
|
|
80
|
+
const name = ref('')
|
|
81
|
+
const email = ref('')
|
|
82
|
+
const authToken = ref('')
|
|
83
|
+
const lastFetchTime = ref(null)
|
|
84
|
+
|
|
85
|
+
// Getters
|
|
86
|
+
const isLoggedIn = computed(() => !!authToken.value)
|
|
87
|
+
|
|
88
|
+
// Actions
|
|
89
|
+
async function login(credentials) {
|
|
90
|
+
const response = await fetch('/api/login', {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
body: JSON.stringify(credentials)
|
|
93
|
+
})
|
|
94
|
+
const data = await response.json()
|
|
95
|
+
|
|
96
|
+
authToken.value = data.token
|
|
97
|
+
name.value = data.name
|
|
98
|
+
email.value = data.email
|
|
99
|
+
lastFetchTime.value = Date.now()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function logout() {
|
|
103
|
+
authToken.value = ''
|
|
104
|
+
name.value = ''
|
|
105
|
+
email.value = ''
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// CORRECT: Return ALL state, getters, and actions
|
|
109
|
+
return {
|
|
110
|
+
// State
|
|
111
|
+
name,
|
|
112
|
+
email,
|
|
113
|
+
authToken,
|
|
114
|
+
lastFetchTime,
|
|
115
|
+
// Getters
|
|
116
|
+
isLoggedIn,
|
|
117
|
+
// Actions
|
|
118
|
+
login,
|
|
119
|
+
logout
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## If You Need "Private" State
|
|
125
|
+
|
|
126
|
+
Use naming conventions instead of actually hiding state:
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
import { defineStore } from 'pinia'
|
|
130
|
+
import { ref, computed } from 'vue'
|
|
131
|
+
|
|
132
|
+
export const useUserStore = defineStore('user', () => {
|
|
133
|
+
// Convention: underscore prefix for "internal" state
|
|
134
|
+
// Still returned, but signals it's not for external use
|
|
135
|
+
const _authToken = ref('')
|
|
136
|
+
const _lastFetchTime = ref(null)
|
|
137
|
+
|
|
138
|
+
// Public state
|
|
139
|
+
const name = ref('')
|
|
140
|
+
const email = ref('')
|
|
141
|
+
|
|
142
|
+
const isLoggedIn = computed(() => !!_authToken.value)
|
|
143
|
+
|
|
144
|
+
// Return everything - convention communicates intent
|
|
145
|
+
return {
|
|
146
|
+
// "Private" - use with caution
|
|
147
|
+
_authToken,
|
|
148
|
+
_lastFetchTime,
|
|
149
|
+
// Public
|
|
150
|
+
name,
|
|
151
|
+
email,
|
|
152
|
+
isLoggedIn
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Option Stores Don't Have This Problem
|
|
158
|
+
|
|
159
|
+
With the Options API syntax, all state is automatically tracked:
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
// stores/user.js - Options syntax: all state is tracked automatically
|
|
163
|
+
import { defineStore } from 'pinia'
|
|
164
|
+
|
|
165
|
+
export const useUserStore = defineStore('user', {
|
|
166
|
+
state: () => ({
|
|
167
|
+
name: '',
|
|
168
|
+
email: '',
|
|
169
|
+
authToken: '', // Automatically included
|
|
170
|
+
lastFetchTime: null // Automatically included
|
|
171
|
+
}),
|
|
172
|
+
|
|
173
|
+
getters: {
|
|
174
|
+
isLoggedIn: (state) => !!state.authToken
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
actions: {
|
|
178
|
+
async login(credentials) {
|
|
179
|
+
// ...
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## How Setup Stores Map to State
|
|
186
|
+
|
|
187
|
+
Understanding the mapping helps avoid mistakes:
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
defineStore('example', () => {
|
|
191
|
+
// ref() becomes state
|
|
192
|
+
const count = ref(0) // → state.count
|
|
193
|
+
|
|
194
|
+
// computed() becomes getters
|
|
195
|
+
const double = computed(() => count.value * 2) // → getters.double
|
|
196
|
+
|
|
197
|
+
// Regular functions become actions
|
|
198
|
+
function increment() { // → actions.increment
|
|
199
|
+
count.value++
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// CRITICAL: Must return all of them
|
|
203
|
+
return { count, double, increment }
|
|
204
|
+
})
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Debugging: Verify All State is Returned
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
// Test that DevTools can see all state
|
|
211
|
+
import { useUserStore } from '@/stores/user'
|
|
212
|
+
|
|
213
|
+
const userStore = useUserStore()
|
|
214
|
+
|
|
215
|
+
// In DevTools console or tests:
|
|
216
|
+
console.log(userStore.$state)
|
|
217
|
+
// Should include ALL reactive state properties
|
|
218
|
+
|
|
219
|
+
// Check what's returned
|
|
220
|
+
console.log(Object.keys(userStore))
|
|
221
|
+
// Should include: name, email, authToken, lastFetchTime, isLoggedIn, login, logout
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Reference
|
|
225
|
+
- [Pinia - Setup Stores](https://pinia.vuejs.org/core-concepts/#setup-stores)
|
|
226
|
+
- [Pinia - SSR](https://pinia.vuejs.org/ssr/)
|
|
227
|
+
- [Mastering Pinia - Common Mistakes](https://masteringpinia.com/blog/top-5-mistakes-to-avoid-when-using-pinia)
|
package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use storeToRefs When Destructuring Pinia Stores
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Destructuring Pinia stores directly breaks reactivity - state changes won't trigger UI updates
|
|
5
|
+
type: gotcha
|
|
6
|
+
tags: [vue3, pinia, state-management, reactivity, destructuring]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Use storeToRefs When Destructuring Pinia Stores
|
|
10
|
+
|
|
11
|
+
**Impact: HIGH** - Pinia stores are wrapped with `reactive`, so destructuring them directly extracts non-reactive values. Changes to the store won't be reflected in your component, causing stale UI and confusing bugs.
|
|
12
|
+
|
|
13
|
+
This is one of the most common mistakes when using Pinia, especially for developers coming from Vuex or other state management libraries.
|
|
14
|
+
|
|
15
|
+
## Task Checklist
|
|
16
|
+
|
|
17
|
+
- [ ] Never destructure state or getters directly from a Pinia store
|
|
18
|
+
- [ ] Use `storeToRefs()` to extract reactive state and getters
|
|
19
|
+
- [ ] Destructure actions directly (they don't need reactivity)
|
|
20
|
+
- [ ] Remember: `storeToRefs` is for state/getters, direct destructure is for actions
|
|
21
|
+
|
|
22
|
+
## The Problem: Direct Destructuring
|
|
23
|
+
|
|
24
|
+
```vue
|
|
25
|
+
<script setup>
|
|
26
|
+
import { useUserStore } from '@/stores/user'
|
|
27
|
+
|
|
28
|
+
const userStore = useUserStore()
|
|
29
|
+
|
|
30
|
+
// WRONG: Direct destructuring breaks reactivity
|
|
31
|
+
const { name, email, isLoggedIn } = userStore
|
|
32
|
+
|
|
33
|
+
// Later, when store updates...
|
|
34
|
+
userStore.login({ name: 'John', email: 'john@example.com' })
|
|
35
|
+
|
|
36
|
+
// name and email are still the OLD values!
|
|
37
|
+
// UI won't update because these are no longer reactive
|
|
38
|
+
console.log(name) // undefined (or initial value)
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<!-- This won't update when store changes -->
|
|
43
|
+
<div>{{ name }}</div>
|
|
44
|
+
</template>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## The Solution: Use storeToRefs
|
|
48
|
+
|
|
49
|
+
```vue
|
|
50
|
+
<script setup>
|
|
51
|
+
import { storeToRefs } from 'pinia'
|
|
52
|
+
import { useUserStore } from '@/stores/user'
|
|
53
|
+
|
|
54
|
+
const userStore = useUserStore()
|
|
55
|
+
|
|
56
|
+
// CORRECT: Use storeToRefs for state and getters
|
|
57
|
+
const { name, email, isLoggedIn } = storeToRefs(userStore)
|
|
58
|
+
|
|
59
|
+
// Actions can be destructured directly (they're just functions)
|
|
60
|
+
const { login, logout } = userStore
|
|
61
|
+
|
|
62
|
+
// Now when the store updates...
|
|
63
|
+
login({ name: 'John', email: 'john@example.com' })
|
|
64
|
+
|
|
65
|
+
// name and email are reactive refs that update automatically
|
|
66
|
+
console.log(name.value) // 'John'
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<template>
|
|
70
|
+
<!-- This updates reactively -->
|
|
71
|
+
<div>{{ name }}</div>
|
|
72
|
+
<button @click="logout">Logout</button>
|
|
73
|
+
</template>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Understanding Why This Happens
|
|
77
|
+
|
|
78
|
+
Pinia stores are reactive objects (like `reactive()`). When you destructure:
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
const store = useCounterStore()
|
|
82
|
+
// store is a reactive Proxy
|
|
83
|
+
|
|
84
|
+
const { count } = store
|
|
85
|
+
// count is now just a primitive number (0), not reactive
|
|
86
|
+
// It's like doing: const count = 0
|
|
87
|
+
|
|
88
|
+
// vs with storeToRefs
|
|
89
|
+
const { count } = storeToRefs(store)
|
|
90
|
+
// count is now a ref that stays connected to the store
|
|
91
|
+
// It's like: const count = computed(() => store.count)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Complete Pattern: State, Getters, and Actions
|
|
95
|
+
|
|
96
|
+
```vue
|
|
97
|
+
<script setup>
|
|
98
|
+
import { storeToRefs } from 'pinia'
|
|
99
|
+
import { useCartStore } from '@/stores/cart'
|
|
100
|
+
|
|
101
|
+
const cartStore = useCartStore()
|
|
102
|
+
|
|
103
|
+
// State and getters: USE storeToRefs
|
|
104
|
+
const {
|
|
105
|
+
items, // state
|
|
106
|
+
itemCount, // getter
|
|
107
|
+
totalPrice, // getter
|
|
108
|
+
isEmpty // getter
|
|
109
|
+
} = storeToRefs(cartStore)
|
|
110
|
+
|
|
111
|
+
// Actions: destructure directly
|
|
112
|
+
const {
|
|
113
|
+
addItem,
|
|
114
|
+
removeItem,
|
|
115
|
+
clearCart
|
|
116
|
+
} = cartStore
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
<template>
|
|
120
|
+
<div v-if="isEmpty">Cart is empty</div>
|
|
121
|
+
<div v-else>
|
|
122
|
+
<p>{{ itemCount }} items - ${{ totalPrice }}</p>
|
|
123
|
+
<ul>
|
|
124
|
+
<li v-for="item in items" :key="item.id">
|
|
125
|
+
{{ item.name }}
|
|
126
|
+
<button @click="removeItem(item.id)">Remove</button>
|
|
127
|
+
</li>
|
|
128
|
+
</ul>
|
|
129
|
+
<button @click="clearCart">Clear All</button>
|
|
130
|
+
</div>
|
|
131
|
+
</template>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Alternative: Don't Destructure
|
|
135
|
+
|
|
136
|
+
If you prefer, you can avoid destructuring entirely:
|
|
137
|
+
|
|
138
|
+
```vue
|
|
139
|
+
<script setup>
|
|
140
|
+
import { useUserStore } from '@/stores/user'
|
|
141
|
+
|
|
142
|
+
const userStore = useUserStore()
|
|
143
|
+
// Use userStore.name, userStore.login(), etc. directly
|
|
144
|
+
</script>
|
|
145
|
+
|
|
146
|
+
<template>
|
|
147
|
+
<div>{{ userStore.name }}</div>
|
|
148
|
+
<button @click="userStore.logout()">Logout</button>
|
|
149
|
+
</template>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
This works fine but is more verbose for stores used frequently in the template.
|
|
153
|
+
|
|
154
|
+
## Common Mistake: Mixing storeToRefs with Actions
|
|
155
|
+
|
|
156
|
+
```vue
|
|
157
|
+
<script setup>
|
|
158
|
+
import { storeToRefs } from 'pinia'
|
|
159
|
+
import { useUserStore } from '@/stores/user'
|
|
160
|
+
|
|
161
|
+
const userStore = useUserStore()
|
|
162
|
+
|
|
163
|
+
// WRONG: Don't include actions in storeToRefs
|
|
164
|
+
// Actions are just functions and storeToRefs will skip them anyway
|
|
165
|
+
const { name, login } = storeToRefs(userStore)
|
|
166
|
+
// login is undefined! Actions aren't included in storeToRefs result
|
|
167
|
+
|
|
168
|
+
// CORRECT: Separate state/getters from actions
|
|
169
|
+
const { name } = storeToRefs(userStore)
|
|
170
|
+
const { login } = userStore
|
|
171
|
+
</script>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## TypeScript Tip
|
|
175
|
+
|
|
176
|
+
With TypeScript, the types work correctly:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { storeToRefs } from 'pinia'
|
|
180
|
+
import { useUserStore } from '@/stores/user'
|
|
181
|
+
|
|
182
|
+
const userStore = useUserStore()
|
|
183
|
+
|
|
184
|
+
// name is Ref<string>, email is Ref<string>
|
|
185
|
+
const { name, email } = storeToRefs(userStore)
|
|
186
|
+
|
|
187
|
+
// login is (credentials: Credentials) => Promise<void>
|
|
188
|
+
const { login } = userStore
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Reference
|
|
192
|
+
- [Pinia - Destructuring from a Store](https://pinia.vuejs.org/core-concepts/#destructuring-from-a-store)
|
|
193
|
+
- [Pinia API - storeToRefs](https://pinia.vuejs.org/api/modules/pinia.html#storetorefs)
|