@qlover/create-app 0.6.1 → 0.6.3

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 (68) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/templates/react-app/README.en.md +257 -0
  5. package/dist/templates/react-app/README.md +29 -231
  6. package/dist/templates/react-app/config/IOCIdentifier.ts +13 -0
  7. package/dist/templates/react-app/docs/en/bootstrap.md +562 -0
  8. package/dist/templates/react-app/docs/en/development-guide.md +523 -0
  9. package/dist/templates/react-app/docs/en/env.md +482 -0
  10. package/dist/templates/react-app/docs/en/global.md +509 -0
  11. package/dist/templates/react-app/docs/en/i18n.md +268 -0
  12. package/dist/templates/react-app/docs/en/index.md +173 -0
  13. package/dist/templates/react-app/docs/en/ioc.md +424 -0
  14. package/dist/templates/react-app/docs/en/project-structure.md +434 -0
  15. package/dist/templates/react-app/docs/en/request.md +425 -0
  16. package/dist/templates/react-app/docs/en/router.md +404 -0
  17. package/dist/templates/react-app/docs/en/store.md +321 -0
  18. package/dist/templates/react-app/docs/en/theme.md +424 -0
  19. package/dist/templates/react-app/docs/en/typescript-guide.md +473 -0
  20. package/dist/templates/react-app/docs/zh/bootstrap.md +562 -0
  21. package/dist/templates/react-app/docs/zh/development-guide.md +523 -0
  22. package/dist/templates/react-app/docs/zh/env.md +479 -0
  23. package/dist/templates/react-app/docs/zh/global.md +511 -0
  24. package/dist/templates/react-app/docs/zh/i18n.md +268 -0
  25. package/dist/templates/react-app/docs/zh/index.md +173 -0
  26. package/dist/templates/react-app/docs/zh/ioc.md +422 -0
  27. package/dist/templates/react-app/docs/zh/project-structure.md +434 -0
  28. package/dist/templates/react-app/docs/zh/request.md +429 -0
  29. package/dist/templates/react-app/docs/zh/router.md +408 -0
  30. package/dist/templates/react-app/docs/zh/store.md +321 -0
  31. package/dist/templates/react-app/docs/zh/theme.md +424 -0
  32. package/dist/templates/react-app/docs/zh/typescript-guide.md +473 -0
  33. package/dist/templates/react-app/package.json +2 -2
  34. package/dist/templates/react-app/src/base/apis/AiApi.ts +10 -5
  35. package/dist/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +1 -1
  36. package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +1 -1
  37. package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +10 -17
  38. package/dist/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +1 -1
  39. package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +2 -1
  40. package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +7 -5
  41. package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +3 -2
  42. package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +33 -0
  43. package/dist/templates/react-app/src/base/cases/RequestLogger.ts +1 -1
  44. package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +2 -2
  45. package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +1 -1
  46. package/dist/templates/react-app/src/base/services/RouteService.ts +5 -2
  47. package/dist/templates/react-app/src/base/services/UserService.ts +8 -10
  48. package/dist/templates/react-app/src/core/IOC.ts +73 -83
  49. package/dist/templates/react-app/src/core/bootstraps/BootstrapApp.ts +52 -4
  50. package/dist/templates/react-app/src/core/bootstraps/{index.ts → BootstrapsRegistry.ts} +2 -3
  51. package/dist/templates/react-app/src/core/registers/IocRegisterImpl.ts +25 -0
  52. package/dist/templates/react-app/src/core/registers/RegisterCommon.ts +11 -17
  53. package/dist/templates/react-app/src/core/registers/RegisterControllers.ts +10 -4
  54. package/dist/templates/react-app/src/core/registers/RegisterGlobals.ts +6 -15
  55. package/dist/templates/react-app/src/main.tsx +2 -5
  56. package/dist/templates/react-app/src/styles/css/antd-themes/dark.css +3 -1
  57. package/dist/templates/react-app/src/styles/css/antd-themes/index.css +1 -1
  58. package/dist/templates/react-app/src/styles/css/antd-themes/pink.css +6 -1
  59. package/dist/templates/react-app/src/styles/css/page.css +1 -1
  60. package/dist/templates/react-app/src/uikit/controllers/JSONStorageController.ts +1 -1
  61. package/dist/templates/react-app/tsconfig.app.json +2 -1
  62. package/dist/templates/react-app/tsconfig.node.json +2 -1
  63. package/package.json +2 -2
  64. package/dist/templates/react-app/src/base/port/ApiTransactionInterface.ts +0 -7
  65. package/dist/templates/react-app/src/base/port/RequestCatcherInterface.ts +0 -12
  66. package/dist/templates/react-app/src/core/bootstrap.ts +0 -58
  67. package/dist/templates/react-app/src/core/registers/RegisterApi.ts +0 -5
  68. package/dist/templates/react-app/src/core/registers/index.ts +0 -32
@@ -0,0 +1,408 @@
1
+ # 路由系统
2
+
3
+ ## 概述
4
+
5
+ 路由系统采用配置式路由,通过 `RouteService` 和 `RouterLoader` 实现了一个灵活、可扩展的路由管理方案。主要特点:
6
+
7
+ - **配置驱动**:通过配置文件定义路由,无需手动编写路由组件
8
+ - **代码分割**:自动处理组件的懒加载
9
+ - **类型安全**:完整的 TypeScript 类型支持
10
+ - **状态管理**:与 Store 系统无缝集成
11
+ - **国际化支持**:内置多语言路由支持
12
+ - **元数据扩展**:支持路由级别的元数据配置
13
+
14
+ ## 路由配置
15
+
16
+ ### 1. 路径配置(path)
17
+
18
+ `path` 定义了路由的 URL 路径模式:
19
+
20
+ ```typescript
21
+ {
22
+ // 基础路径
23
+ path: '/about', // 匹配 /about
24
+
25
+ // 动态参数
26
+ path: '/user/:id', // 匹配 /user/123
27
+
28
+ // 可选参数
29
+ path: '/posts/:id?', // 匹配 /posts 和 /posts/1
30
+
31
+ // 多层级路径
32
+ path: '/blog/:category/:id', // 匹配 /blog/tech/123
33
+
34
+ // 通配符
35
+ path: '*', // 匹配任何未定义的路径
36
+
37
+ // 国际化路径
38
+ path: '/:lng/dashboard', // 匹配 /en/dashboard, /zh/dashboard
39
+
40
+ // 索引路由(默认子路由)
41
+ index: true // 父路由的默认渲染内容
42
+ }
43
+ ```
44
+
45
+ ### 2. 组件配置(element)
46
+
47
+ `element` 使用字符串标识符来引用实际的组件,这种设计有以下优势:
48
+
49
+ 1. **自动代码分割**:
50
+
51
+ ```typescript
52
+ // App.tsx
53
+ function getAllPages() {
54
+ // 自动扫描 pages 目录下的所有组件
55
+ const modules = import.meta.glob('./pages/**/*.tsx');
56
+ return Object.keys(modules).reduce((acc, path) => {
57
+ // 将文件路径转换为组件标识符
58
+ const componentName = path.replace(/^\.\/pages\/(.*)\.tsx$/, '$1');
59
+ // 创建懒加载组件
60
+ acc[componentName] = () =>
61
+ lazy(
62
+ modules[path] as () => Promise<{
63
+ default: React.ComponentType<unknown>;
64
+ }>
65
+ );
66
+ return acc;
67
+ }, {} as ComponentValue);
68
+ }
69
+ ```
70
+
71
+ 2. **组件映射规则**:
72
+
73
+ ```typescript
74
+ {
75
+ // 基础组件映射
76
+ element: 'HomePage', // 映射到 pages/HomePage.tsx
77
+
78
+ // 子目录组件
79
+ element: 'user/Profile', // 映射到 pages/user/Profile.tsx
80
+
81
+ // 布局组件
82
+ element: 'layouts/Default', // 映射到 pages/layouts/Default.tsx
83
+
84
+ // 特殊页面
85
+ element: '404', // 映射到 pages/404.tsx
86
+
87
+ // 认证相关页面
88
+ element: 'auth/LoginPage' // 映射到 pages/auth/LoginPage.tsx
89
+ }
90
+ ```
91
+
92
+ 3. **组件加载过程**:
93
+
94
+ ```typescript
95
+ class RouterLoader {
96
+ // 获取组件实现
97
+ getComponent(element: string): () => RouteComponentType {
98
+ const maps = this.getComponentMaps();
99
+ const component = maps[element];
100
+
101
+ if (!component) {
102
+ throw new Error(`Component not found: ${element}`);
103
+ }
104
+
105
+ return component;
106
+ }
107
+
108
+ // 转换为路由对象
109
+ toRoute(route: RouteConfigValue): RouteObject {
110
+ const { element, children, ...rest } = route;
111
+ const component = this.getComponent(element || '404');
112
+
113
+ return {
114
+ ...rest,
115
+ element: this.render({ ...rest, element: component }),
116
+ children: children?.map((child) => this.toRoute(child))
117
+ };
118
+ }
119
+ }
120
+ ```
121
+
122
+ 4. **组件渲染流程**:
123
+
124
+ ```tsx
125
+ // RouterRenderComponent.tsx
126
+ export const RouterRenderComponent: RouterLoaderRender = (route) => {
127
+ const Component = route.element(); // 懒加载组件
128
+
129
+ return (
130
+ <Suspense fallback={<Loading fullscreen />}>
131
+ <BaseRouteProvider {...route.meta}>
132
+ <Component />
133
+ </BaseRouteProvider>
134
+ </Suspense>
135
+ );
136
+ };
137
+ ```
138
+
139
+ ### 3. 完整路由示例
140
+
141
+ ```typescript
142
+ export const baseRoutes: RouteConfigValue[] = [
143
+ // 重定向路由
144
+ {
145
+ path: '/',
146
+ element: 'base/RedirectPathname' // 处理默认语言重定向
147
+ },
148
+
149
+ // 主布局路由
150
+ {
151
+ path: '/:lng', // 语言参数
152
+ element: 'base/Layout', // 主布局组件
153
+ meta: {
154
+ category: 'main'
155
+ },
156
+ children: [
157
+ // 首页路由
158
+ {
159
+ index: true, // 默认子路由
160
+ element: 'base/HomePage', // 首页组件
161
+ meta: {
162
+ title: 'PAGE_HOME_TITLE',
163
+ icon: 'home',
164
+ localNamespace: 'common'
165
+ }
166
+ },
167
+
168
+ // 功能页面路由
169
+ {
170
+ path: 'dashboard', // 仪表盘页面
171
+ element: 'base/DashboardPage',
172
+ meta: {
173
+ title: 'PAGE_DASHBOARD_TITLE',
174
+ icon: 'dashboard'
175
+ }
176
+ }
177
+ ]
178
+ },
179
+
180
+ // 认证布局路由
181
+ {
182
+ path: '/:lng',
183
+ element: 'auth/Layout',
184
+ meta: {
185
+ category: 'auth'
186
+ },
187
+ children: [
188
+ {
189
+ path: 'login',
190
+ element: 'auth/LoginPage',
191
+ meta: {
192
+ title: 'PAGE_LOGIN_TITLE'
193
+ }
194
+ }
195
+ ]
196
+ }
197
+ ];
198
+ ```
199
+
200
+ ### 2. 路由类型定义
201
+
202
+ ```typescript
203
+ interface RouteConfigValue {
204
+ path?: string; // 路由路径
205
+ element: string; // 组件标识符
206
+ children?: RouteConfigValue[]; // 子路由
207
+ meta?: RouteMeta; // 路由元数据
208
+ index?: boolean; // 是否为索引路由
209
+ }
210
+
211
+ interface RouteMeta {
212
+ title?: string; // 页面标题
213
+ description?: string; // 页面描述
214
+ icon?: string; // 页面图标
215
+ category?: string; // 路由分类
216
+ localNamespace?: string; // 国际化命名空间
217
+ }
218
+ ```
219
+
220
+ ## 核心组件
221
+
222
+ ### 1. RouterLoader
223
+
224
+ `RouterLoader` 负责将路由配置转换为实际的路由组件:
225
+
226
+ ```typescript
227
+ class RouterLoader {
228
+ constructor(private readonly options: RouterLoaderOptions) {
229
+ if (!options.render) {
230
+ throw new Error('RouterLoader render is required');
231
+ }
232
+ }
233
+
234
+ // 转换路由配置为 React Router 路由对象
235
+ toRoute(route: RouteConfigValue): RouteObject {
236
+ const { render } = this.options;
237
+ const { element, children, ...rest } = route;
238
+
239
+ const component = this.getComponent(element || '404');
240
+ const Element = render({ ...rest, element: component });
241
+
242
+ return {
243
+ ...rest,
244
+ element: Element,
245
+ children: children?.map((child) => this.toRoute(child))
246
+ };
247
+ }
248
+ }
249
+ ```
250
+
251
+ ### 2. RouteService
252
+
253
+ `RouteService` 管理路由状态和导航:
254
+
255
+ ```typescript
256
+ class RouteService extends StoreInterface<RouterServiceState> {
257
+ // 组合路径(添加语言前缀)
258
+ composePath(path: string): string {
259
+ const targetLang = I18nService.getCurrentLanguage();
260
+ return `/${targetLang}${path}`;
261
+ }
262
+
263
+ // 路由跳转
264
+ goto(path: string, options?: NavigateOptions): void {
265
+ path = this.composePath(path);
266
+ this.navigate?.(path, options);
267
+ }
268
+
269
+ // 更新路由配置
270
+ changeRoutes(routes: RouteConfigValue[]): void {
271
+ this.emit({ routes });
272
+ }
273
+ }
274
+ ```
275
+
276
+ ### 3. RouterRenderComponent
277
+
278
+ 路由渲染组件,处理懒加载和页面上下文:
279
+
280
+ ```tsx
281
+ export const RouterRenderComponent: RouterLoaderRender = (route) => {
282
+ const Component = route.element();
283
+
284
+ return (
285
+ <Suspense fallback={<Loading fullscreen />}>
286
+ <BaseRouteProvider {...route.meta}>
287
+ <Component />
288
+ </BaseRouteProvider>
289
+ </Suspense>
290
+ );
291
+ };
292
+ ```
293
+
294
+ ## 使用方式
295
+
296
+ ### 1. 应用配置
297
+
298
+ 在应用入口处配置路由系统:
299
+
300
+ ```tsx
301
+ function App() {
302
+ // 初始化路由加载器
303
+ const routerLoader = new RouterLoader({
304
+ componentMaps: getAllPages(),
305
+ render: RouterRenderComponent
306
+ });
307
+
308
+ // 获取路由配置
309
+ const routes = useStore(IOC(RouteService), (state) => state.routes);
310
+
311
+ // 创建路由器
312
+ const routerBase = useMemo(() => {
313
+ const routeList = routes.map((route) => routerLoader.toRoute(route));
314
+ return createBrowserRouter(routeList, {
315
+ basename: routerPrefix
316
+ });
317
+ }, [routes]);
318
+
319
+ return <RouterProvider router={routerBase} />;
320
+ }
321
+ ```
322
+
323
+ ### 2. 页面导航
324
+
325
+ 在组件中使用路由服务进行导航:
326
+
327
+ ```tsx
328
+ function LoginButton() {
329
+ const routeService = IOC(RouteService);
330
+
331
+ const handleLogin = () => {
332
+ routeService.goto('/login');
333
+ };
334
+
335
+ return <button onClick={handleLogin}>登录</button>;
336
+ }
337
+ ```
338
+
339
+ ### 3. 路由守卫
340
+
341
+ 通过 `BaseRouteProvider` 实现路由级别的功能:
342
+
343
+ ```tsx
344
+ function BaseRouteProvider(props: PropsWithChildren<RouteMeta>) {
345
+ const { t } = useTranslation();
346
+
347
+ // 自动设置页面标题
348
+ useDocumentTitle(props.title ? t(props.title) : IOC('AppConfig').appName);
349
+
350
+ return (
351
+ <BaseRoutePageContext.Provider value={props}>
352
+ {props.children}
353
+ </BaseRoutePageContext.Provider>
354
+ );
355
+ }
356
+ ```
357
+
358
+ ## 最佳实践
359
+
360
+ 1. **路由组织**
361
+ - 按功能模块组织路由配置
362
+ - 使用嵌套路由处理复杂页面结构
363
+ - 合理使用路由元数据
364
+
365
+ 2. **代码分割**
366
+ - 对大型页面组件进行代码分割
367
+ - 使用 Suspense 处理加载状态
368
+ - 预加载关键路由组件
369
+
370
+ 3. **类型安全**
371
+ - 为所有路由配置定义类型
372
+ - 使用常量管理路由路径
373
+ - 避免硬编码路由字符串
374
+
375
+ 4. **国际化**
376
+ - 使用路由参数处理多语言
377
+ - 配置页面级别的翻译命名空间
378
+ - 自动处理标题和描述的翻译
379
+
380
+ ## 常见问题
381
+
382
+ ### 1. 路由不生效
383
+
384
+ 检查以下几点:
385
+
386
+ - 确保路由配置格式正确
387
+ - 检查组件映射是否正确配置
388
+ - 验证路径是否包含语言前缀
389
+
390
+ ### 2. 页面加载失败
391
+
392
+ 可能的解决方案:
393
+
394
+ - 检查组件是否正确导出
395
+ - 确保懒加载配置正确
396
+ - 查看网络请求是否正常
397
+
398
+ ### 3. 类型错误
399
+
400
+ 常见解决方法:
401
+
402
+ - 确保路由配置符合类型定义
403
+ - 检查组件属性是否完整
404
+ - 使用正确的路由元数据类型
405
+
406
+ ```
407
+
408
+ ```
@@ -0,0 +1,321 @@
1
+ # Store 状态管理
2
+
3
+ ## 核心思想
4
+
5
+ Store 的设计理念基于以下几个核心思想:
6
+
7
+ 1. **逻辑与 UI 分离**
8
+ - 业务逻辑集中在 Store 中管理
9
+ - UI 组件只负责渲染和用户交互
10
+ - 通过 IOC 容器实现逻辑的依赖注入
11
+
12
+ 2. **响应式数据流**
13
+ - 基于发布订阅模式
14
+ - 状态变更自动触发 UI 更新
15
+ - 精确的组件重渲染控制
16
+
17
+ 3. **状态分片管理**
18
+ - 将复杂状态分解为独立的分片
19
+ - 每个分片负责特定的业务领域
20
+ - 分片之间可以组合和通信
21
+
22
+ ## 工作原理
23
+
24
+ ### 1. 状态订阅机制
25
+
26
+ ```typescript
27
+ // Store 内部实现了发布订阅机制
28
+ class SliceStore<T> {
29
+ private listeners = new Set<(state: T) => void>();
30
+
31
+ // 发布状态更新
32
+ protected emit(newState: T) {
33
+ this.state = newState;
34
+ this.listeners.forEach((listener) => listener(this.state));
35
+ }
36
+
37
+ // 订阅状态变化
38
+ subscribe(listener: (state: T) => void) {
39
+ this.listeners.add(listener);
40
+ return () => this.listeners.delete(listener);
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### 2. 状态更新流程
46
+
47
+ ```
48
+ 用户操作 → 调用 Store 方法 → 更新状态 → 通知订阅者 → UI 更新
49
+ ```
50
+
51
+ 1. 用户触发操作(如点击按钮)
52
+ 2. 调用 Store 中的方法
53
+ 3. Store 使用 emit 发布新状态
54
+ 4. 订阅该状态的组件收到通知
55
+ 5. 组件重新渲染,显示最新状态
56
+
57
+ ### 3. 组件集成
58
+
59
+ ```tsx
60
+ // 在组件中使用 Store
61
+ function UserProfile() {
62
+ // useStore hook 自动处理订阅和取消订阅
63
+ const user = useStore(IOC(UserService), (state) => state.userInfo);
64
+
65
+ return <div>{user.name}</div>;
66
+ }
67
+ ```
68
+
69
+ ### 4. 状态分片示例
70
+
71
+ ```typescript
72
+ // 用户认证分片
73
+ class AuthStore extends StoreInterface<AuthState> {
74
+ constructor() {
75
+ super(() => ({
76
+ isLoggedIn: false,
77
+ user: null
78
+ }));
79
+ }
80
+
81
+ login(credentials: Credentials) {
82
+ // 处理登录逻辑
83
+ this.emit({
84
+ isLoggedIn: true,
85
+ user: userData
86
+ });
87
+ }
88
+ }
89
+
90
+ // 主题设置分片
91
+ class ThemeStore extends StoreInterface<ThemeState> {
92
+ constructor() {
93
+ super(() => ({
94
+ mode: 'light',
95
+ colors: defaultColors
96
+ }));
97
+ }
98
+
99
+ toggleTheme() {
100
+ const mode = this.state.mode === 'light' ? 'dark' : 'light';
101
+ this.emit({
102
+ ...this.state,
103
+ mode
104
+ });
105
+ }
106
+ }
107
+ ```
108
+
109
+ ## 概述
110
+
111
+ Store 是应用的状态管理解决方案,基于 `@qlover/slice-store-react` 实现。它采用分片(Slice)的方式来管理状态,具有以下特点:
112
+
113
+ - **类型安全**:基于 TypeScript,提供完整的类型推导
114
+ - **轻量级**:无需复杂的配置,易于使用
115
+ - **高性能**:精确的组件更新,避免不必要的渲染
116
+ - **模块化**:支持状态分片,便于管理大型应用
117
+ - **IOC 集成**:与依赖注入系统完美配合
118
+
119
+ ## 核心概念
120
+
121
+ ### 1. Store 接口
122
+
123
+ Store 系统基于两个核心接口:
124
+
125
+ #### StoreStateInterface
126
+
127
+ ```typescript
128
+ /**
129
+ * Store 状态接口
130
+ *
131
+ * 作用:定义 store 状态对象的契约
132
+ * 核心思想:为 store 状态强制实施一致的结构
133
+ * 主要功能:作为所有 store 状态类型的基础
134
+ * 主要目的:确保状态类型安全和可扩展性
135
+ */
136
+ interface StoreStateInterface {
137
+ // 可以在这里定义自己的属性
138
+ // ...
139
+ }
140
+ ```
141
+
142
+ #### StoreInterface
143
+
144
+ ```typescript
145
+ /**
146
+ * Store 接口
147
+ *
148
+ * 作用:所有状态存储的抽象基类
149
+ * 核心思想:提供统一的状态管理 API,包含重置和克隆辅助方法
150
+ * 主要功能:扩展 SliceStore,添加 resetState 和 cloneState 工具方法
151
+ * 主要目的:简化 store 实现并确保一致性
152
+ */
153
+ abstract class StoreInterface<
154
+ T extends StoreStateInterface
155
+ > extends SliceStore<T> {
156
+ constructor(protected stateFactory: () => T) {
157
+ super(stateFactory);
158
+ }
159
+
160
+ // 重置 store 状态
161
+ resetState(): void {
162
+ this.emit(this.stateFactory());
163
+ }
164
+
165
+ // 克隆 store 状态
166
+ cloneState(source?: Partial<T>): T {
167
+ const cloned = clone(this.state);
168
+ if (typeof cloned === 'object' && cloned !== null) {
169
+ Object.assign(cloned, source);
170
+ }
171
+ return cloned;
172
+ }
173
+ }
174
+ ```
175
+
176
+ ### 2. 状态分片
177
+
178
+ 状态分片(Slice)是将应用状态分割成独立的部分:
179
+
180
+ ```typescript
181
+ // 用户状态分片示例
182
+ class UserState implements StoreStateInterface {
183
+ isLoggedIn: boolean = false;
184
+ userInfo: {
185
+ name: string;
186
+ role: string;
187
+ } | null = null;
188
+ }
189
+
190
+ // Store 实现示例
191
+ export class UserStore extends StoreInterface<UserState> {
192
+ constructor() {
193
+ super(() => new UserState());
194
+ }
195
+ }
196
+ ```
197
+
198
+ ## 在项目中使用
199
+
200
+ ### 1. 创建 Store Controller
201
+
202
+ ```typescript
203
+ import { StoreInterface, StoreStateInterface } from '@qlover/corekit-bridge';
204
+
205
+ interface ExecutorState extends StoreStateInterface {
206
+ helloState: string;
207
+ tasks: Task[];
208
+ }
209
+
210
+ @injectable()
211
+ export class ExecutorController extends StoreInterface<ExecutorState> {
212
+ constructor() {
213
+ super(() => ({
214
+ helloState: '',
215
+ tasks: []
216
+ }));
217
+ }
218
+
219
+ // 选择器
220
+ selector = {
221
+ helloState: (state: ExecutorState) => state.helloState,
222
+ tasks: (state: ExecutorState) => state.tasks
223
+ };
224
+ }
225
+ ```
226
+
227
+ ### 2. 在组件中使用
228
+
229
+ 使用 `useStore` Hook 访问状态:
230
+
231
+ ```tsx
232
+ function MyComponent() {
233
+ // 获取完整状态
234
+ const state = useStore(IOC(ExecutorController));
235
+
236
+ // 使用选择器获取特定状态
237
+ const helloState = useStore(
238
+ IOC(ExecutorController),
239
+ (controller) => controller.selector.helloState
240
+ );
241
+
242
+ return (
243
+ <div>
244
+ <h1>{helloState}</h1>
245
+ </div>
246
+ );
247
+ }
248
+ ```
249
+
250
+ ### 3. 更新状态
251
+
252
+ 通过 controller 方法更新状态:
253
+
254
+ ```typescript
255
+ @injectable()
256
+ class ExecutorController extends StoreInterface<ExecutorState> {
257
+ // ... 构造函数等其他代码
258
+
259
+ updateHelloState(newState: string) {
260
+ this.emit({ ...this.state, helloState: newState });
261
+ }
262
+
263
+ async fetchTasks() {
264
+ const tasks = await api.getTasks();
265
+ this.emit({ ...this.state, tasks });
266
+ }
267
+
268
+ // 使用 cloneState 进行状态更新
269
+ updateWithClone(newState: Partial<ExecutorState>) {
270
+ this.emit(this.cloneState(newState));
271
+ }
272
+ }
273
+ ```
274
+
275
+ ## 最佳实践
276
+
277
+ 1. **状态组织**
278
+ - 按功能模块划分状态
279
+ - 避免状态冗余
280
+ - 保持状态扁平化
281
+
282
+ 2. **性能优化**
283
+ - 使用选择器获取状态,避免不必要的重渲染
284
+ - 合理拆分组件,避免大组件订阅过多状态
285
+ - 使用 `cloneState` 方法确保状态更新的不可变性
286
+
287
+ 3. **类型安全**
288
+ - 为所有状态定义接口
289
+ - 使用 TypeScript 的类型推导
290
+ - 避免使用 any 类型
291
+
292
+ 4. **与启动器集成**
293
+ - 在 Bootstrap 阶段初始化 store
294
+ - 通过 IOC 容器管理 store 实例
295
+ - 使用插件系统扩展功能
296
+
297
+ ## 常见问题
298
+
299
+ ### 1. 状态更新不生效
300
+
301
+ 检查以下几点:
302
+
303
+ - 确保正确使用 `emit` 方法更新状态
304
+ - 使用 `cloneState` 方法确保状态不可变性
305
+ - 检查组件是否正确订阅了状态
306
+
307
+ ### 2. 组件重复渲染
308
+
309
+ 可能的解决方案:
310
+
311
+ - 使用选择器只订阅需要的状态
312
+ - 检查依赖项是否正确设置
313
+ - 考虑使用 React.memo 优化组件
314
+
315
+ ### 3. TypeScript 类型报错
316
+
317
+ 常见解决方法:
318
+
319
+ - 确保正确继承 StoreInterface
320
+ - 检查泛型参数是否正确
321
+ - 确保状态类型实现了 StoreStateInterface