@doubao-apps/create 0.0.28 → 0.0.29

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 (27) hide show
  1. package/dist/template-empty/README.md +8 -6
  2. package/dist/template-empty/package.json +2 -2
  3. package/dist/template-empty/references/examples/common-patterns.md +4 -15
  4. package/dist/template-empty/references/examples/component-basics.md +34 -17
  5. package/dist/template-empty/references/guides/component-development.md +103 -69
  6. package/dist/template-empty/references/guides/performance-optimization.md +0 -2
  7. package/dist/template-empty/references/guides/troubleshooting.md +0 -4
  8. package/dist/template-empty/references/reference/framework-api-quick-ref.md +52 -39
  9. package/dist/template-empty/references/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +12 -2
  10. package/dist/template-empty/references/reference/open-api/10-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +34 -0
  11. package/dist/template-empty/references/reference/open-api/README.md +1 -1
  12. package/dist/template-empty/references/reference/open-api.md +91 -2
  13. package/dist/template-empty/references/rules/dos-and-donts.md +113 -36
  14. package/dist/template-starter/package.json +2 -2
  15. package/dist/template-starter/references/examples/common-patterns.md +4 -15
  16. package/dist/template-starter/references/examples/component-basics.md +34 -17
  17. package/dist/template-starter/references/guides/component-development.md +103 -69
  18. package/dist/template-starter/references/guides/performance-optimization.md +0 -2
  19. package/dist/template-starter/references/guides/troubleshooting.md +0 -4
  20. package/dist/template-starter/references/reference/framework-api-quick-ref.md +52 -39
  21. package/dist/template-starter/references/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +12 -2
  22. package/dist/template-starter/references/reference/open-api/10-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +34 -0
  23. package/dist/template-starter/references/reference/open-api/README.md +1 -1
  24. package/dist/template-starter/references/reference/open-api.md +91 -2
  25. package/dist/template-starter/references/rules/dos-and-donts.md +113 -36
  26. package/dist/template-starter/src/app.config.ts +3 -29
  27. package/package.json +1 -1
@@ -31,13 +31,14 @@ import { defineAppConfig } from '@doubao-apps/kit';
31
31
  export default defineAppConfig({
32
32
  appId: 'com.example.demo',
33
33
  name: 'Demo App',
34
- pages: {
35
- 'pages/home': {
34
+ pages: [
35
+ {
36
+ entry: 'pages/home/index',
36
37
  id: 'home',
37
38
  title: 'Home',
38
39
  description: 'Home page'
39
40
  }
40
- }
41
+ ]
41
42
  });
42
43
  ```
43
44
 
@@ -72,13 +73,14 @@ export default definePage({
72
73
  import { defineAppConfig } from '@doubao-apps/kit';
73
74
 
74
75
  export default defineAppConfig({
75
- pages: {
76
- 'pages/home': {
76
+ pages: [
77
+ {
78
+ entry: 'pages/home/index',
77
79
  id: 'home',
78
80
  title: 'Home',
79
81
  description: 'Home page'
80
82
  }
81
- }
83
+ ]
82
84
  });
83
85
  ```
84
86
 
@@ -6,10 +6,10 @@
6
6
  "build": "doubao build"
7
7
  },
8
8
  "dependencies": {
9
- "@doubao-apps/framework": "^0.0.28"
9
+ "@doubao-apps/framework": "^0.0.29"
10
10
  },
11
11
  "devDependencies": {
12
- "@doubao-apps/kit": "^0.0.28",
12
+ "@doubao-apps/kit": "^0.0.29",
13
13
  "typescript": "5.5.3"
14
14
  },
15
15
  "version": "0.0.16"
@@ -412,7 +412,8 @@ function relaunchHome() {
412
412
  }
413
413
  ```
414
414
 
415
- 这里的 `url` 直接使用目标页面的 `pageId`,与页面的 `aiMeta.id` 一致;如需传参,可继续拼接 query string。
415
+ 这里的 `url` 直接使用目标页面的 `pageId`。显式配置时取 `src/app.config.ts` 中对应 page 的 `id`;不配置时取入口目录名,例如
416
+ `src/pages/detail/index.tsx` 默认为 `detail`。如需传参,可继续拼接 query string。
416
417
 
417
418
  ### 2. 页面间传参
418
419
 
@@ -441,20 +442,16 @@ function navigateWithParams() {
441
442
  // 接收方 (detail-page)
442
443
  import { getViewData } from '@doubao-apps/framework';
443
444
 
444
- interface DetailPageInput {
445
+ interface DetailPageData {
445
446
  id: string;
446
447
  name: string;
447
448
  price: number;
448
449
  }
449
450
 
450
451
  export default definePage({
451
- aiMeta: {
452
- id: 'detail-page',
453
- title: '详情页'
454
- },
455
452
  render() {
456
453
  // getViewData() 直接返回传入页面的最终对象
457
- const { id, name, price } = getViewData<DetailPageInput>();
454
+ const { id, name, price } = getViewData<DetailPageData>();
458
455
 
459
456
  return (
460
457
  <view>
@@ -497,10 +494,6 @@ function goBackTwoPages() {
497
494
 
498
495
  ```tsx
499
496
  export default definePage({
500
- aiMeta: {
501
- id: 'my-page',
502
- title: '我的页面'
503
- },
504
497
  onShow() {
505
498
  // 页面显示时调用(包括从其他页面返回)
506
499
  console.log('页面显示');
@@ -536,10 +529,6 @@ function openGridPage() {
536
529
 
537
530
  // 九宫格页面定义
538
531
  export default definePage({
539
- aiMeta: {
540
- id: 'app-grid',
541
- title: '应用中心'
542
- },
543
532
  render() {
544
533
  const apps = [
545
534
  { id: 'app1', name: '应用1', icon: '🎯' },
@@ -28,6 +28,28 @@ src/pages/user-profile/
28
28
  └── index.scss # 组件样式
29
29
  ```
30
30
 
31
+ ### app.config.ts
32
+
33
+ `app.config.ts` 需要配置 `appId` 和 `name`。这里额外配置 `pages` 是为了补充标题和描述,并确保
34
+ `user-profile` 作为页面 ID 使用。
35
+
36
+ ```ts
37
+ import { defineAppConfig } from '@doubao-apps/kit';
38
+
39
+ export default defineAppConfig({
40
+ appId: 'com.example.my-doubao-app',
41
+ name: '我的豆包应用',
42
+ pages: [
43
+ {
44
+ entry: 'pages/user-profile/index',
45
+ id: 'user-profile',
46
+ title: '用户资料',
47
+ description: '显示用户个人信息和统计数据'
48
+ }
49
+ ]
50
+ });
51
+ ```
52
+
31
53
  ### index.tsx
32
54
 
33
55
  ```tsx
@@ -139,11 +161,6 @@ function UserProfilePage() {
139
161
  }
140
162
 
141
163
  export default definePage({
142
- aiMeta: {
143
- id: 'user-profile',
144
- title: '用户资料',
145
- description: '显示用户个人信息和统计数据'
146
- },
147
164
  onShow() {
148
165
  console.log('页面显示');
149
166
  },
@@ -261,11 +278,11 @@ interface WeatherData {
261
278
  icon: string;
262
279
  }
263
280
 
264
- interface WeatherWidgetInput {
281
+ interface WeatherWidgetData {
265
282
  city: string;
266
283
  }
267
284
 
268
- function WeatherCard({ city }: WeatherWidgetInput) {
285
+ function WeatherCard({ city }: WeatherWidgetData) {
269
286
  const [weather, setWeather] = useState<WeatherData | null>(null);
270
287
  const [loading, setLoading] = useState(true);
271
288
  const [error, setError] = useState<string | null>(null);
@@ -365,8 +382,8 @@ export default defineWidget({
365
382
  console.log('卡片销毁');
366
383
  },
367
384
  render() {
368
- const input = getViewData<WeatherWidgetInput>();
369
- return <WeatherCard city={input.city} />;
385
+ const viewData = getViewData<WeatherWidgetData>();
386
+ return <WeatherCard city={viewData.city} />;
370
387
  }
371
388
  });
372
389
  ```
@@ -466,10 +483,10 @@ export default defineWidget({
466
483
  - `onHide()` - 页面隐藏时调用
467
484
  - `onDestroy()` - 页面销毁时调用
468
485
 
469
- 2. **页面配置 (aiMeta)**
470
- - `id` - 页面唯一标识
471
- - `title` - 页面标题
472
- - `description` - 页面描述
486
+ 2. **页面配置(可选 pages)**
487
+ - 一级目录不写进 `pages` 也会自动发现,默认 `id` 是目录名
488
+ - 需要 `title`、`description`、固定首页或多级目录时再配置
489
+ - 多级目录需要显式写 `entry`
473
490
 
474
491
  3. **状态管理**
475
492
  - 使用 React Hooks(useState, useEffect)
@@ -486,10 +503,10 @@ export default defineWidget({
486
503
  - `onForeground()` / `onBackground()` - 应用前后台切换
487
504
  - `onMounted()` / `onDestroy()` - 挂载/销毁
488
505
 
489
- 2. **输入数据定义 (input schema)**
490
- - 使用 JSON Schema 定义输入格式
491
- - AI 根据 schema 生成结构化数据
492
- - 必须字段使用 `required` 数组
506
+ 2. **ViewData 定义**
507
+ - 使用 TypeScript 类型定义 `getViewData<T>()` 的 viewData 结构
508
+ - 对可选字段和空数据做兜底处理
509
+ - 避免直接使用 `any`
493
510
 
494
511
  3. **卡片类型 (boxType)**
495
512
  - `inbox` - 普通卡片
@@ -6,6 +6,42 @@ Page(页面)和 Widget(卡片)组件的完整开发指南。
6
6
 
7
7
  ## 🎯 Page 开发指南
8
8
 
9
+ ### App 配置、可选入口与多级目录
10
+
11
+ `src/app.config.ts` 是应用配置文件,需要配置 `appId` 和 `name`。`pages` / `widgets` 是可选的显式入口配置。
12
+ 一级页面目录会自动发现,例如 `src/pages/home/index.tsx` 会产出 `pageId: 'home'`;不配置到 `pages` 时仍可构建,
13
+ 但 `title`、`description` 等页面 metadata 为空。
14
+
15
+ 需要补 metadata、固定首页顺序或声明多级目录时,再配置 `pages` 数组。`pages` 是有序数组,第一项会作为应用首页
16
+ (最终 manifest 的 `appletEntry`);如果希望 `home` 是默认打开页面,把 `pages/home/index` 放在第一项。
17
+ 数组项可以是字符串,也可以是 `{ entry, ...metadata }` 对象:只声明入口时用字符串;需要补 metadata 时用对象。
18
+
19
+ 如果不配置 `pages` / `widgets`,一级 Page / Widget 仍会按目录产出;Page / Widget 的默认 ID 取入口最后一级目录名,
20
+ 页面/卡片 metadata 字段为空,Widget 的 `boxType` 默认为 `inbox`。没有显式 `pages` 顺序时,首页入口会走构建兜底/历史默认
21
+ `index`;首页不是 `index` 时建议配置 `pages` 第一项。
22
+
23
+ 多级目录不会被一级扫描自动发现,例如 `src/pages/account/demo/index.tsx` 需要显式写
24
+ `entry: 'pages/account/demo/index'`。如果不配置 `id`,默认 `pageId` 是最后一级目录名 `demo`。
25
+
26
+ ```ts
27
+ import { defineAppConfig } from '@doubao-apps/kit';
28
+
29
+ export default defineAppConfig({
30
+ appId: 'com.example.my-doubao-app',
31
+ name: '我的豆包应用',
32
+ pages: [
33
+ 'pages/home/index',
34
+ 'pages/account/demo/index',
35
+ {
36
+ entry: 'pages/profile/index',
37
+ id: 'profile',
38
+ title: '资料页',
39
+ description: '补充 metadata 的页面示例'
40
+ }
41
+ ]
42
+ });
43
+ ```
44
+
9
45
  ### 基本结构
10
46
 
11
47
  ```tsx
@@ -13,14 +49,7 @@ import { definePage, getViewData, useState, useEffect } from '@doubao-apps/frame
13
49
  import './index.scss';
14
50
 
15
51
  export default definePage({
16
- // 1. AI 元数据配置
17
- aiMeta: {
18
- id: 'my-page', // 页面唯一标识
19
- title: '我的页面', // 页面标题
20
- description: '页面功能描述' // 页面描述
21
- },
22
-
23
- // 2. 生命周期钩子
52
+ // 1. 生命周期钩子
24
53
  onShow() {
25
54
  // 页面显示时调用(包括从其他页面返回)
26
55
  console.log('页面显示');
@@ -36,12 +65,12 @@ export default definePage({
36
65
  console.log('页面销毁');
37
66
  },
38
67
 
39
- // 3. 渲染函数
68
+ // 2. 渲染函数
40
69
  render() {
41
70
  // 使用 getViewData() 和 getViewContext() 获取数据和上下文
42
- const input = getViewData();
71
+ const viewData = getViewData();
43
72
 
44
- return <MyPageComponent {...input} />;
73
+ return <MyPageComponent {...viewData} />;
45
74
  }
46
75
  });
47
76
  ```
@@ -52,10 +81,6 @@ export default definePage({
52
81
 
53
82
  ```tsx
54
83
  export default definePage({
55
- aiMeta: {
56
- id: 'full-page',
57
- title: '全屏页面'
58
- },
59
84
  render() {
60
85
  return (
61
86
  <view className="full-page">
@@ -72,10 +97,6 @@ export default definePage({
72
97
 
73
98
  ```tsx
74
99
  export default definePage({
75
- aiMeta: {
76
- id: 'grid-page',
77
- title: '九宫格'
78
- },
79
100
  render() {
80
101
  const items = [
81
102
  { id: '1', title: '应用1', icon: '🎯' },
@@ -100,19 +121,15 @@ export default definePage({
100
121
  ### 页面参数接收
101
122
 
102
123
  ```tsx
103
- interface PageInput {
124
+ interface PageViewData {
104
125
  userId: string;
105
126
  tab?: string;
106
127
  }
107
128
 
108
129
  export default definePage({
109
- aiMeta: {
110
- id: 'user-detail',
111
- title: '用户详情'
112
- },
113
130
  render() {
114
- const input = getViewData<PageInput>();
115
- const { userId, tab = 'profile' } = input;
131
+ const viewData = getViewData<PageViewData>();
132
+ const { userId, tab = 'profile' } = viewData;
116
133
 
117
134
  return (
118
135
  <view>
@@ -145,9 +162,10 @@ reLaunch({
145
162
  });
146
163
  ```
147
164
 
148
- `url` 在常规页面跳转里填写页面的 `pageId`,与该页面的 `aiMeta.id` 一致;需要传参时可直接在后面拼接 query string。
165
+ `url` 在常规页面跳转里填写页面的 `pageId`。显式配置时取 `src/app.config.ts` 中对应 page 的 `id`;不配置时取入口目录名,例如
166
+ `src/pages/detail/index.tsx` 默认为 `detail`。
149
167
 
150
- 页面内可继续通过 `getViewData<PageInput>()` 读取 URL 中传入的参数。
168
+ 页面内可继续通过 `getViewData<PageViewData>()` 读取 URL 中传入的参数。
151
169
 
152
170
  ### 常用模式
153
171
 
@@ -243,14 +261,26 @@ function FormPage() {
243
261
 
244
262
  ## 🎴 Widget 开发指南
245
263
 
246
- ### Metadata 配置
264
+ ### 可选 Widgets 配置
265
+
266
+ 一级 Widget 目录会自动发现,例如 `src/widgets/my-widget/index.tsx` 会产出 `widgetId: 'my-widget'`。不配置
267
+ `widgets` 时仍可构建,但 `name`、`description` 等 metadata 为空,`boxType` 默认是 `inbox`。
268
+
269
+ 需要补 metadata 或声明多级目录时,再配置 `widgets` 数组。多级目录如 `src/widgets/order/detail/index.tsx`
270
+ 需要显式写 `entry: 'widgets/order/detail/index'`;如果不配置 `id`,默认 `widgetId` 是最后一级目录名 `detail`。
271
+ 数组项可以是字符串,也可以是 `{ entry, ...metadata }` 对象:只声明入口时用字符串;需要补 metadata 时用对象。
247
272
 
248
273
  ```ts
249
274
  import { defineAppConfig } from '@doubao-apps/kit';
250
275
 
251
276
  export default defineAppConfig({
252
- widgets: {
253
- 'widgets/my-widget': {
277
+ appId: 'com.example.my-doubao-app',
278
+ name: '我的豆包应用',
279
+ widgets: [
280
+ 'widgets/simple-card/index',
281
+ 'widgets/order/detail/index',
282
+ {
283
+ entry: 'widgets/my-widget/index',
254
284
  id: 'my-widget', // 卡片唯一标识
255
285
  name: '我的卡片', // 卡片名称
256
286
  description: '卡片功能描述', // 卡片描述
@@ -259,7 +289,7 @@ export default defineAppConfig({
259
289
  keywords: ['demo', 'widget'],
260
290
  titleType: 'normal'
261
291
  }
262
- }
292
+ ]
263
293
  });
264
294
  ```
265
295
 
@@ -301,8 +331,8 @@ export default defineWidget({
301
331
  },
302
332
 
303
333
  render() {
304
- const input = getViewData<MyWidgetData>();
305
- return <MyWidgetComponent {...input} />;
334
+ const viewData = getViewData<MyWidgetData>();
335
+ return <MyWidgetComponent {...viewData} />;
306
336
  }
307
337
  });
308
338
  ```
@@ -323,25 +353,28 @@ export default defineWidget({
323
353
  import { defineAppConfig } from '@doubao-apps/kit';
324
354
 
325
355
  export default defineAppConfig({
326
- widgets: {
327
- 'widgets/info-card': {
356
+ appId: 'com.example.my-doubao-app',
357
+ name: '我的豆包应用',
358
+ widgets: [
359
+ {
360
+ entry: 'widgets/info-card/index',
328
361
  id: 'info-card',
329
362
  name: '信息卡片',
330
363
  boxType: 'inbox'
331
364
  }
332
- }
365
+ ]
333
366
  });
334
367
  ```
335
368
 
336
369
  ```tsx
337
370
  export default defineWidget({
338
371
  render() {
339
- const input = getViewData<{ title: string; content: string }>();
372
+ const viewData = getViewData<{ title: string; content: string }>();
340
373
 
341
374
  return (
342
375
  <view className="info-card">
343
- <text className="title">{input.title}</text>
344
- <text className="content">{input.content}</text>
376
+ <text className="title">{viewData.title}</text>
377
+ <text className="content">{viewData.content}</text>
345
378
  </view>
346
379
  );
347
380
  }
@@ -357,33 +390,36 @@ export default defineWidget({
357
390
  import { defineAppConfig } from '@doubao-apps/kit';
358
391
 
359
392
  export default defineAppConfig({
360
- widgets: {
361
- 'widgets/user-action-card': {
393
+ appId: 'com.example.my-doubao-app',
394
+ name: '我的豆包应用',
395
+ widgets: [
396
+ {
397
+ entry: 'widgets/user-action-card/index',
362
398
  id: 'user-action-card',
363
399
  name: '全宽卡片示例',
364
400
  boxType: 'full_box'
365
401
  }
366
- }
402
+ ]
367
403
  });
368
404
  ```
369
405
 
370
406
  ```tsx
371
407
  export default defineWidget({
372
408
  render() {
373
- const input = getViewData<{ action: string; result: string }>();
409
+ const viewData = getViewData<{ action: string; result: string }>();
374
410
  return (
375
411
  <view className="user-action-card">
376
- <text>操作: {input.action}</text>
377
- <text>结果: {input.result}</text>
412
+ <text>操作: {viewData.action}</text>
413
+ <text>结果: {viewData.result}</text>
378
414
  </view>
379
415
  );
380
416
  }
381
417
  });
382
418
  ```
383
419
 
384
- ### 输入数据类型
420
+ ### ViewData 类型
385
421
 
386
- Widget 输入数据通过 `getViewData<T>()` 的泛型参数和 TypeScript 接口表达。
422
+ Widget viewData 通过 `getViewData<T>()` 的泛型参数和 TypeScript 接口表达。
387
423
 
388
424
  ```tsx
389
425
  interface ProductCardData {
@@ -400,20 +436,20 @@ interface ProductCardData {
400
436
 
401
437
  export default defineWidget({
402
438
  render() {
403
- const input = getViewData<ProductCardData>();
439
+ const viewData = getViewData<ProductCardData>();
404
440
  return (
405
441
  <view className="product-card">
406
- <text className="name">{input.name}</text>
407
- <text className="price">¥{input.price}</text>
408
- {input.images && (
442
+ <text className="name">{viewData.name}</text>
443
+ <text className="price">¥{viewData.price}</text>
444
+ {viewData.images && (
409
445
  <view className="images">
410
- {input.images.map((img, idx) => (
446
+ {viewData.images.map((img, idx) => (
411
447
  <image key={idx} src={img} />
412
448
  ))}
413
449
  </view>
414
450
  )}
415
- <text className="category">{input.category}</text>
416
- {!input.inStock && <text className="out-of-stock">缺货</text>}
451
+ <text className="category">{viewData.category}</text>
452
+ {!viewData.inStock && <text className="out-of-stock">缺货</text>}
417
453
  </view>
418
454
  );
419
455
  }
@@ -671,18 +707,16 @@ interface TodoData {
671
707
  }
672
708
 
673
709
  export default defineWidget({
674
- aiMeta: { ... },
675
-
676
710
  onMounted() {
677
711
  // 在生命周期钩子中访问数据
678
- const data = getViewData<TodoData>();
679
- console.log('任务列表:', data.tasks);
712
+ const viewData = getViewData<TodoData>();
713
+ console.log('任务列表:', viewData.tasks);
680
714
  },
681
715
 
682
716
  render() {
683
717
  // render 函数中使用 getViewData() 获取数据
684
- const input = getViewData<TodoData>();
685
- return <view>{input.tasks.length} 个任务</view>;
718
+ const viewData = getViewData<TodoData>();
719
+ return <view>{viewData.tasks.length} 个任务</view>;
686
720
  }
687
721
  });
688
722
  ```
@@ -696,8 +730,8 @@ interface WeatherData {
696
730
 
697
731
  function WeatherWidget() {
698
732
  const loadWeatherIcon = () => {
699
- const data = getViewData<WeatherData>();
700
- return data.temperature > 25 ? '☀️' : '❄️';
733
+ const viewData = getViewData<WeatherData>();
734
+ return viewData.temperature > 25 ? '☀️' : '❄️';
701
735
  };
702
736
 
703
737
  return (
@@ -715,27 +749,27 @@ function WeatherWidget() {
715
749
 
716
750
  ### 使用 `getViewData()` 和 `getViewContext()`
717
751
 
718
- render 函数不再接收 input 和 context 参数,请使用以下方法获取数据和上下文:
752
+ render 函数不再通过参数接收 viewData 和 context,请使用以下方法获取数据和上下文:
719
753
 
720
754
  **推荐做法**:
721
755
  ```tsx
722
756
  // ✅ 推荐:render 函数中使用 getViewData()
723
757
  render() {
724
- const input = getViewData<WeatherData>();
725
- return <text>{input.city}: {input.temperature}°C</text>;
758
+ const viewData = getViewData<WeatherData>();
759
+ return <text>{viewData.city}: {viewData.temperature}°C</text>;
726
760
  }
727
761
 
728
762
  // ✅ 推荐:生命周期钩子中使用 getViewData()
729
763
  onMounted() {
730
- const data = getViewData<WeatherData>();
764
+ const viewData = getViewData<WeatherData>();
731
765
  // 处理数据...
732
766
  }
733
767
 
734
768
  // ✅ 推荐:同时获取数据和上下文
735
769
  render() {
736
- const input = getViewData<WeatherData>();
770
+ const viewData = getViewData<WeatherData>();
737
771
  const context = getViewContext();
738
- return <text>{input.city} - {context.lang}</text>;
772
+ return <text>{viewData.city} - {context.lang}</text>;
739
773
  }
740
774
  ```
741
775
 
@@ -348,8 +348,6 @@ function HeavyFeature() {
348
348
  ```tsx
349
349
  // ✅ 好的做法 - 优先渲染关键内容
350
350
  export default definePage({
351
- aiMeta: { /* ... */ },
352
-
353
351
  onShow() {
354
352
  // 先显示页面骨架
355
353
  this.showSkeleton = true;
@@ -120,8 +120,6 @@ const handleClick = useCallback(() => {
120
120
  ```tsx
121
121
  // ❌ 错误写法 - 没有在正确位置定义
122
122
  export default definePage({
123
- aiMeta: { /* ... */ },
124
-
125
123
  render() {
126
124
  // ❌ 不能在这里定义
127
125
  const onShow = () => {
@@ -134,8 +132,6 @@ export default definePage({
134
132
 
135
133
  // ✅ 正确写法
136
134
  export default definePage({
137
- aiMeta: { /* ... */ },
138
-
139
135
  onShow() {
140
136
  console.log('Page shown');
141
137
  },