@bovinphang/frontend-craft 2.6.0 → 2.7.0

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.
Files changed (110) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +38 -1
  4. package/CHANGELOG.zh-CN.md +37 -1
  5. package/README.md +10 -6
  6. package/README.openclaw.md +3 -1
  7. package/README.openclaw.zh-CN.md +3 -1
  8. package/README.zh-CN.md +10 -6
  9. package/agents/fec-typescript-reviewer.md +1 -1
  10. package/docs/example-prompts.md +81 -69
  11. package/docs/ja-JP/README.md +56 -52
  12. package/docs/ko-KR/README.md +45 -41
  13. package/docs/project-structure.md +8 -4
  14. package/docs/superpowers/plans/2026-05-29-fec-debug.md +491 -0
  15. package/docs/superpowers/specs/2026-05-29-fec-debug-design.md +340 -0
  16. package/docs/zh-CN/example-prompts.md +81 -69
  17. package/docs/zh-CN/project-structure.md +8 -4
  18. package/docs/zh-TW/README.md +33 -29
  19. package/openclaw.plugin.json +1 -1
  20. package/package.json +3 -3
  21. package/skills/eval_queries.json +154 -56
  22. package/skills/fec-backend-requirements-handoff/SKILL.md +45 -0
  23. package/skills/fec-code-review/SKILL.md +1 -1
  24. package/skills/fec-drawio-studio/SKILL.md +69 -0
  25. package/skills/fec-drawio-studio/data/THIRD_PARTY_NOTICES.md +10 -0
  26. package/skills/fec-drawio-studio/data/brand-icons.json +878 -0
  27. package/skills/fec-drawio-studio/data/shape-index.json.gz +0 -0
  28. package/skills/fec-drawio-studio/references/data-residency.md +27 -0
  29. package/skills/fec-drawio-studio/references/diagram-patterns.md +41 -0
  30. package/skills/fec-drawio-studio/references/layout-and-export.md +57 -0
  31. package/skills/fec-drawio-studio/references/troubleshooting.md +29 -0
  32. package/skills/fec-drawio-studio/references/xml-and-mermaid.md +54 -0
  33. package/skills/fec-drawio-studio/scripts/brand-symbols.mjs +99 -0
  34. package/skills/fec-drawio-studio/scripts/diagram-lint.mjs +143 -0
  35. package/skills/fec-drawio-studio/scripts/diagram-url.mjs +102 -0
  36. package/skills/fec-drawio-studio/scripts/layout-graph.mjs +107 -0
  37. package/skills/fec-drawio-studio/scripts/png-embed-fix.mjs +26 -0
  38. package/skills/fec-drawio-studio/scripts/scan-go-packages.mjs +36 -0
  39. package/skills/fec-drawio-studio/scripts/scan-js-modules.mjs +52 -0
  40. package/skills/fec-drawio-studio/scripts/scan-python-classes.mjs +30 -0
  41. package/skills/fec-drawio-studio/scripts/scan-python-modules.mjs +55 -0
  42. package/skills/fec-drawio-studio/scripts/scan-rust-modules.mjs +35 -0
  43. package/skills/fec-drawio-studio/scripts/scan-ts-modules.mjs +7 -0
  44. package/skills/fec-drawio-studio/scripts/shape-query.mjs +81 -0
  45. package/skills/fec-drawio-studio/scripts/studio-core.mjs +139 -0
  46. package/skills/fec-drawio-studio/styles/built-in/corporate.json +49 -0
  47. package/skills/fec-drawio-studio/styles/built-in/default.json +49 -0
  48. package/skills/fec-drawio-studio/styles/built-in/handdrawn.json +49 -0
  49. package/skills/fec-drawio-studio/styles/schema.json +112 -0
  50. package/skills/fec-e2e-testing/SKILL.md +3 -1
  51. package/skills/fec-e2e-testing/references/e2e-ci-reporting.md +62 -0
  52. package/skills/fec-e2e-testing/references/e2e-special-scenarios.md +52 -0
  53. package/skills/fec-e2e-testing/references/e2e-visual-regression.md +60 -0
  54. package/skills/fec-image-generation/SKILL.md +56 -0
  55. package/skills/fec-image-generation/references/artifact-routing.md +80 -0
  56. package/skills/fec-image-generation/references/diagram-workflows.md +43 -0
  57. package/skills/fec-image-generation/references/png-qa-autofix.md +30 -0
  58. package/skills/fec-image-generation/scripts/png-qa.mjs +431 -0
  59. package/skills/fec-implement-from-design/SKILL.md +7 -0
  60. package/skills/fec-legacy-to-modern-migration/SKILL.md +24 -168
  61. package/skills/fec-legacy-to-modern-migration/references/migration-execution-checklist.md +110 -0
  62. package/skills/fec-legacy-to-modern-migration/references/migration-strategy-and-mapping.md +48 -0
  63. package/skills/fec-motion-interaction/SKILL.md +7 -0
  64. package/skills/fec-nextjs-project-standard/SKILL.md +7 -1
  65. package/skills/fec-performance-optimization/SKILL.md +5 -1
  66. package/skills/fec-performance-optimization/references/framework-performance-patterns.md +38 -0
  67. package/skills/fec-performance-optimization/references/report-template.md +6 -0
  68. package/skills/fec-react-project-standard/SKILL.md +11 -3
  69. package/skills/fec-react-project-standard/references/react-performance-patterns.md +35 -0
  70. package/skills/fec-react-project-standard/references/react-project-structure.md +197 -0
  71. package/skills/fec-react-project-standard/references/react-quality-patterns.md +131 -0
  72. package/skills/fec-react-project-standard/references/react-runtime-patterns.md +293 -0
  73. package/skills/fec-responsive-layout/references/responsive-layout-patterns.md +11 -0
  74. package/skills/fec-source-driven-development/SKILL.md +26 -0
  75. package/skills/fec-tailwind-design-system/references/tailwind-system-patterns.md +5 -1
  76. package/skills/fec-typescript-project-standard/SKILL.md +54 -0
  77. package/skills/{fec-typescript-type-safety → fec-typescript-project-standard}/references/type-safety-patterns.md +1 -1
  78. package/skills/{fec-typescript-type-safety/SKILL.md → fec-typescript-project-standard/references/type-safety.md} +1 -10
  79. package/skills/fec-ui-design/SKILL.md +26 -8
  80. package/skills/fec-ui-design/data/style-archetypes.json +40 -0
  81. package/skills/fec-ui-design/data/ux-quality-rules.json +35 -0
  82. package/skills/fec-ui-design/references/design-intelligence.md +66 -6
  83. package/skills/fec-ui-design/references/pre-delivery-checklist.md +6 -0
  84. package/skills/fec-ui-design/scripts/design-system.mjs +119 -1
  85. package/skills/fec-vue3-project-standard/SKILL.md +11 -2
  86. package/skills/fec-vue3-project-standard/references/vue3-composables-routing.md +163 -0
  87. package/skills/fec-vue3-project-standard/references/vue3-performance-patterns.md +13 -0
  88. package/skills/fec-vue3-project-standard/references/vue3-project-structure.md +177 -0
  89. package/skills/fec-vue3-project-standard/references/vue3-state-api-quality.md +216 -0
  90. package/skills/fec-web-video-presentation/SKILL.md +61 -0
  91. package/skills/fec-web-video-presentation/data/starter-themes.json +59 -0
  92. package/skills/fec-web-video-presentation/references/chapter-craft.md +37 -0
  93. package/skills/fec-web-video-presentation/references/content-plan.md +38 -0
  94. package/skills/fec-web-video-presentation/references/recording-and-audio.md +33 -0
  95. package/skills/fec-web-video-presentation/references/theme-system.md +36 -0
  96. package/skills/fec-web-video-presentation/scripts/create-video-presentation.mjs +430 -0
  97. package/skills/metadata.json +340 -164
  98. package/skills/relations.json +116 -25
  99. package/templates/shared/rules/fec-ci-cd.md +20 -108
  100. package/templates/shared/rules/fec-design-system.md +47 -223
  101. package/templates/shared/rules/fec-error-handling.md +35 -179
  102. package/templates/shared/rules/fec-i18n.md +43 -91
  103. package/templates/shared/rules/fec-refactoring.md +4 -0
  104. package/templates/shared/rules/fec-rendering-patterns.md +28 -171
  105. package/templates/shared/rules/fec-responsive-design.md +34 -211
  106. package/templates/shared/rules/fec-state-management.md +41 -144
  107. package/templates/shared/rules/fec-typescript.md +47 -290
  108. package/skills/fec-e2e-testing/references/e2e-advanced.md +0 -176
  109. package/skills/fec-react-project-standard/references/react-project-details.md +0 -642
  110. package/skills/fec-vue3-project-standard/references/vue3-project-details.md +0 -547
@@ -1,227 +1,50 @@
1
1
  # 响应式设计规则
2
2
 
3
- 凡是任务涉及移动端适配、响应式布局、多端兼容时,都应用本文件。
3
+ 凡是任务涉及移动端适配、响应式布局、多端兼容、触摸目标或视口行为时,都应用本文件。本文只保留项目常驻约束;布局模式、container query、响应式表格、媒体和验证细节交给 `fec-responsive-layout`。
4
4
 
5
5
  ## 核心原则
6
6
 
7
- - **移动优先**: 从小屏幕开始设计,逐步增强到大屏幕
8
- - **内容优先**: 移动端优先展示核心内容,次要内容折叠或延后
9
- - **触摸友好**: 所有交互元素必须适配手指操作
10
- - **性能优先**: 移动端网络和设备性能较弱,需优化加载
11
- - **容器感知**: 可复用组件优先适配所在容器,而不是假设整页断点
12
- - **稳定尺寸**: 工具栏、表格列、棋盘、卡片网格和计数器需要稳定约束,避免状态变化导致布局跳动
7
+ - **移动优先**:从小屏幕开始设计,逐步增强到大屏幕。
8
+ - **内容优先**:小屏优先展示核心任务、关键操作和反馈,次要内容折叠、延后或进入详情层。
9
+ - **触摸友好**:所有交互元素必须适配手指操作,关键功能不能只依赖 hover。
10
+ - **性能优先**:移动端网络和设备性能较弱,首屏资源、图表、动效和大列表要克制。
11
+ - **容器感知**:可复用组件优先适配所在容器,而不是假设整页断点。
12
+ - **稳定尺寸**:工具栏、表格列、棋盘、卡片网格和计数器需要稳定约束,避免状态变化导致布局跳动。
13
13
 
14
- ## 断点策略
14
+ ## 断点与容器策略
15
15
 
16
- | 断点 | 宽度 | 设备 | Tailwind | 说明 |
17
- | ----------- | ------ | --------------- | -------- | -------------------- |
18
- | **Mobile** | 375px | 手机竖屏 | (默认) | 基础样式,无媒体查询 |
19
- | **Tablet** | 768px | 平板 / 手机横屏 | `md:` | 两列布局起点 |
20
- | **Desktop** | 1024px | 笔记本 | `lg:` | 完整布局 |
21
- | **Large** | 1280px | 桌面显示器 | `xl:` | 宽屏优化 |
22
- | **XLarge** | 1536px | 超宽屏 | `2xl:` | 最大内容宽度 |
16
+ - 默认验证 375px、768px、1024px、1440px,以及断点中间值。
17
+ - 使用 mobile-first `min-width` 断点;不要先写桌面样式再用 `max-width` 补移动端。
18
+ - Tailwind 前缀从小到大使用:默认 → `sm:` → `md:` → `lg:` → `xl:` → `2xl:`。
19
+ - 页面级结构可以使用断点;会被放进侧栏、弹窗、卡片或主内容区的复用组件优先使用 container query。
20
+ - grid/flex 子项包含长文本、图表、代码、媒体或表格时,必须考虑 `min-width: 0`、`minmax()`、`aspect-ratio` 和明确溢出策略。
23
21
 
24
- ### 移动优先 CSS
22
+ ## 触摸目标与移动端交互
25
23
 
26
- ```css
27
- /* 基础样式 — 移动端 */
28
- .container {
29
- padding: 16px;
30
- display: flex;
31
- flex-direction: column;
32
- gap: 12px;
33
- }
24
+ - 空间允许时,按钮、链接、关闭按钮等交互目标至少 44x44px;紧凑工具界面最低也要保证可操作。
25
+ - 输入框字号避免低于 16px,防止 iOS Safari 自动缩放。
26
+ - 固定底部栏、操作条、抽屉和对话框必须考虑 safe area 与虚拟键盘。
27
+ - hover-only 信息必须有点击、焦点或常驻可见替代方案。
28
+ - 横竖屏切换后,主操作、焦点位置、滚动容器和错误提示仍应可达。
34
29
 
35
- /* Tablet — 768px+ */
36
- @media (min-width: 768px) {
37
- .container {
38
- padding: 24px;
39
- flex-direction: row;
40
- gap: 24px;
41
- }
42
- }
30
+ ## 数据密集区域
43
31
 
44
- /* Desktop — 1024px+ */
45
- @media (min-width: 1024px) {
46
- .container {
47
- max-width: 960px;
48
- margin: 0 auto;
49
- padding: 32px;
50
- }
51
- }
52
- ```
32
+ - 表格、列表、看板、编辑器和画布可以局部横向滚动,但页面整体不应出现无意水平溢出。
33
+ - 移动端数据密集视图需先定义列优先级:主标识、状态和主操作优先保留;低优先级字段进入详情、展开行或抽屉。
34
+ - 小屏仍要保留排序、筛选、分页和选择能力。
35
+ - 虚拟滚动只解决 DOM 数量问题,不能替代信息层级设计。
53
36
 
54
- ### Tailwind 移动优先
37
+ ## 响应式媒体
55
38
 
56
- Tailwind 默认移动优先,无前缀类作用于所有屏幕,前缀仅覆盖更大断点:
57
-
58
- ```html
59
- <!-- 移动端: 单列, 小间距 | Tablet: 双列 | Desktop: 三列 -->
60
- <div
61
- class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 lg:gap-8"
62
- >
63
- <!-- 卡片: 移动端小字, Desktop 大字 -->
64
- <div class="p-4 md:p-6 text-sm md:text-base">...</div>
65
- </div>
66
-
67
- <!-- 导航: 移动端隐藏, Desktop 显示 -->
68
- <nav class="hidden md:flex">...</nav>
69
-
70
- <!-- 移动端汉堡菜单, Desktop 隐藏 -->
71
- <button class="md:hidden" aria-label="菜单">☰</button>
72
- ```
73
-
74
- **关键约定**:
75
-
76
- - 始终使用 `min-width` 媒体查询(mobile-first),不用 `max-width`
77
- - Tailwind 前缀从小到大:`sm:` → `md:` → `lg:` → `xl:`
78
- - 不要在桌面端写默认样式然后用 `max-width` 覆盖移动端
79
-
80
- ## 触摸目标
81
-
82
- | 元素 | 最小尺寸 | 说明 |
83
- | ----------- | --------- | --------------------------- |
84
- | 按钮 | 44×44px | WCAG 2.2 触摸目标要求 |
85
- | 链接 | 44×44px | 可通过 padding 扩大点击区域 |
86
- | 表单输入 | 44px 高度 | 避免 iOS 自动缩放 |
87
- | 复选框/单选 | 24×24px | 最小可见尺寸 |
88
- | 关闭按钮 | 44×44px | 模态框、Toast 的关闭按钮 |
89
-
90
- ```css
91
- /* 扩大点击区域(视觉尺寸不变) */
92
- .icon-button {
93
- width: 24px;
94
- height: 24px;
95
- padding: 10px; /* 实际点击区域 44×44 */
96
- }
97
-
98
- /* 表单输入 — 避免 iOS 缩放 */
99
- input,
100
- select,
101
- textarea {
102
- font-size: 16px; /* < 16px 时 iOS Safari 会自动缩放页面 */
103
- }
104
- ```
105
-
106
- ## 布局模式
107
-
108
- ### Container Query
109
-
110
- 当组件会出现在侧栏、弹窗、卡片和主内容区等不同容器时,优先使用容器查询:
111
-
112
- ```css
113
- .summary-panel {
114
- container-type: inline-size;
115
- }
116
-
117
- @container (min-width: 42rem) {
118
- .summary-panel__body {
119
- display: grid;
120
- grid-template-columns: 16rem minmax(0, 1fr);
121
- }
122
- }
123
- ```
124
-
125
- Flex/Grid 子项包含长文本、图表、代码或表格时,记得设置 `min-width: 0`。
126
-
127
- ### Stack → Row
128
-
129
- 移动端纵向堆叠,桌面端横向排列:
130
-
131
- ```html
132
- <div class="flex flex-col md:flex-row gap-4">
133
- <div class="flex-1">主内容</div>
134
- <div class="md:w-64 md:flex-shrink-0">侧边栏</div>
135
- </div>
136
- ```
137
-
138
- ### 响应式表格
139
-
140
- ```html
141
- <!-- 小屏横向滚动 -->
142
- <div class="overflow-x-auto">
143
- <table class="min-w-full">
144
- ...
145
- </table>
146
- </div>
147
-
148
- <!-- 或:移动端卡片式布局 -->
149
- <div class="hidden md:block">
150
- <table>
151
- ...
152
- </table>
153
- </div>
154
- <div class="md:hidden">
155
- <!-- 每行变为卡片 -->
156
- </div>
157
- ```
158
-
159
- 移动端数据密集视图需先定义列优先级:主标识、状态和主操作优先保留;低优先级字段进入详情、展开行或抽屉。
160
-
161
- ### 响应式图片
162
-
163
- ```html
164
- <!-- srcset 按设备像素比加载 -->
165
- <img
166
- src="/img/hero-800.jpg"
167
- srcset="
168
- /img/hero-400.jpg 400w,
169
- /img/hero-800.jpg 800w,
170
- /img/hero-1200.jpg 1200w
171
- "
172
- sizes="(max-width: 768px) 100vw, 800px"
173
- alt="描述"
174
- loading="lazy"
175
- />
176
-
177
- <!-- picture 元素按断点切换 -->
178
- <picture>
179
- <source
180
- media="(min-width: 1024px)"
181
- srcset="/img/hero-desktop.webp"
182
- type="image/webp"
183
- />
184
- <source
185
- media="(min-width: 768px)"
186
- srcset="/img/hero-tablet.webp"
187
- type="image/webp"
188
- />
189
- <img src="/img/hero-mobile.webp" alt="描述" loading="lazy" />
190
- </picture>
191
- ```
192
-
193
- ## 移动端交互注意
194
-
195
- - **悬停不可靠**: 移动端无 hover 状态,不要将关键功能隐藏在 hover 中(如 tooltip 改为点击触发)
196
- - **键盘弹出**: 移动端虚拟键盘会缩小可视区域,固定定位元素需注意位置调整
197
- - **滚动性能**: 使用 `-webkit-overflow-scrolling: touch`(iOS)或 `overscroll-behavior` 优化滚动体验
198
- - **安全区域**: 适配 iPhone 刘海/底部横条,使用 `env(safe-area-inset-*)`:
199
-
200
- ```css
201
- .app-content {
202
- padding-top: env(safe-area-inset-top);
203
- padding-bottom: env(safe-area-inset-bottom);
204
- padding-left: env(safe-area-inset-left);
205
- padding-right: env(safe-area-inset-right);
206
- }
207
- ```
208
-
209
- ## 测试策略
210
-
211
- - 使用 Chrome DevTools Device Mode 测试主流设备
212
- - 优先在真实设备上测试(iOS Safari / Android Chrome)
213
- - 测试方向切换(横屏 / 竖屏)
214
- - 测试不同网络条件(3G / 4G / 弱网)
215
- - 不要假设桌面端是"默认",移动端优先验证
39
+ - 图片和视频要有稳定尺寸、`aspect-ratio` 或容器约束,避免加载后推挤布局。
40
+ - 需要多尺寸资源时使用 `srcset`、`sizes`、`picture` 或框架图片组件,避免移动端下载桌面大图。
41
+ - 媒体裁切必须保留主体信息,不为填满卡片裁掉产品、人物、图表或状态关键区域。
216
42
 
217
43
  ## 检查清单
218
44
 
219
- - [ ] 375px 宽度下布局正常,无水平溢出
220
- - [ ] 所有交互元素 ≥ 44×44px(触摸目标)
221
- - [ ] 输入框 font-size ≥ 16px(避免 iOS 缩放)
222
- - [ ] 无 hover 依赖的关键功能
223
- - [ ] 图片使用 srcset / picture 按设备加载
224
- - [ ] iPhone 安全区域适配(safe-area-inset)
225
- - [ ] 内容在断点间平滑过渡,无突变
226
- - [ ] 断点中间值、横竖屏切换和虚拟键盘弹出不遮挡主操作
227
- - [ ] 数据密集区域有列优先级或局部滚动策略
45
+ - [ ] 320-375px 页面级无水平溢出。
46
+ - [ ] 断点切换后阅读顺序合理,主操作不被隐藏。
47
+ - [ ] 触摸目标、输入字号、safe area、虚拟键盘和横竖屏行为已验证。
48
+ - [ ] loading、empty、error、disabled、hover/focus、长翻译文本和大数字不会撑坏固定格式控件。
49
+ - [ ] 数据密集区域有列优先级、局部滚动或移动端摘要策略。
50
+ - [ ] 首屏媒体尺寸稳定,非首屏媒体不会拖慢移动端主路径。
@@ -1,163 +1,60 @@
1
1
  # 状态管理规范
2
2
 
3
+ 本文件约定前端状态归属底线。状态清单、Store 形状示例、URL 状态、持久化适配器和 SSR 隔离细节交给 `fec-state-management`;请求缓存细节交给数据获取 workflow;表单字段和校验交给表单 workflow。
4
+
3
5
  ## 状态分类
4
6
 
5
- | 类型 | 示例 | 存放位置 |
6
- | ------------ | -------------------------------- | ------------------- |
7
- | 组件 UI 状态 | modal 开关、tab 索引、hover 状态 | 组件内 state |
8
- | 表单状态 | 输入值、校验错误 | 表单库或组件 state |
9
- | 服务端数据 | 用户列表、订单详情 | 数据请求库缓存 |
10
- | 全局业务状态 | 当前用户、权限、主题 | 全局 Store |
11
- | URL 状态 | 当前页码、筛选条件、排序 | 路由参数 / 搜索参数 |
7
+ | 类型 | 示例 | 默认归属 |
8
+ | ---- | ---- | -------- |
9
+ | 本地 UI 状态 | modal 开关、tab、展开行、hover 编辑态 | 组件内 state / ref |
10
+ | 表单状态 | 输入值、脏字段、校验错误、提交中 | 表单库或表单组件 |
11
+ | 服务端状态 | 列表、详情、分页结果、远程错误 | 请求缓存库 |
12
+ | URL 状态 | 搜索词、筛选、排序、页码、选中 tab | 路由参数 / search params |
13
+ | 全局客户端状态 | 登录用户、主题、权限快照、购物车草稿 | 全局 store |
14
+ | 浏览器持久化状态 | 偏好、非敏感草稿、离线队列 | 存储层 + 状态适配器 |
12
15
 
13
16
  ## 核心原则
14
17
 
15
- - **就近管理**: 状态放在需要它的最近公共祖先
16
- - **单一数据源**: 同一份数据只在一个地方维护
17
- - **派生优于同步**: 可计算的值用 computed / useMemo,而不是手动同步多个 state
18
- - **最小状态**: 不存储可以从已有状态推导的值
19
-
20
- ## React 状态管理
21
-
22
- ### 本地状态
23
-
24
- ```tsx
25
- // 简单值 - useState
26
- const [count, setCount] = useState(0);
27
-
28
- // 复杂逻辑 - useReducer
29
- const [state, dispatch] = useReducer(formReducer, initialState);
30
- ```
31
-
32
- ### 全局状态(Zustand 示例)
33
-
34
- <!-- 请根据项目实际选型调整:Redux Toolkit / Zustand / Jotai -->
35
-
36
- ```tsx
37
- const useAuthStore = create<AuthState>((set) => ({
38
- user: null,
39
- login: async (credentials) => {
40
- const user = await authApi.login(credentials);
41
- set({ user });
42
- },
43
- logout: () => set({ user: null }),
44
- }));
45
- ```
46
-
47
- ### 服务端状态
48
-
49
- <!-- 请根据项目实际选型调整:React Query / SWR -->
50
-
51
- ```tsx
52
- const { data, isLoading, error } = useQuery({
53
- queryKey: ["users", params],
54
- queryFn: () => fetchUsers(params),
55
- staleTime: 5 * 60 * 1000,
56
- });
57
- ```
58
-
59
- ## Vue 状态管理
60
-
61
- ### 本地状态
62
-
63
- ```typescript
64
- const count = ref(0);
65
- const form = reactive({ name: "", email: "" });
66
- ```
67
-
68
- ### 全局状态(Pinia)
69
-
70
- ```typescript
71
- export const useAuthStore = defineStore("auth", () => {
72
- const user = ref<User | null>(null);
73
-
74
- async function login(credentials: LoginParams) {
75
- user.value = await authApi.login(credentials);
76
- }
77
-
78
- function logout() {
79
- user.value = null;
80
- }
81
-
82
- const isLoggedIn = computed(() => user.value !== null);
83
-
84
- return { user: readonly(user), isLoggedIn, login, logout };
85
- });
86
- ```
87
-
88
- ### 服务端状态
89
-
90
- <!-- 请根据项目实际选型调整:VueQuery / 自定义 composable -->
91
-
92
- ```typescript
93
- const { data, isLoading, error } = useQuery({
94
- queryKey: ["users", params],
95
- queryFn: () => fetchUsers(toValue(params)),
96
- });
97
- ```
98
-
99
- ## 选型决策矩阵
100
-
101
- ### React 全局状态管理选型
102
-
103
- | 维度 | Context API | Zustand | Redux Toolkit | Jotai |
104
- | -------------- | -------------------------------------- | -------------------------------------- | ------------------------------- | ------------------- |
105
- | **适用场景** | 全局常量(主题、语言、用户信息) | 复杂业务状态(购物车、Dashboard 筛选) | 大型应用,需要严格的状态流控制 | 细粒度原子状态 |
106
- | **重渲染性能** | ❌ 任何 value 变化导致所有消费者重渲染 | ✅ 通过 selector 精确订阅 | ✅ connect/useSelector 精确订阅 | ✅ 原子级订阅 |
107
- | **样板代码** | 少(Provider + createContext) | 极少(一个 create 调用) | 多(slice / action / selector) | 极少(atom) |
108
- | **DevTools** | ❌ 无 | ✅ Redux DevTools(中间件) | ✅ Redux DevTools | ✅ 专用 DevTools |
109
- | **TypeScript** | ⚠️ 需手动类型标注 | ✅ 自动推导 | ✅ 自动推导 | ✅ 自动推导 |
110
- | **中间件** | ❌ | ✅(persist / devtools / immer) | ✅(thunk / listener) | ✅ |
111
- | **Provider** | ✅ 必须包裹 | ❌ 不需要(外部 store) | ✅ Provider | ❌(可选 Provider) |
18
+ - **先归属,后选库**:不要先选 Redux、Zustand、Pinia 或 Context;先确定每个状态的唯一 owner。
19
+ - **就近管理**:状态放在需要它的最近公共祖先。
20
+ - **单一数据源**:同一份数据只在一个地方维护。
21
+ - **派生优于同步**:可从 props、server state、URL 或已有 state 推导的值,不另存一份。
22
+ - **最小全局状态**:全局 store 只保存真正跨页面、跨 feature 或需要统一动作的客户端状态。
112
23
 
113
- **推荐决策流程**:
24
+ ## React 状态边界
114
25
 
115
- ```
116
- 状态是否跨组件共享?
117
- ├── 否 → useState / useReducer(本地状态)
118
- └── 是
119
- ├── 值是否几乎不变?(主题、语言、配置)
120
- │ └── 是 → Context API
121
- │
122
- ├── 是否需要严格状态流 + 时间旅行调试?
123
- │ └── 是 → Redux Toolkit
124
- │
125
- ├── 状态是否高度关联、需要集中管理?
126
- │ └── 是 → Zustand
127
- │
128
- └── 状态是否独立、需要细粒度订阅?
129
- └── 是 → Jotai
130
- ```
26
+ - 单组件或小子树使用 `useState` / `useReducer`。
27
+ - 低频全局配置、主题或依赖注入可用 Context;高频变化的大对象不要放 Context。
28
+ - 中等复杂业务状态可用 Zustand、Jotai 或仓库既有方案;大型严格动作流可用 Redux Toolkit。
29
+ - 服务端数据使用请求缓存库,不复制到全局 store。
131
30
 
132
- ### Vue 全局状态管理选型
31
+ ## Vue 状态边界
133
32
 
134
- | 维度 | provide/inject | Pinia |
135
- | -------------- | ---------------------------------- | ---------------- |
136
- | **适用场景** | 局部跨层级传递(主题、表单上下文) | 全局业务状态 |
137
- | **响应式** | ✅(传入 reactive/ref) | ✅ |
138
- | **DevTools** | ❌ | ✅ Vue DevTools |
139
- | **TypeScript** | ⚠️ 需 InjectionKey | ✅ 自动推导 |
140
- | **SSR 安全** | ⚠️ 需注意作用域 | ✅ 内置 SSR 支持 |
33
+ - 局部状态使用 `ref` / `reactive` / `computed`。
34
+ - 局部跨层级上下文使用 `provide/inject`。
35
+ - 全局业务状态使用 Pinia 或项目既有 store。
36
+ - 服务端数据优先使用请求库或 composable 管理,不原封不动写入 Pinia。
141
37
 
142
- **Vue 选型结论**:Pinia 是 Vue 3 官方推荐,新项目直接使用。provide/inject 仅用于局部上下文传递。
38
+ ## URL 与持久化状态
143
39
 
144
- ---
40
+ - 搜索、筛选、排序、分页、选中 tab 等需要分享或刷新保留的视图状态优先放 URL。
41
+ - 浏览器持久化只保存稳定偏好或非敏感草稿,并明确字段白名单、版本号、迁移路径、过期策略和敏感字段排除。
42
+ - SSR 场景不要在模块顶层创建带用户数据的单例 store;每次请求需要独立实例。
145
43
 
146
44
  ## 反模式
147
45
 
148
- - 将所有状态都放进全局 store(应优先本地状态)
149
- - 在 store 中存放 UI 临时状态(modal 开关、表单输入等)
150
- - 手动同步多份相同数据而不是用计算属性
151
- - 在组件中直接修改 store 的内部数据(应通过 action / mutation)
152
- - 将服务端响应原封不动存入全局 store 而不用请求缓存库
153
- - 过度使用 Context / provide 替代 props 传递
154
- - 用 Context 管理频繁更新的状态(导致全量消费者重渲染,应改用 Zustand/Pinia)
46
+ - 将所有状态都放进全局 store。
47
+ - 在 store 中存放 UI 临时状态或表单每个字段。
48
+ - 手动同步多份相同数据,而不是从源状态派生。
49
+ - 将服务端响应原封不动存入全局 store,而不用请求缓存库。
50
+ - 用 Context / provide 承载高频变化大对象,导致大范围重渲染。
51
+ - 持久化 token、权限细节、个人敏感数据或未版本化的大对象。
155
52
 
156
53
  ## 检查清单
157
54
 
158
- - [ ] 每个状态都有明确的归属(本地 / 全局 / URL / 服务端缓存)
159
- - [ ] 可派生的值没有被存为独立 state
160
- - [ ] 全局 store 仅包含真正需要跨组件共享的数据
161
- - [ ] 服务端数据通过请求库管理,而非手动存入 store
162
- - [ ] URL 状态(搜索、分页、筛选)与路由参数同步
163
- - [ ] Context 仅用于低频变更的全局值(主题、语言、用户信息)
55
+ - [ ] 每个状态都有明确归属:本地 / 表单 / 服务端缓存 / URL / 全局 store / 浏览器持久化。
56
+ - [ ] 可派生的值没有被存为独立 state。
57
+ - [ ] 全局 store 只包含真正跨边界共享的数据。
58
+ - [ ] 服务端数据通过请求库管理,刷新、回退、权限变化和错误状态仍可恢复。
59
+ - [ ] URL 状态与路由参数同步,刷新和分享行为符合预期。
60
+ - [ ] 持久化状态有白名单、版本、迁移和敏感字段排除。