@gong-ym/ai-spec-auto 0.2.13 → 0.2.15
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/.agents/commands/README.md +33 -33
- package/.agents/commands/claude/spec-start-review.md +88 -88
- package/.agents/commands/codex/spec-continue.md +74 -74
- package/.agents/commands/codex/spec-orchestrate.md +35 -35
- package/.agents/commands/codex/spec-start-review.md +88 -88
- package/.agents/commands/codex/spec-start.md +67 -67
- package/.agents/commands/codex/spec-status.md +22 -22
- package/.agents/commands/codex/spec-stop.md +29 -29
- package/.agents/commands/codex/spec-update.md +40 -40
- package/.agents/commands/common/branch-review.md +117 -117
- package/.agents/commands/common/project-init.md +25 -25
- package/.agents/commands/common/spec-continue.md +74 -74
- package/.agents/commands/common/spec-orchestrate.md +35 -35
- package/.agents/commands/common/spec-start-review.md +82 -82
- package/.agents/commands/common/spec-start.md +67 -67
- package/.agents/commands/common/spec-status.md +22 -22
- package/.agents/commands/common/spec-stop.md +29 -29
- package/.agents/commands/common/spec-update.md +60 -40
- package/.agents/commands/cursor/opsx-apply.md +55 -55
- package/.agents/commands/cursor/opsx-archive.md +48 -48
- package/.agents/commands/cursor/opsx-explore.md +45 -45
- package/.agents/commands/cursor/opsx-propose.md +59 -59
- package/.agents/commands/cursor/spec-continue.md +63 -63
- package/.agents/commands/cursor/spec-orchestrate.md +53 -53
- package/.agents/commands/cursor/spec-start-review.md +78 -78
- package/.agents/commands/cursor/spec-start.md +59 -59
- package/.agents/commands/cursor/spec-status.md +30 -30
- package/.agents/commands/cursor/spec-stop.md +29 -29
- package/.agents/commands/cursor/spec-update.md +41 -41
- package/.agents/flows/FRONTMATTER.md +263 -263
- package/.agents/flows/RUN_OUTPUT.md +263 -263
- package/.agents/flows/common/README.md +29 -29
- package/.agents/flows/common/bugfix-to-verification.md +95 -95
- package/.agents/flows/common/change-to-architecture-review.md +89 -89
- package/.agents/flows/common/change-to-release.md +94 -94
- package/.agents/flows/common/prd-to-delivery.md +184 -184
- package/.agents/flows/common/requirement-to-observability.md +97 -97
- package/.agents/orchestration/README.md +22 -22
- package/.agents/orchestration/expert-dispatch-spec.md +155 -155
- package/.agents/orchestration/expert-executor-spec.md +84 -84
- package/.agents/orchestration/expert-runtime-action-spec.md +73 -73
- package/.agents/orchestration/runtime-state-handoff-spec.md +264 -264
- package/.agents/orchestration/task-anchor-spec.md +212 -212
- package/.agents/orchestration/task-orchestrator-adapter-payload.md +153 -153
- package/.agents/orchestration/task-orchestrator-bootstrap-payload.md +145 -145
- package/.agents/orchestration/task-orchestrator-output-extractor-spec.md +93 -93
- package/.agents/orchestration/task-orchestrator-run-plan-template.md +312 -312
- package/.agents/orchestration/task-orchestrator-runtime-hooks.md +214 -214
- package/.agents/registry/README.md +63 -63
- package/.agents/registry/flows.json +125 -125
- package/.agents/registry/profiles.json +101 -101
- package/.agents/registry/roles.json +1265 -1265
- package/.agents/registry/rules.json +148 -148
- package/.agents/registry/scenario-packages.json +123 -123
- package/.agents/registry/skills.json +130 -130
- package/.agents/roles/INDEX.md +346 -346
- package/.agents/roles/common/README.md +76 -76
- package/.agents/roles/common/archive-change.md +80 -80
- package/.agents/roles/common/backend-implementer.md +92 -92
- package/.agents/roles/common/code-guardian.md +151 -151
- package/.agents/roles/common/frontend-implementer.md +146 -146
- package/.agents/roles/common/requirement-analyst.md +138 -138
- package/.agents/roles/common/task-orchestrator-routing.md +301 -301
- package/.agents/roles/common/task-orchestrator.md +224 -224
- package/.agents/roles/common/tooling-implementer.md +92 -92
- package/.agents/roles/domains/README.md +35 -35
- package/.agents/roles/domains/delivery/README.md +11 -11
- package/.agents/roles/domains/delivery/container-specialist.md +50 -50
- package/.agents/roles/domains/delivery/deployment-specialist.md +50 -50
- package/.agents/roles/domains/delivery/pipeline-specialist.md +50 -50
- package/.agents/roles/domains/demand-design/README.md +16 -16
- package/.agents/roles/domains/demand-design/api-contract-specialist.md +52 -52
- package/.agents/roles/domains/demand-design/design-collaborator.md +58 -58
- package/.agents/roles/domains/documentation/README.md +11 -11
- package/.agents/roles/domains/documentation/api-doc-specialist.md +50 -50
- package/.agents/roles/domains/documentation/component-doc-specialist.md +49 -49
- package/.agents/roles/domains/documentation/technical-writing-specialist.md +48 -48
- package/.agents/roles/domains/engineering/README.md +17 -17
- package/.agents/roles/domains/engineering/architecture-advisor.md +53 -53
- package/.agents/roles/domains/engineering/build-specialist.md +51 -51
- package/.agents/roles/domains/engineering/dependency-governor.md +52 -52
- package/.agents/roles/domains/governance/README.md +17 -17
- package/.agents/roles/domains/governance/api-governance-specialist.md +51 -51
- package/.agents/roles/domains/governance/lint-policy-specialist.md +49 -49
- package/.agents/roles/domains/governance/route-governance-specialist.md +52 -52
- package/.agents/roles/domains/observability/README.md +11 -11
- package/.agents/roles/domains/observability/error-tracker.md +50 -50
- package/.agents/roles/domains/observability/event-instrumentation-specialist.md +51 -51
- package/.agents/roles/domains/observability/rum-analyst.md +50 -50
- package/.agents/roles/domains/performance/README.md +11 -11
- package/.agents/roles/domains/performance/asset-optimizer.md +50 -50
- package/.agents/roles/domains/performance/performance-auditor.md +56 -56
- package/.agents/roles/domains/performance/vitals-analyst.md +50 -50
- package/.agents/roles/domains/security-a11y/README.md +11 -11
- package/.agents/roles/domains/security-a11y/a11y-auditor.md +50 -50
- package/.agents/roles/domains/security-a11y/aria-specialist.md +51 -51
- package/.agents/roles/domains/security-a11y/security-reviewer.md +49 -49
- package/.agents/roles/domains/testing/README.md +12 -12
- package/.agents/roles/domains/testing/coverage-analyst.md +50 -50
- package/.agents/roles/domains/testing/e2e-test-specialist.md +51 -51
- package/.agents/roles/domains/testing/unit-test-specialist.md +56 -56
- package/.agents/roles/domains/testing/verification-reviewer.md +67 -67
- package/.agents/rules/README.md +87 -87
- package/.agents/rules/common/02-/347/274/226/347/240/201/350/247/204/350/214/203.md +45 -45
- package/.agents/rules/common/08-/351/200/232/347/224/250/347/272/246/346/235/237.md +63 -63
- package/.agents/rules/common/10-/346/226/207/346/241/243/350/247/204/350/214/203.md +101 -101
- package/.agents/rules/common/12-Superpowers/346/211/247/350/241/214/350/247/204/350/214/203.md +46 -46
- package/.agents/rules/common/14-/345/256/241/350/256/241/346/261/207/346/212/245/350/247/204/350/214/203.md +107 -107
- package/.agents/rules/common/15-visual-gate-wait.md +90 -90
- package/.agents/rules/profiles/nestjs/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +27 -27
- package/.agents/rules/profiles/nestjs/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +20 -20
- package/.agents/rules/profiles/nestjs/04-/346/250/241/345/235/227/347/273/223/346/236/204/350/247/204/350/214/203.md +24 -24
- package/.agents/rules/profiles/nestjs/05-/346/216/245/345/217/243/344/270/216/345/245/221/347/272/246/350/247/204/350/214/203.md +24 -24
- package/.agents/rules/profiles/nestjs/06-/346/225/260/346/215/256/350/256/277/351/227/256/350/247/204/350/214/203.md +24 -24
- package/.agents/rules/profiles/nestjs/07-/351/205/215/347/275/256/344/270/216/350/277/220/350/241/214/346/227/266/350/247/204/350/214/203.md +20 -20
- package/.agents/rules/profiles/nestjs/09-/345/274/202/345/270/270/344/270/216/346/227/245/345/277/227/350/247/204/350/214/203.md +20 -20
- package/.agents/rules/profiles/nestjs/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +24 -24
- package/.agents/rules/profiles/nestjs/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +20 -20
- package/.agents/rules/profiles/node-tooling/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +30 -30
- package/.agents/rules/profiles/node-tooling/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +37 -37
- package/.agents/rules/profiles/node-tooling/04-CLI/344/270/216/346/250/241/345/235/227/350/247/204/350/214/203.md +42 -42
- package/.agents/rules/profiles/node-tooling/05-Contract/344/270/216Schema/350/247/204/350/214/203.md +42 -42
- package/.agents/rules/profiles/node-tooling/06-/350/277/220/350/241/214/346/227/266/346/226/207/344/273/266/350/247/204/350/214/203.md +30 -30
- package/.agents/rules/profiles/node-tooling/07-/346/227/245/345/277/227/344/270/216/351/224/231/350/257/257/345/244/204/347/220/206/350/247/204/350/214/203.md +60 -60
- package/.agents/rules/profiles/node-tooling/09-/350/204/232/346/234/254/344/270/216/345/205/245/345/217/243/350/247/204/350/214/203.md +45 -45
- package/.agents/rules/profiles/node-tooling/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +41 -41
- package/.agents/rules/profiles/node-tooling/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +55 -55
- package/.agents/rules/profiles/react/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +29 -29
- package/.agents/rules/profiles/react/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +104 -104
- package/.agents/rules/profiles/react/04-/347/273/204/344/273/266/350/247/204/350/214/203.md +46 -46
- package/.agents/rules/profiles/react/05-API/350/247/204/350/214/203.md +67 -67
- package/.agents/rules/profiles/react/06-/350/267/257/347/224/261/350/247/204/350/214/203.md +54 -54
- package/.agents/rules/profiles/react/07-/347/212/266/346/200/201/347/256/241/347/220/206.md +226 -226
- package/.agents/rules/profiles/react/09-/346/240/267/345/274/217/350/247/204/350/214/203.md +71 -71
- package/.agents/rules/profiles/react/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +80 -80
- package/.agents/rules/profiles/react/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +159 -159
- package/.agents/rules/profiles/springboot/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +31 -31
- package/.agents/rules/profiles/springboot/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +37 -37
- package/.agents/rules/profiles/springboot/04-/345/210/206/345/261/202/350/247/204/350/214/203.md +33 -33
- package/.agents/rules/profiles/springboot/05-/346/216/245/345/217/243/344/270/216/345/245/221/347/272/246/350/247/204/350/214/203.md +51 -51
- package/.agents/rules/profiles/springboot/06-/346/225/260/346/215/256/350/256/277/351/227/256/350/247/204/350/214/203.md +34 -34
- package/.agents/rules/profiles/springboot/07-/351/205/215/347/275/256/344/270/216/350/277/220/350/241/214/346/227/266/350/247/204/350/214/203.md +38 -38
- package/.agents/rules/profiles/springboot/09-/345/274/202/345/270/270/344/270/216/346/227/245/345/277/227/350/247/204/350/214/203.md +48 -48
- package/.agents/rules/profiles/springboot/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +43 -43
- package/.agents/rules/profiles/springboot/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +48 -48
- package/.agents/rules/profiles/vue/01-/351/241/271/347/233/256/346/246/202/350/277/260.md +47 -47
- package/.agents/rules/profiles/vue/03-/351/241/271/347/233/256/347/273/223/346/236/204.md +106 -106
- package/.agents/rules/profiles/vue/04-/347/273/204/344/273/266/350/247/204/350/214/203.md +61 -61
- package/.agents/rules/profiles/vue/05-API/350/247/204/350/214/203.md +67 -67
- package/.agents/rules/profiles/vue/06-/350/267/257/347/224/261/350/247/204/350/214/203.md +69 -69
- package/.agents/rules/profiles/vue/07-/347/212/266/346/200/201/347/256/241/347/220/206.md +93 -93
- package/.agents/rules/profiles/vue/09-/346/240/267/345/274/217/350/247/204/350/214/203.md +67 -67
- package/.agents/rules/profiles/vue/11-/346/265/213/350/257/225/350/247/204/350/214/203.md +80 -80
- package/.agents/rules/profiles/vue/13-/344/273/243/347/240/201/346/240/274/345/274/217/345/214/226/344/270/216/346/243/200/346/237/245.md +159 -159
- package/.agents/skills/README.md +171 -171
- package/.agents/skills/common/archive-change/SKILL.md +180 -180
- package/.agents/skills/common/branch-code-reviewer/SKILL.md +533 -459
- package/.agents/skills/common/branch-code-reviewer/references/business-risk-guide.md +293 -293
- package/.agents/skills/common/branch-code-reviewer/references/html-template-guide.md +121 -121
- package/.agents/skills/common/config-and-secret-scan/SKILL.md +99 -99
- package/.agents/skills/common/create-proposal/SKILL.md +192 -192
- package/.agents/skills/common/create-proposal/evals/evals.json +16 -16
- package/.agents/skills/common/create-proposal/evals/train_queries.json +18 -18
- package/.agents/skills/common/create-proposal/evals/validation_queries.json +18 -18
- package/.agents/skills/common/create-proposal/references/interaction-spec-template.md +42 -42
- package/.agents/skills/common/create-test/SKILL.md +292 -292
- package/.agents/skills/common/dependency-impact-graph/SKILL.md +80 -80
- package/.agents/skills/common/execute-task/SKILL.md +206 -206
- package/.agents/skills/common/execute-task/evals/evals.json +16 -16
- package/.agents/skills/common/execute-task/evals/train_queries.json +18 -18
- package/.agents/skills/common/execute-task/evals/validation_queries.json +18 -18
- package/.agents/skills/common/find-skills/SKILL.md +144 -144
- package/.agents/skills/common/install-ai-spec-auto/SKILL.md +260 -260
- package/.agents/skills/common/install-ai-spec-auto/evals/evals.json +17 -17
- package/.agents/skills/common/install-ai-spec-auto/evals/train_queries.json +18 -18
- package/.agents/skills/common/install-ai-spec-auto/evals/validation_queries.json +18 -18
- package/.agents/skills/common/project-init/SKILL.md +178 -178
- package/.agents/skills/common/project-init/evals/evals.json +16 -16
- package/.agents/skills/common/project-init/evals/train_queries.json +18 -18
- package/.agents/skills/common/project-init/evals/validation_queries.json +18 -18
- package/.agents/skills/common/project-init/references/custom-rule-generation.md +89 -89
- package/.agents/skills/common/project-init/references/deep-scan-rules.md +67 -67
- package/.agents/skills/common/project-init/references/output-contracts.md +71 -71
- package/.agents/skills/common/project-init/references/repo-fact-gathering.md +83 -83
- package/.agents/skills/common/project-init/references/scope-resolution.md +76 -76
- package/.agents/skills/common/project-init/scripts/inspect-project.js +112 -112
- package/.agents/skills/common/skill-creator/LICENSE.txt +201 -201
- package/.agents/skills/common/skill-creator/SKILL.md +370 -370
- package/.agents/skills/common/skill-creator/evals/evals.json +16 -16
- package/.agents/skills/common/skill-creator/evals/train_queries.json +18 -18
- package/.agents/skills/common/skill-creator/evals/validation_queries.json +18 -18
- package/.agents/skills/common/skill-creator/references/output-patterns.md +82 -82
- package/.agents/skills/common/skill-creator/references/workflows.md +27 -27
- package/.agents/skills/common/skill-creator/scripts/init_skill.py +209 -209
- package/.agents/skills/common/skill-creator/scripts/package_skill.py +110 -110
- package/.agents/skills/common/skill-creator/scripts/quick_validate.py +51 -51
- package/.agents/skills/common/skill-optimizer/SKILL.md +102 -102
- package/.agents/skills/common/skill-optimizer/evals/evals.json +16 -16
- package/.agents/skills/common/skill-optimizer/evals/train_queries.json +18 -18
- package/.agents/skills/common/skill-optimizer/evals/validation_queries.json +18 -18
- package/.agents/skills/common/skill-optimizer/references/design-patterns.md +26 -26
- package/.agents/skills/common/skill-optimizer/references/review-checklist.md +22 -22
- package/.agents/skills/common/using-superpowers/SKILL.md +151 -151
- package/.agents/skills/common/wait-for-gate-signal/SKILL.md +85 -85
- package/.agents/skills/domains/README.md +19 -19
- package/.agents/skills/domains/ui-ux-pro-max/SKILL.md +58 -58
- package/.agents/skills/domains/web/design-analysis/SKILL.md +89 -89
- package/.agents/skills/domains/web/design-analysis/rules/analysis-order.md +61 -61
- package/.agents/skills/domains/web/design-analysis/rules/analysis-priorities.md +136 -136
- package/.agents/skills/domains/web/design-analysis/rules/checklist-common-misses.md +107 -107
- package/.agents/skills/domains/web/design-analysis/rules/implementation-common-errors.md +204 -204
- package/.agents/skills/domains/web/design-analysis/rules/implementation-guidelines.md +211 -211
- package/.agents/skills/domains/web/design-analysis/rules/output-analysis-checklist.md +247 -247
- package/.agents/skills/domains/web/design-analysis/rules/tools-design-guidelines.md +108 -108
- package/.agents/skills/domains/web/design-analysis/rules/workflow-element-extraction.md +162 -162
- package/.agents/skills/domains/web/design-analysis/rules/workflow-layout-map.md +131 -131
- package/.agents/skills/domains/web/design-analysis/rules/workflow-output-checklist.md +70 -70
- package/.agents/skills/domains/web/design-analysis/rules/workflow-style-summary.md +91 -91
- package/.agents/skills/domains/web/route-permission-map/SKILL.md +103 -103
- package/.agents/skills/domains/web/ui-verification/SKILL.md +114 -114
- package/.agents/skills/domains/web/ui-verification/evals/evals.json +16 -16
- package/.agents/skills/domains/web/ui-verification/evals/train_queries.json +18 -18
- package/.agents/skills/domains/web/ui-verification/evals/validation_queries.json +18 -18
- package/.agents/skills/domains/web/ui-verification/rules/comparison-content-image.md +34 -34
- package/.agents/skills/domains/web/ui-verification/rules/comparison-content-text.md +30 -30
- package/.agents/skills/domains/web/ui-verification/rules/comparison-hierarchy.md +33 -33
- package/.agents/skills/domains/web/ui-verification/rules/comparison-layout.md +35 -35
- package/.agents/skills/domains/web/ui-verification/rules/errors-alignment.md +42 -42
- package/.agents/skills/domains/web/ui-verification/rules/errors-button-dimensions.md +28 -28
- package/.agents/skills/domains/web/ui-verification/rules/errors-button-position.md +25 -25
- package/.agents/skills/domains/web/ui-verification/rules/errors-css-priority.md +50 -50
- package/.agents/skills/domains/web/ui-verification/rules/errors-flex-column-width.md +46 -46
- package/.agents/skills/domains/web/ui-verification/rules/errors-flex-layout.md +46 -46
- package/.agents/skills/domains/web/ui-verification/rules/errors-grid-container-width.md +44 -44
- package/.agents/skills/domains/web/ui-verification/rules/errors-page-container-width.md +39 -39
- package/.agents/skills/domains/web/ui-verification/rules/tools-browser-navigation.md +53 -53
- package/.agents/skills/domains/web/ui-verification/rules/tools-design-guidelines.md +53 -53
- package/.agents/skills/domains/web/ui-verification/rules/workflow-checklist.md +27 -27
- package/.agents/skills/domains/web/ui-verification/rules/workflow-problem-list.md +56 -56
- package/.agents/skills/domains/web/ui-verification/rules/workflow-reflection.md +44 -44
- package/.agents/skills/domains/web/ui-verification/rules/writing-alignment.md +44 -44
- package/.agents/skills/domains/web/ui-verification/rules/writing-element-completeness.md +63 -63
- package/.agents/skills/domains/web/ui-verification/rules/writing-list-layout.md +75 -75
- package/.agents/skills/domains/web/ui-verification/rules/writing-page-container-width.md +37 -37
- package/.agents/skills/domains/web/web-design-guidelines/SKILL.md +40 -40
- package/.agents/skills/profiles/nestjs/README.md +4 -4
- package/.agents/skills/profiles/node-tooling/README.md +9 -9
- package/.agents/skills/profiles/react/create-api/SKILL.md +145 -145
- package/.agents/skills/profiles/react/create-component/SKILL.md +160 -160
- package/.agents/skills/profiles/react/create-route/SKILL.md +168 -168
- package/.agents/skills/profiles/react/create-store/SKILL.md +262 -262
- package/.agents/skills/profiles/react/theme-variables/SKILL.md +82 -82
- package/.agents/skills/profiles/react/vercel-composition-patterns/AGENTS.md +899 -899
- package/.agents/skills/profiles/react/vercel-composition-patterns/SKILL.md +81 -81
- package/.agents/skills/profiles/react/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -100
- package/.agents/skills/profiles/react/vercel-composition-patterns/rules/architecture-compound-components.md +112 -112
- package/.agents/skills/profiles/react/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -87
- package/.agents/skills/profiles/react/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -100
- package/.agents/skills/profiles/react/vercel-composition-patterns/rules/state-context-interface.md +191 -191
- package/.agents/skills/profiles/react/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -113
- package/.agents/skills/profiles/react/vercel-composition-patterns/rules/state-lift-state.md +125 -125
- package/.agents/skills/profiles/react/vercel-react-best-practices/AGENTS.md +2934 -2934
- package/.agents/skills/profiles/react/vercel-react-best-practices/SKILL.md +136 -136
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -55
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/advanced-init-once.md +42 -42
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/advanced-use-latest.md +39 -39
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-api-routes.md +38 -38
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-defer-await.md +80 -80
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-dependencies.md +51 -51
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-parallel.md +28 -28
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -99
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -59
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-conditional.md +31 -31
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -49
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -35
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/bundle-preload.md +50 -50
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-event-listeners.md +74 -74
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -71
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -48
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/client-swr-dedup.md +56 -56
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -107
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-cache-function-results.md +80 -80
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-cache-property-access.md +28 -28
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-cache-storage.md +70 -70
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-combine-iterations.md +32 -32
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-early-exit.md +50 -50
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -45
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-index-maps.md +37 -37
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-length-check-first.md +49 -49
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-min-max-loop.md +82 -82
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -24
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -57
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-activity.md +26 -26
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -47
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -40
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -38
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -46
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -82
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -30
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -28
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -75
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -39
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-dependencies.md +45 -45
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -40
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-derived-state.md +29 -29
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -74
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -58
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -38
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-memo.md +44 -44
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -45
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -35
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-transitions.md +40 -40
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -73
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -73
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-auth-actions.md +96 -96
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-cache-lru.md +41 -41
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-cache-react.md +76 -76
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-dedup-props.md +65 -65
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -83
- package/.agents/skills/profiles/react/vercel-react-best-practices/rules/server-serialization.md +38 -38
- package/.agents/skills/profiles/springboot/README.md +10 -10
- package/.agents/skills/profiles/vue/create-api/SKILL.md +105 -105
- package/.agents/skills/profiles/vue/create-component/SKILL.md +76 -76
- package/.agents/skills/profiles/vue/create-route/SKILL.md +141 -141
- package/.agents/skills/profiles/vue/create-store/SKILL.md +97 -97
- package/.agents/skills/profiles/vue/create-view/SKILL.md +81 -81
- package/.agents/skills/profiles/vue/theme-variables/SKILL.md +73 -73
- package/.agents/skills/profiles/vue/vue-best-practices/SKILL.md +166 -166
- package/.agents/skills/profiles/vue/vue-best-practices/references/animation-class-based-technique.md +254 -254
- package/.agents/skills/profiles/vue/vue-best-practices/references/animation-state-driven-technique.md +291 -291
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-async.md +97 -97
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-data-flow.md +307 -307
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-fallthrough-attrs.md +174 -174
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-keep-alive.md +137 -137
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-slots.md +216 -216
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-suspense.md +228 -228
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-teleport.md +108 -108
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-transition-group.md +128 -128
- package/.agents/skills/profiles/vue/vue-best-practices/references/component-transition.md +125 -125
- package/.agents/skills/profiles/vue/vue-best-practices/references/composables.md +290 -290
- package/.agents/skills/profiles/vue/vue-best-practices/references/directives.md +162 -162
- package/.agents/skills/profiles/vue/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -159
- package/.agents/skills/profiles/vue/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -182
- package/.agents/skills/profiles/vue/vue-best-practices/references/perf-virtualize-large-lists.md +187 -187
- package/.agents/skills/profiles/vue/vue-best-practices/references/plugins.md +166 -166
- package/.agents/skills/profiles/vue/vue-best-practices/references/reactivity.md +344 -344
- package/.agents/skills/profiles/vue/vue-best-practices/references/render-functions.md +201 -201
- package/.agents/skills/profiles/vue/vue-best-practices/references/sfc.md +310 -310
- package/.agents/skills/profiles/vue/vue-best-practices/references/state-management.md +135 -135
- package/.agents/skills/profiles/vue/vue-best-practices/references/updated-hook-performance.md +187 -187
- package/.agents/templates/common/README.md +23 -23
- package/.agents/templates/common/bugfix.md +22 -22
- package/.agents/templates/common/create-expert-package.md +458 -458
- package/.agents/templates/common/mock-page.md +28 -28
- package/.agents/templates/common/new-component.md +25 -25
- package/.agents/templates/common/new-page.md +31 -31
- package/.cursor/mcp.json +35 -35
- package/.qoder/mcp.json +26 -26
- package/bin/archive-change.js +560 -474
- package/bin/check-command.js +62 -62
- package/bin/cli.js +0 -0
- package/bin/command-template-renderer.js +40 -40
- package/bin/context-command.js +102 -102
- package/bin/demo-runtime-smoke.js +760 -760
- package/bin/execution-semantics.js +821 -821
- package/bin/executor-command.js +93 -93
- package/bin/expert-dispatch.js +334 -334
- package/bin/expert-executor.js +1148 -1148
- package/bin/guard-command.js +52 -52
- package/bin/hub-command.js +876 -876
- package/bin/ide-command.js +242 -242
- package/bin/init-command.js +193 -193
- package/bin/install-workflow.js +35 -3
- package/bin/manifest-export.js +34 -34
- package/bin/profile-registry.js +90 -90
- package/bin/protocol-workflow.js +452 -446
- package/bin/repair-command.js +161 -161
- package/bin/repo-map.js +177 -177
- package/bin/report-command.js +236 -236
- package/bin/runtime-bootstrap.js +428 -428
- package/bin/runtime-embedded.js +101 -101
- package/bin/runtime-fallback.js +106 -106
- package/bin/runtime-launcher.js +116 -116
- package/bin/runtime-paths.js +177 -177
- package/bin/runtime-registry.js +289 -289
- package/bin/runtime-state.js +2541 -2541
- package/bin/scan.js +96 -96
- package/bin/self-upgrade.js +206 -206
- package/bin/skill-spec-validator.js +457 -457
- package/bin/spec-command.js +366 -366
- package/bin/superpowers.js +384 -384
- package/bin/sync-command.js +59 -59
- package/bin/sync.js +1904 -1904
- package/bin/task-orchestrator-adapter.js +341 -341
- package/bin/task-orchestrator-extractor.js +274 -274
- package/bin/task-orchestrator-runner.js +1208 -1208
- package/bin/telemetry/README.md +66 -66
- package/bin/telemetry/aspect.js +153 -153
- package/bin/telemetry/collect.js +67 -67
- package/bin/telemetry/config.js +114 -114
- package/bin/telemetry/defaults.json +5 -5
- package/bin/telemetry/healthcheck.js +195 -195
- package/bin/telemetry/identity.js +53 -53
- package/bin/telemetry/index.js +25 -25
- package/bin/telemetry/reporter.js +83 -83
- package/bin/telemetry/safe.js +39 -39
- package/bin/validate-registry.js +740 -740
- package/bin/visual-bridge-config.js +117 -117
- package/bin/visual-bridge.js +287 -287
- package/bin/visual-command.js +432 -432
- package/bin/worktree-command.js +194 -194
- package/configs/common/.editorconfig +15 -15
- package/configs/common/.husky/commit-msg +4 -4
- package/configs/common/.husky/pre-commit +4 -4
- package/configs/common/.lintstagedrc +11 -11
- package/configs/common/.prettierignore +11 -11
- package/configs/common/.prettierrc.json +11 -11
- package/configs/common/.stylelintignore +14 -14
- package/configs/common/.stylelintrc.json +21 -21
- package/configs/common/commitlint.config.js +3 -3
- package/configs/profiles/nestjs/.gitkeep +1 -1
- package/configs/profiles/node-tooling/.gitkeep +1 -1
- package/configs/profiles/react/.eslintignore +6 -6
- package/configs/profiles/react/.eslintrc.js +16 -16
- package/configs/profiles/react/.stylelintrc.json +18 -18
- package/configs/profiles/springboot/.gitkeep +1 -1
- package/configs/profiles/vue/.eslintignore +6 -6
- package/configs/profiles/vue/.eslintrc.cjs +17 -17
- package/contracts/README.md +28 -28
- package/contracts/fixtures/asset-package.fixture.json +26 -26
- package/contracts/fixtures/asset-usage-feedback.fixture.json +14 -14
- package/contracts/fixtures/evidence-report.fixture.json +28 -28
- package/contracts/fixtures/manifest.fixture.json +20 -20
- package/contracts/fixtures/run-event.fixture.json +15 -15
- package/contracts/schemas/asset-package.schema.json +76 -76
- package/contracts/schemas/asset-usage-feedback.schema.json +57 -57
- package/contracts/schemas/evidence-report.schema.json +60 -60
- package/contracts/schemas/manifest.schema.json +63 -63
- package/contracts/schemas/run-event.schema.json +72 -72
- package/install.ps1 +35 -35
- package/install.sh +17 -17
- package/internal/ai-protocol-workflow.js +5824 -5600
- package/internal/hub-client.js +98 -98
- package/internal/hub-sync-selection.js +69 -69
- package/internal/visual-hooks/README.md +481 -481
- package/internal/visual-hooks/config-loader.js +218 -218
- package/internal/visual-hooks/control-puller.js +206 -206
- package/internal/visual-hooks/gate-signal.js +150 -150
- package/internal/visual-hooks/inbox-consumer.js +469 -469
- package/internal/visual-hooks/index.js +197 -197
- package/internal/visual-hooks/push-client.js +189 -189
- package/internal/visual-hooks/receipt-pusher.js +176 -176
- package/internal/visual-hooks/runtime-state-pusher.js +128 -128
- package/openspec/config.yaml.template +52 -52
- package/openspec/schemas/expert-delivery/schema.yaml +68 -68
- package/openspec/schemas/expert-delivery/templates/checklist.md +39 -39
- package/openspec/schemas/expert-delivery/templates/design.md +61 -61
- package/openspec/schemas/expert-delivery/templates/iterations.md +25 -25
- package/openspec/schemas/expert-delivery/templates/proposal.md +45 -45
- package/openspec/schemas/expert-delivery/templates/spec.md +29 -29
- package/openspec/schemas/expert-delivery/templates/tasks.md +24 -24
- package/package.json +1 -1
- package/scripts/acceptance-zero-intrusion.sh +168 -168
- package/scripts/hub-sync-assets.config.example.json +296 -296
- package/scripts/hub-sync-assets.js +2038 -2038
- package/scripts/local-verify.sh +280 -280
- package/scripts/post-publish-auto-fix-check.js +404 -404
- package/scripts/post-publish-verify.sh +175 -175
- package/scripts/setup-cursor-manual-test.sh +107 -107
- package/scripts/setup-cursor-spec-archive-test.sh +111 -111
- package/scripts/setup-visual-integration.sh +225 -225
- package/scripts/test-integration.sh +176 -176
- package/scripts/update-test-project.sh +93 -93
- package/scripts/upload-four-web.sh +57 -57
- package/scripts/verify-install-ps1-bom.js +26 -26
- package/src/agent/agent-context.js +259 -259
- package/src/agent/agent-profile.js +185 -185
- package/src/agent/agent-templates.js +161 -161
- package/src/agent/agent-types.js +108 -108
- package/src/agent/collaboration-protocol.js +333 -333
- package/src/agent/conflict-handler.js +364 -364
- package/src/agent/file-permission.js +121 -121
- package/src/agent/index.js +38 -38
- package/src/agent/permission-audit.js +151 -151
- package/src/agent/review-repair-loop.js +270 -270
- package/src/agent/tool-permission.js +101 -101
- package/src/asset/asset-dependency.js +322 -322
- package/src/asset/asset-feedback.js +350 -350
- package/src/asset/asset-fork.js +300 -300
- package/src/asset/asset-install.js +278 -278
- package/src/asset/asset-installer.js +497 -497
- package/src/asset/asset-lifecycle.js +324 -324
- package/src/asset/asset-manager.js +245 -245
- package/src/asset/asset-package-manager.js +349 -349
- package/src/asset/asset-package.js +186 -186
- package/src/asset/asset-quality.js +262 -262
- package/src/asset/asset-registry.js +387 -387
- package/src/asset/asset-version.js +293 -293
- package/src/asset/index.js +86 -86
- package/src/cache/agent-profile-cache.js +59 -59
- package/src/cache/asset-cache.js +63 -63
- package/src/cache/global-cache.js +61 -61
- package/src/cache/manifest-cache.js +30 -30
- package/src/check/check-service.js +32 -32
- package/src/config/config-layer.js +343 -343
- package/src/config/config-loader.js +60 -60
- package/src/config/defaults.js +49 -49
- package/src/connectors/hub/asset-package.js +72 -72
- package/src/connectors/hub/asset-usage-feedback.js +46 -46
- package/src/connectors/hub/hub-connector.js +44 -44
- package/src/connectors/hub/index.js +21 -21
- package/src/connectors/visual/evidence-report.js +49 -49
- package/src/connectors/visual/index.js +15 -15
- package/src/connectors/visual/queue.js +41 -41
- package/src/connectors/visual/run-event.js +81 -81
- package/src/connectors/visual/visual-connector.js +77 -77
- package/src/context/context-budget.js +59 -59
- package/src/context/context-builder.js +285 -285
- package/src/context/context-loader.js +116 -116
- package/src/context/context-planner.js +158 -158
- package/src/context/types.js +96 -96
- package/src/contracts/index.js +63 -63
- package/src/executor/executor-registry.js +78 -78
- package/src/executor/executor-result-parser.js +44 -44
- package/src/executor/executor-runner.js +141 -141
- package/src/executor/executor-selector.js +139 -139
- package/src/executor/executor-timeout.js +36 -36
- package/src/executor/providers/base-provider-utils.js +189 -189
- package/src/executor/providers/claude-code-executor-provider.js +128 -128
- package/src/executor/providers/codex-executor-provider.js +126 -126
- package/src/executor/providers/cursor-executor-provider.js +99 -99
- package/src/executor/types.js +137 -137
- package/src/git/branch-manager.js +71 -71
- package/src/git/dirty-checker.js +43 -43
- package/src/git/dirty-strategy-handler.js +29 -29
- package/src/git/git-command.js +37 -37
- package/src/git/git-repository-detector.js +45 -45
- package/src/git/multi-repo-worktree-planner.js +88 -88
- package/src/git/policy.js +19 -19
- package/src/git/strategies/block-dirty-strategy.js +34 -34
- package/src/git/strategies/ignore-dirty-strategy.js +33 -33
- package/src/git/strategies/patch-snapshot-strategy.js +53 -53
- package/src/git/strategies/wip-commit-strategy.js +38 -38
- package/src/git/types.js +71 -71
- package/src/git/worktree-manager.js +85 -85
- package/src/governance/asset-review.js +351 -351
- package/src/governance/audit-log.js +368 -368
- package/src/governance/gray-release.js +312 -312
- package/src/governance/index.js +31 -31
- package/src/governance/policy-types.js +56 -56
- package/src/governance/rbac-types.js +171 -171
- package/src/governance/rbac.js +382 -382
- package/src/governance/rollback.js +360 -360
- package/src/governance/security-policy.js +354 -354
- package/src/hook/hook-config-writer.js +125 -125
- package/src/hub/hub-client.js +186 -186
- package/src/hub/hub-config.js +39 -39
- package/src/hub/project-facts.js +31 -31
- package/src/hub/runtime-feedback-reporter.js +55 -55
- package/src/ide/adapters/adapter-protocol.js +385 -385
- package/src/ide/adapters/claude-adapter.js +419 -419
- package/src/ide/adapters/codex-adapter.js +60 -60
- package/src/ide/adapters/cursor-adapter.js +484 -484
- package/src/ide/adapters/index.js +24 -24
- package/src/ide/anchors/markdown-anchor-writer.js +152 -152
- package/src/ide/ide-service.js +270 -270
- package/src/ide/ide-types.js +94 -94
- package/src/ide/links/link-mode-resolver.js +160 -160
- package/src/ide/registry/ide-registry-builder.js +165 -165
- package/src/incident/incident-writer.js +47 -47
- package/src/incident/types.js +22 -22
- package/src/init/ide-linker.js +126 -126
- package/src/init/ide-pointer-injector.js +75 -75
- package/src/init/init-applier.js +197 -197
- package/src/init/init-plan.js +294 -294
- package/src/init/init-service.js +65 -65
- package/src/init/manifest-installer.js +302 -302
- package/src/init/types.js +26 -26
- package/src/project/config-writer.js +83 -83
- package/src/project/context-index-writer.js +82 -82
- package/src/project/json-utils.js +72 -72
- package/src/project/local-state-writer.js +50 -50
- package/src/project/lock-file-writer.js +98 -98
- package/src/project/manifest-writer.js +126 -126
- package/src/project/policy-config-writer.js +91 -91
- package/src/project/project-config-writer.js +74 -74
- package/src/project/project-files.js +39 -39
- package/src/project/registry-index-writer.js +43 -43
- package/src/project/workspace-config-writer.js +63 -63
- package/src/run/index.js +11 -11
- package/src/run/run-id.js +32 -32
- package/src/run/run-service.js +269 -269
- package/src/run/run-store.js +80 -80
- package/src/scanner/aggregator/detection-aggregator.js +23 -23
- package/src/scanner/boundary/boundary-resolver.js +229 -229
- package/src/scanner/detectors/detector-registry.js +44 -44
- package/src/scanner/detectors/fastapi-detector.js +46 -46
- package/src/scanner/detectors/go-detector.js +46 -46
- package/src/scanner/detectors/nestjs-detector.js +57 -57
- package/src/scanner/detectors/nextjs-detector.js +52 -52
- package/src/scanner/detectors/react-vite-detector.js +52 -52
- package/src/scanner/detectors/react-webpack-detector.js +57 -57
- package/src/scanner/detectors/springboot-detector.js +46 -46
- package/src/scanner/detectors/springcloud-detector.js +46 -46
- package/src/scanner/detectors/springmvc-detector.js +46 -46
- package/src/scanner/detectors/vue-vite-detector.js +52 -52
- package/src/scanner/engine.js +72 -72
- package/src/scanner/facts/fact-extractor.js +211 -211
- package/src/scanner/types.js +30 -30
- package/src/security/asset-tamper-checker.js +188 -188
- package/src/security/checksum.js +40 -40
- package/src/spec/spec-writer.js +302 -302
- package/src/state-machine/circuit-breaker.js +112 -112
- package/src/state-machine/escape-hatch.js +49 -49
- package/src/state-machine/stage-runner.js +281 -281
- package/src/state-machine/state-machine.js +24 -24
- package/src/state-machine/transition-guard.js +36 -36
- package/src/state-machine/types.js +37 -37
- package/src/sync/sync-service.js +192 -192
- package/src/visual/agent-visual.js +142 -142
- package/src/visual/event-gateway.js +357 -357
- package/src/visual/event-mapper.js +128 -128
- package/src/visual/hook-dashboard.js +216 -216
- package/src/visual/index.js +27 -27
- package/src/visual/metrics.js +287 -287
- package/src/visual/privacy-filter.js +100 -100
- package/src/visual/risk-board.js +252 -252
- package/src/visual/timeline.js +245 -245
- package/src/visual/visual-client.js +94 -94
- package/src/visual/visual-config.js +40 -40
- package/src/visual/visual-reporter.js +88 -88
|
@@ -1,344 +1,344 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Reactivity Core Patterns (ref, reactive, shallowRef, computed, watch)
|
|
3
|
-
impact: MEDIUM
|
|
4
|
-
impactDescription: Clear reactivity choices keep state predictable and reduce unnecessary updates in Vue 3 apps
|
|
5
|
-
type: efficiency
|
|
6
|
-
tags: [vue3, reactivity, ref, reactive, shallowRef, computed, watch, watchEffect, external-state, best-practice]
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Reactivity Core Patterns (ref, reactive, shallowRef, computed, watch)
|
|
10
|
-
|
|
11
|
-
**Impact: MEDIUM** - Choose the right reactive primitive first, derive with `computed`, and use watchers only for side effects.
|
|
12
|
-
|
|
13
|
-
This reference covers the core reactivity decisions for local state, external data, derived values, and effects.
|
|
14
|
-
|
|
15
|
-
## Task List
|
|
16
|
-
|
|
17
|
-
- Declare reactive state correctly
|
|
18
|
-
- Always use `shallowRef()` instead of `ref()` for primitive values
|
|
19
|
-
- Choose the correct reactive declaration method for objects/arrays/map/set
|
|
20
|
-
- Follow best practices for `reactive`
|
|
21
|
-
- Avoid destructuring from `reactive()` directly
|
|
22
|
-
- Watch correctly for `reactive`
|
|
23
|
-
- Follow best practices for `computed`
|
|
24
|
-
- Prefer `computed` over watcher-assigned derived refs
|
|
25
|
-
- Keep filtered/sorted derivations out of templates
|
|
26
|
-
- Use `computed` for reusable class/style logic
|
|
27
|
-
- Keep computed getters pure (no side effects) and put side effects in watchers
|
|
28
|
-
- Follow best practices for watchers
|
|
29
|
-
- Use `immediate: true` instead of duplicate initial calls
|
|
30
|
-
- Clean up async effects for watchers
|
|
31
|
-
|
|
32
|
-
## Declare reactive state correctly
|
|
33
|
-
|
|
34
|
-
### Always use `shallowRef()` instead of `ref()` for primitive values (string, number, boolean, null, etc.) for better performance.
|
|
35
|
-
|
|
36
|
-
**Incorrect:**
|
|
37
|
-
```ts
|
|
38
|
-
import { ref } from 'vue'
|
|
39
|
-
const count = ref(0)
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
**Correct:**
|
|
43
|
-
```ts
|
|
44
|
-
import { shallowRef } from 'vue'
|
|
45
|
-
const count = shallowRef(0)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Choose the correct reactive declaration method for objects/arrays/map/set
|
|
49
|
-
|
|
50
|
-
Use `ref()` when you often **replace the entire value** (`state.value = newObj`) and still want deep reactivity inside it, usually used for:
|
|
51
|
-
|
|
52
|
-
- Frequently reassigned state (replace fetched object/list, reset to defaults, switch presets).
|
|
53
|
-
- Composable return values where updates happen mostly via `.value` reassignment.
|
|
54
|
-
|
|
55
|
-
Use `reactive()` when you mainly **mutate properties** and full replacement is uncommon, usually used for:
|
|
56
|
-
|
|
57
|
-
- “Single state object” patterns (stores/forms): `state.count++`, `state.items.push(...)`, `state.user.name = ...`.
|
|
58
|
-
- Situations where you want to avoid `.value` and update nested fields in place.
|
|
59
|
-
|
|
60
|
-
```ts
|
|
61
|
-
import { reactive } from 'vue'
|
|
62
|
-
|
|
63
|
-
const state = reactive({
|
|
64
|
-
count: 0,
|
|
65
|
-
user: { name: 'Alice', age: 30 }
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
state.count++ // ✅ reactive
|
|
69
|
-
state.user.age = 31 // ✅ reactive
|
|
70
|
-
// ❌ avoid replacing the reactive object reference:
|
|
71
|
-
// state = reactive({ count: 1 })
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Use `shallowRef()` when the value is **opaque / should not be proxied** (class instances, external library objects, very large nested data) and you only want updates to trigger when you **replace** `state.value` (no deep tracking), usually used for:
|
|
75
|
-
|
|
76
|
-
- Storing external instances/handles (SDK clients, class instances) without Vue proxying internals.
|
|
77
|
-
- Large data where you update by replacing the root reference (immutable-style updates).
|
|
78
|
-
|
|
79
|
-
```ts
|
|
80
|
-
import { shallowRef } from 'vue'
|
|
81
|
-
|
|
82
|
-
const user = shallowRef({ name: 'Alice', age: 30 })
|
|
83
|
-
|
|
84
|
-
user.value.age = 31 // ❌ not reactive
|
|
85
|
-
user.value = { name: 'Bob', age: 25 } // ✅ triggers update
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Use `shallowReactive()` when you want **only top-level properties** reactive; nested objects remain raw, usually used for:
|
|
89
|
-
|
|
90
|
-
- Container objects where only top-level keys change and nested payloads should stay unmanaged/unproxied.
|
|
91
|
-
- Mixed structures where Vue tracks the wrapper object, but not deeply nested or foreign objects.
|
|
92
|
-
|
|
93
|
-
```ts
|
|
94
|
-
import { shallowReactive } from 'vue'
|
|
95
|
-
|
|
96
|
-
const state = shallowReactive({
|
|
97
|
-
count: 0,
|
|
98
|
-
user: { name: 'Alice', age: 30 }
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
state.count++ // ✅ reactive
|
|
102
|
-
state.user.age = 31 // ❌ not reactive
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Best practices for `reactive`
|
|
106
|
-
|
|
107
|
-
### Avoid destructuring from `reactive()` directly
|
|
108
|
-
|
|
109
|
-
**BAD:**
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
import { reactive } from 'vue'
|
|
113
|
-
|
|
114
|
-
const state = reactive({ count: 0 })
|
|
115
|
-
const { count } = state // ❌ disconnected from reactivity
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Watch correctly for reactive
|
|
119
|
-
|
|
120
|
-
**BAD:**
|
|
121
|
-
|
|
122
|
-
passing a non-getter value into `watch()`
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
import { reactive, watch } from 'vue'
|
|
126
|
-
|
|
127
|
-
const state = reactive({ count: 0 })
|
|
128
|
-
|
|
129
|
-
// ❌ watch expects a getter, ref, reactive object, or array of these
|
|
130
|
-
watch(state.count, () => { /* ... */ })
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
**GOOD:**
|
|
134
|
-
|
|
135
|
-
preserve reactivity with `toRefs()` and use a getter for `watch()`
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
import { reactive, toRefs, watch } from 'vue'
|
|
139
|
-
|
|
140
|
-
const state = reactive({ count: 0 })
|
|
141
|
-
const { count } = toRefs(state) // ✅ count is a ref
|
|
142
|
-
|
|
143
|
-
watch(count, () => { /* ... */ }) // ✅
|
|
144
|
-
watch(() => state.count, () => { /* ... */ }) // ✅
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Best practices for `computed`
|
|
148
|
-
|
|
149
|
-
### Prefer `computed` over watcher-assigned derived refs
|
|
150
|
-
|
|
151
|
-
**BAD:**
|
|
152
|
-
```ts
|
|
153
|
-
import { ref, watchEffect } from 'vue'
|
|
154
|
-
|
|
155
|
-
const items = ref([{ price: 10 }, { price: 20 }])
|
|
156
|
-
const total = ref(0)
|
|
157
|
-
|
|
158
|
-
watchEffect(() => {
|
|
159
|
-
total.value = items.value.reduce((sum, item) => sum + item.price, 0)
|
|
160
|
-
})
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**GOOD:**
|
|
164
|
-
```ts
|
|
165
|
-
import { ref, computed } from 'vue'
|
|
166
|
-
|
|
167
|
-
const items = ref([{ price: 10 }, { price: 20 }])
|
|
168
|
-
const total = computed(() =>
|
|
169
|
-
items.value.reduce((sum, item) => sum + item.price, 0)
|
|
170
|
-
)
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Keep filtered/sorted derivations out of templates
|
|
174
|
-
|
|
175
|
-
**BAD:**
|
|
176
|
-
```vue
|
|
177
|
-
<template>
|
|
178
|
-
<li v-for="item in items.filter(item => item.active)" :key="item.id">
|
|
179
|
-
{{ item.name }}
|
|
180
|
-
</li>
|
|
181
|
-
|
|
182
|
-
<li v-for="item in getSortedItems()" :key="item.id">
|
|
183
|
-
{{ item.name }}
|
|
184
|
-
</li>
|
|
185
|
-
</template>
|
|
186
|
-
|
|
187
|
-
<script setup>
|
|
188
|
-
import { ref } from 'vue'
|
|
189
|
-
|
|
190
|
-
const items = ref([
|
|
191
|
-
{ id: 1, name: 'B', active: true },
|
|
192
|
-
{ id: 2, name: 'A', active: false }
|
|
193
|
-
])
|
|
194
|
-
|
|
195
|
-
function getSortedItems() {
|
|
196
|
-
return [...items.value].sort((a, b) => a.name.localeCompare(b.name))
|
|
197
|
-
}
|
|
198
|
-
</script>
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**GOOD:**
|
|
202
|
-
```vue
|
|
203
|
-
<script setup>
|
|
204
|
-
import { ref, computed } from 'vue'
|
|
205
|
-
|
|
206
|
-
const items = ref([
|
|
207
|
-
{ id: 1, name: 'B', active: true },
|
|
208
|
-
{ id: 2, name: 'A', active: false }
|
|
209
|
-
])
|
|
210
|
-
|
|
211
|
-
const visibleItems = computed(() =>
|
|
212
|
-
items.value
|
|
213
|
-
.filter(item => item.active)
|
|
214
|
-
.sort((a, b) => a.name.localeCompare(b.name))
|
|
215
|
-
)
|
|
216
|
-
</script>
|
|
217
|
-
|
|
218
|
-
<template>
|
|
219
|
-
<li v-for="item in visibleItems" :key="item.id">
|
|
220
|
-
{{ item.name }}
|
|
221
|
-
</li>
|
|
222
|
-
</template>
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### Use `computed` for reusable class/style logic
|
|
226
|
-
|
|
227
|
-
**BAD:**
|
|
228
|
-
```vue
|
|
229
|
-
<template>
|
|
230
|
-
<button :class="{ btn: true, 'btn-primary': type === 'primary' && !disabled, 'btn-disabled': disabled }">
|
|
231
|
-
{{ label }}
|
|
232
|
-
</button>
|
|
233
|
-
</template>
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**GOOD:**
|
|
237
|
-
```vue
|
|
238
|
-
<script setup>
|
|
239
|
-
import { computed } from 'vue'
|
|
240
|
-
|
|
241
|
-
const props = defineProps({
|
|
242
|
-
type: { type: String, default: 'primary' },
|
|
243
|
-
disabled: Boolean,
|
|
244
|
-
label: String
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
const buttonClasses = computed(() => ({
|
|
248
|
-
btn: true,
|
|
249
|
-
[`btn-${props.type}`]: !props.disabled,
|
|
250
|
-
'btn-disabled': props.disabled
|
|
251
|
-
}))
|
|
252
|
-
</script>
|
|
253
|
-
|
|
254
|
-
<template>
|
|
255
|
-
<button :class="buttonClasses">
|
|
256
|
-
{{ label }}
|
|
257
|
-
</button>
|
|
258
|
-
</template>
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### Keep computed getters pure (no side effects) and put side effects in watchers instead
|
|
262
|
-
|
|
263
|
-
A computed getter should only derive a value. No mutation, no API calls, no storage writes, no event emits.
|
|
264
|
-
([Reference](https://vuejs.org/guide/essentials/computed.html#best-practices))
|
|
265
|
-
|
|
266
|
-
**BAD:**
|
|
267
|
-
|
|
268
|
-
side effects inside computed
|
|
269
|
-
|
|
270
|
-
```ts
|
|
271
|
-
const count = ref(0)
|
|
272
|
-
|
|
273
|
-
const doubled = computed(() => {
|
|
274
|
-
// ❌ side effect
|
|
275
|
-
if (count.value > 10) console.warn('Too big!')
|
|
276
|
-
return count.value * 2
|
|
277
|
-
})
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
**GOOD:**
|
|
281
|
-
|
|
282
|
-
pure computed + `watch()` for side effects
|
|
283
|
-
|
|
284
|
-
```ts
|
|
285
|
-
const count = ref(0)
|
|
286
|
-
const doubled = computed(() => count.value * 2)
|
|
287
|
-
|
|
288
|
-
watch(count, (value) => {
|
|
289
|
-
if (value > 10) console.warn('Too big!')
|
|
290
|
-
})
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Best practices for watchers
|
|
294
|
-
|
|
295
|
-
### Use `immediate: true` instead of duplicate initial calls
|
|
296
|
-
|
|
297
|
-
**BAD:**
|
|
298
|
-
```ts
|
|
299
|
-
import { ref, watch, onMounted } from 'vue'
|
|
300
|
-
|
|
301
|
-
const userId = ref(1)
|
|
302
|
-
|
|
303
|
-
function loadUser(id) {
|
|
304
|
-
// ...
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
onMounted(() => loadUser(userId.value))
|
|
308
|
-
watch(userId, (id) => loadUser(id))
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
**GOOD:**
|
|
312
|
-
```ts
|
|
313
|
-
import { ref, watch } from 'vue'
|
|
314
|
-
|
|
315
|
-
const userId = ref(1)
|
|
316
|
-
|
|
317
|
-
watch(
|
|
318
|
-
userId,
|
|
319
|
-
(id) => loadUser(id),
|
|
320
|
-
{ immediate: true }
|
|
321
|
-
)
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### Clean up async effects for watchers
|
|
325
|
-
|
|
326
|
-
When reacting to rapid changes (search boxes, filters), cancel the previous request.
|
|
327
|
-
|
|
328
|
-
**GOOD:**
|
|
329
|
-
|
|
330
|
-
```ts
|
|
331
|
-
const query = ref('')
|
|
332
|
-
const results = ref<string[]>([])
|
|
333
|
-
|
|
334
|
-
watch(query, async (q, _prev, onCleanup) => {
|
|
335
|
-
const controller = new AbortController()
|
|
336
|
-
onCleanup(() => controller.abort())
|
|
337
|
-
|
|
338
|
-
const res = await fetch(`/api/search?q=${encodeURIComponent(q)}`, {
|
|
339
|
-
signal: controller.signal,
|
|
340
|
-
})
|
|
341
|
-
|
|
342
|
-
results.value = await res.json()
|
|
343
|
-
})
|
|
344
|
-
```
|
|
1
|
+
---
|
|
2
|
+
title: Reactivity Core Patterns (ref, reactive, shallowRef, computed, watch)
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Clear reactivity choices keep state predictable and reduce unnecessary updates in Vue 3 apps
|
|
5
|
+
type: efficiency
|
|
6
|
+
tags: [vue3, reactivity, ref, reactive, shallowRef, computed, watch, watchEffect, external-state, best-practice]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Reactivity Core Patterns (ref, reactive, shallowRef, computed, watch)
|
|
10
|
+
|
|
11
|
+
**Impact: MEDIUM** - Choose the right reactive primitive first, derive with `computed`, and use watchers only for side effects.
|
|
12
|
+
|
|
13
|
+
This reference covers the core reactivity decisions for local state, external data, derived values, and effects.
|
|
14
|
+
|
|
15
|
+
## Task List
|
|
16
|
+
|
|
17
|
+
- Declare reactive state correctly
|
|
18
|
+
- Always use `shallowRef()` instead of `ref()` for primitive values
|
|
19
|
+
- Choose the correct reactive declaration method for objects/arrays/map/set
|
|
20
|
+
- Follow best practices for `reactive`
|
|
21
|
+
- Avoid destructuring from `reactive()` directly
|
|
22
|
+
- Watch correctly for `reactive`
|
|
23
|
+
- Follow best practices for `computed`
|
|
24
|
+
- Prefer `computed` over watcher-assigned derived refs
|
|
25
|
+
- Keep filtered/sorted derivations out of templates
|
|
26
|
+
- Use `computed` for reusable class/style logic
|
|
27
|
+
- Keep computed getters pure (no side effects) and put side effects in watchers
|
|
28
|
+
- Follow best practices for watchers
|
|
29
|
+
- Use `immediate: true` instead of duplicate initial calls
|
|
30
|
+
- Clean up async effects for watchers
|
|
31
|
+
|
|
32
|
+
## Declare reactive state correctly
|
|
33
|
+
|
|
34
|
+
### Always use `shallowRef()` instead of `ref()` for primitive values (string, number, boolean, null, etc.) for better performance.
|
|
35
|
+
|
|
36
|
+
**Incorrect:**
|
|
37
|
+
```ts
|
|
38
|
+
import { ref } from 'vue'
|
|
39
|
+
const count = ref(0)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Correct:**
|
|
43
|
+
```ts
|
|
44
|
+
import { shallowRef } from 'vue'
|
|
45
|
+
const count = shallowRef(0)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Choose the correct reactive declaration method for objects/arrays/map/set
|
|
49
|
+
|
|
50
|
+
Use `ref()` when you often **replace the entire value** (`state.value = newObj`) and still want deep reactivity inside it, usually used for:
|
|
51
|
+
|
|
52
|
+
- Frequently reassigned state (replace fetched object/list, reset to defaults, switch presets).
|
|
53
|
+
- Composable return values where updates happen mostly via `.value` reassignment.
|
|
54
|
+
|
|
55
|
+
Use `reactive()` when you mainly **mutate properties** and full replacement is uncommon, usually used for:
|
|
56
|
+
|
|
57
|
+
- “Single state object” patterns (stores/forms): `state.count++`, `state.items.push(...)`, `state.user.name = ...`.
|
|
58
|
+
- Situations where you want to avoid `.value` and update nested fields in place.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { reactive } from 'vue'
|
|
62
|
+
|
|
63
|
+
const state = reactive({
|
|
64
|
+
count: 0,
|
|
65
|
+
user: { name: 'Alice', age: 30 }
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
state.count++ // ✅ reactive
|
|
69
|
+
state.user.age = 31 // ✅ reactive
|
|
70
|
+
// ❌ avoid replacing the reactive object reference:
|
|
71
|
+
// state = reactive({ count: 1 })
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Use `shallowRef()` when the value is **opaque / should not be proxied** (class instances, external library objects, very large nested data) and you only want updates to trigger when you **replace** `state.value` (no deep tracking), usually used for:
|
|
75
|
+
|
|
76
|
+
- Storing external instances/handles (SDK clients, class instances) without Vue proxying internals.
|
|
77
|
+
- Large data where you update by replacing the root reference (immutable-style updates).
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { shallowRef } from 'vue'
|
|
81
|
+
|
|
82
|
+
const user = shallowRef({ name: 'Alice', age: 30 })
|
|
83
|
+
|
|
84
|
+
user.value.age = 31 // ❌ not reactive
|
|
85
|
+
user.value = { name: 'Bob', age: 25 } // ✅ triggers update
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use `shallowReactive()` when you want **only top-level properties** reactive; nested objects remain raw, usually used for:
|
|
89
|
+
|
|
90
|
+
- Container objects where only top-level keys change and nested payloads should stay unmanaged/unproxied.
|
|
91
|
+
- Mixed structures where Vue tracks the wrapper object, but not deeply nested or foreign objects.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { shallowReactive } from 'vue'
|
|
95
|
+
|
|
96
|
+
const state = shallowReactive({
|
|
97
|
+
count: 0,
|
|
98
|
+
user: { name: 'Alice', age: 30 }
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
state.count++ // ✅ reactive
|
|
102
|
+
state.user.age = 31 // ❌ not reactive
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Best practices for `reactive`
|
|
106
|
+
|
|
107
|
+
### Avoid destructuring from `reactive()` directly
|
|
108
|
+
|
|
109
|
+
**BAD:**
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { reactive } from 'vue'
|
|
113
|
+
|
|
114
|
+
const state = reactive({ count: 0 })
|
|
115
|
+
const { count } = state // ❌ disconnected from reactivity
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Watch correctly for reactive
|
|
119
|
+
|
|
120
|
+
**BAD:**
|
|
121
|
+
|
|
122
|
+
passing a non-getter value into `watch()`
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { reactive, watch } from 'vue'
|
|
126
|
+
|
|
127
|
+
const state = reactive({ count: 0 })
|
|
128
|
+
|
|
129
|
+
// ❌ watch expects a getter, ref, reactive object, or array of these
|
|
130
|
+
watch(state.count, () => { /* ... */ })
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**GOOD:**
|
|
134
|
+
|
|
135
|
+
preserve reactivity with `toRefs()` and use a getter for `watch()`
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { reactive, toRefs, watch } from 'vue'
|
|
139
|
+
|
|
140
|
+
const state = reactive({ count: 0 })
|
|
141
|
+
const { count } = toRefs(state) // ✅ count is a ref
|
|
142
|
+
|
|
143
|
+
watch(count, () => { /* ... */ }) // ✅
|
|
144
|
+
watch(() => state.count, () => { /* ... */ }) // ✅
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Best practices for `computed`
|
|
148
|
+
|
|
149
|
+
### Prefer `computed` over watcher-assigned derived refs
|
|
150
|
+
|
|
151
|
+
**BAD:**
|
|
152
|
+
```ts
|
|
153
|
+
import { ref, watchEffect } from 'vue'
|
|
154
|
+
|
|
155
|
+
const items = ref([{ price: 10 }, { price: 20 }])
|
|
156
|
+
const total = ref(0)
|
|
157
|
+
|
|
158
|
+
watchEffect(() => {
|
|
159
|
+
total.value = items.value.reduce((sum, item) => sum + item.price, 0)
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**GOOD:**
|
|
164
|
+
```ts
|
|
165
|
+
import { ref, computed } from 'vue'
|
|
166
|
+
|
|
167
|
+
const items = ref([{ price: 10 }, { price: 20 }])
|
|
168
|
+
const total = computed(() =>
|
|
169
|
+
items.value.reduce((sum, item) => sum + item.price, 0)
|
|
170
|
+
)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Keep filtered/sorted derivations out of templates
|
|
174
|
+
|
|
175
|
+
**BAD:**
|
|
176
|
+
```vue
|
|
177
|
+
<template>
|
|
178
|
+
<li v-for="item in items.filter(item => item.active)" :key="item.id">
|
|
179
|
+
{{ item.name }}
|
|
180
|
+
</li>
|
|
181
|
+
|
|
182
|
+
<li v-for="item in getSortedItems()" :key="item.id">
|
|
183
|
+
{{ item.name }}
|
|
184
|
+
</li>
|
|
185
|
+
</template>
|
|
186
|
+
|
|
187
|
+
<script setup>
|
|
188
|
+
import { ref } from 'vue'
|
|
189
|
+
|
|
190
|
+
const items = ref([
|
|
191
|
+
{ id: 1, name: 'B', active: true },
|
|
192
|
+
{ id: 2, name: 'A', active: false }
|
|
193
|
+
])
|
|
194
|
+
|
|
195
|
+
function getSortedItems() {
|
|
196
|
+
return [...items.value].sort((a, b) => a.name.localeCompare(b.name))
|
|
197
|
+
}
|
|
198
|
+
</script>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**GOOD:**
|
|
202
|
+
```vue
|
|
203
|
+
<script setup>
|
|
204
|
+
import { ref, computed } from 'vue'
|
|
205
|
+
|
|
206
|
+
const items = ref([
|
|
207
|
+
{ id: 1, name: 'B', active: true },
|
|
208
|
+
{ id: 2, name: 'A', active: false }
|
|
209
|
+
])
|
|
210
|
+
|
|
211
|
+
const visibleItems = computed(() =>
|
|
212
|
+
items.value
|
|
213
|
+
.filter(item => item.active)
|
|
214
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
215
|
+
)
|
|
216
|
+
</script>
|
|
217
|
+
|
|
218
|
+
<template>
|
|
219
|
+
<li v-for="item in visibleItems" :key="item.id">
|
|
220
|
+
{{ item.name }}
|
|
221
|
+
</li>
|
|
222
|
+
</template>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Use `computed` for reusable class/style logic
|
|
226
|
+
|
|
227
|
+
**BAD:**
|
|
228
|
+
```vue
|
|
229
|
+
<template>
|
|
230
|
+
<button :class="{ btn: true, 'btn-primary': type === 'primary' && !disabled, 'btn-disabled': disabled }">
|
|
231
|
+
{{ label }}
|
|
232
|
+
</button>
|
|
233
|
+
</template>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**GOOD:**
|
|
237
|
+
```vue
|
|
238
|
+
<script setup>
|
|
239
|
+
import { computed } from 'vue'
|
|
240
|
+
|
|
241
|
+
const props = defineProps({
|
|
242
|
+
type: { type: String, default: 'primary' },
|
|
243
|
+
disabled: Boolean,
|
|
244
|
+
label: String
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
const buttonClasses = computed(() => ({
|
|
248
|
+
btn: true,
|
|
249
|
+
[`btn-${props.type}`]: !props.disabled,
|
|
250
|
+
'btn-disabled': props.disabled
|
|
251
|
+
}))
|
|
252
|
+
</script>
|
|
253
|
+
|
|
254
|
+
<template>
|
|
255
|
+
<button :class="buttonClasses">
|
|
256
|
+
{{ label }}
|
|
257
|
+
</button>
|
|
258
|
+
</template>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Keep computed getters pure (no side effects) and put side effects in watchers instead
|
|
262
|
+
|
|
263
|
+
A computed getter should only derive a value. No mutation, no API calls, no storage writes, no event emits.
|
|
264
|
+
([Reference](https://vuejs.org/guide/essentials/computed.html#best-practices))
|
|
265
|
+
|
|
266
|
+
**BAD:**
|
|
267
|
+
|
|
268
|
+
side effects inside computed
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
const count = ref(0)
|
|
272
|
+
|
|
273
|
+
const doubled = computed(() => {
|
|
274
|
+
// ❌ side effect
|
|
275
|
+
if (count.value > 10) console.warn('Too big!')
|
|
276
|
+
return count.value * 2
|
|
277
|
+
})
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**GOOD:**
|
|
281
|
+
|
|
282
|
+
pure computed + `watch()` for side effects
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
const count = ref(0)
|
|
286
|
+
const doubled = computed(() => count.value * 2)
|
|
287
|
+
|
|
288
|
+
watch(count, (value) => {
|
|
289
|
+
if (value > 10) console.warn('Too big!')
|
|
290
|
+
})
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Best practices for watchers
|
|
294
|
+
|
|
295
|
+
### Use `immediate: true` instead of duplicate initial calls
|
|
296
|
+
|
|
297
|
+
**BAD:**
|
|
298
|
+
```ts
|
|
299
|
+
import { ref, watch, onMounted } from 'vue'
|
|
300
|
+
|
|
301
|
+
const userId = ref(1)
|
|
302
|
+
|
|
303
|
+
function loadUser(id) {
|
|
304
|
+
// ...
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
onMounted(() => loadUser(userId.value))
|
|
308
|
+
watch(userId, (id) => loadUser(id))
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**GOOD:**
|
|
312
|
+
```ts
|
|
313
|
+
import { ref, watch } from 'vue'
|
|
314
|
+
|
|
315
|
+
const userId = ref(1)
|
|
316
|
+
|
|
317
|
+
watch(
|
|
318
|
+
userId,
|
|
319
|
+
(id) => loadUser(id),
|
|
320
|
+
{ immediate: true }
|
|
321
|
+
)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Clean up async effects for watchers
|
|
325
|
+
|
|
326
|
+
When reacting to rapid changes (search boxes, filters), cancel the previous request.
|
|
327
|
+
|
|
328
|
+
**GOOD:**
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
const query = ref('')
|
|
332
|
+
const results = ref<string[]>([])
|
|
333
|
+
|
|
334
|
+
watch(query, async (q, _prev, onCleanup) => {
|
|
335
|
+
const controller = new AbortController()
|
|
336
|
+
onCleanup(() => controller.abort())
|
|
337
|
+
|
|
338
|
+
const res = await fetch(`/api/search?q=${encodeURIComponent(q)}`, {
|
|
339
|
+
signal: controller.signal,
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
results.value = await res.json()
|
|
343
|
+
})
|
|
344
|
+
```
|