@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.
- package/dist/template-empty/README.md +8 -6
- package/dist/template-empty/package.json +2 -2
- package/dist/template-empty/references/examples/common-patterns.md +4 -15
- package/dist/template-empty/references/examples/component-basics.md +34 -17
- package/dist/template-empty/references/guides/component-development.md +103 -69
- package/dist/template-empty/references/guides/performance-optimization.md +0 -2
- package/dist/template-empty/references/guides/troubleshooting.md +0 -4
- package/dist/template-empty/references/reference/framework-api-quick-ref.md +52 -39
- 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
- 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
- package/dist/template-empty/references/reference/open-api/README.md +1 -1
- package/dist/template-empty/references/reference/open-api.md +91 -2
- package/dist/template-empty/references/rules/dos-and-donts.md +113 -36
- package/dist/template-starter/package.json +2 -2
- package/dist/template-starter/references/examples/common-patterns.md +4 -15
- package/dist/template-starter/references/examples/component-basics.md +34 -17
- package/dist/template-starter/references/guides/component-development.md +103 -69
- package/dist/template-starter/references/guides/performance-optimization.md +0 -2
- package/dist/template-starter/references/guides/troubleshooting.md +0 -4
- package/dist/template-starter/references/reference/framework-api-quick-ref.md +52 -39
- 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
- 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
- package/dist/template-starter/references/reference/open-api/README.md +1 -1
- package/dist/template-starter/references/reference/open-api.md +91 -2
- package/dist/template-starter/references/rules/dos-and-donts.md +113 -36
- package/dist/template-starter/src/app.config.ts +3 -29
- 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
|
-
|
|
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
|
-
|
|
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.
|
|
9
|
+
"@doubao-apps/framework": "^0.0.29"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@doubao-apps/kit": "^0.0.
|
|
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
|
|
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
|
|
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<
|
|
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
|
|
281
|
+
interface WeatherWidgetData {
|
|
265
282
|
city: string;
|
|
266
283
|
}
|
|
267
284
|
|
|
268
|
-
function WeatherCard({ city }:
|
|
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
|
|
369
|
-
return <WeatherCard 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.
|
|
470
|
-
- `id`
|
|
471
|
-
- `title
|
|
472
|
-
- `
|
|
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.
|
|
490
|
-
- 使用
|
|
491
|
-
-
|
|
492
|
-
-
|
|
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.
|
|
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
|
-
//
|
|
68
|
+
// 2. 渲染函数
|
|
40
69
|
render() {
|
|
41
70
|
// 使用 getViewData() 和 getViewContext() 获取数据和上下文
|
|
42
|
-
const
|
|
71
|
+
const viewData = getViewData();
|
|
43
72
|
|
|
44
|
-
return <MyPageComponent {...
|
|
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
|
|
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
|
|
115
|
-
const { userId, tab = 'profile' } =
|
|
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
|
|
165
|
+
`url` 在常规页面跳转里填写页面的 `pageId`。显式配置时取 `src/app.config.ts` 中对应 page 的 `id`;不配置时取入口目录名,例如
|
|
166
|
+
`src/pages/detail/index.tsx` 默认为 `detail`。
|
|
149
167
|
|
|
150
|
-
页面内可继续通过 `getViewData<
|
|
168
|
+
页面内可继续通过 `getViewData<PageViewData>()` 读取 URL 中传入的参数。
|
|
151
169
|
|
|
152
170
|
### 常用模式
|
|
153
171
|
|
|
@@ -243,14 +261,26 @@ function FormPage() {
|
|
|
243
261
|
|
|
244
262
|
## 🎴 Widget 开发指南
|
|
245
263
|
|
|
246
|
-
###
|
|
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
|
-
|
|
253
|
-
|
|
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
|
|
305
|
-
return <MyWidgetComponent {...
|
|
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
|
-
|
|
327
|
-
|
|
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
|
|
372
|
+
const viewData = getViewData<{ title: string; content: string }>();
|
|
340
373
|
|
|
341
374
|
return (
|
|
342
375
|
<view className="info-card">
|
|
343
|
-
<text className="title">{
|
|
344
|
-
<text className="content">{
|
|
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
|
-
|
|
361
|
-
|
|
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
|
|
409
|
+
const viewData = getViewData<{ action: string; result: string }>();
|
|
374
410
|
return (
|
|
375
411
|
<view className="user-action-card">
|
|
376
|
-
<text>操作: {
|
|
377
|
-
<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
|
|
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
|
|
439
|
+
const viewData = getViewData<ProductCardData>();
|
|
404
440
|
return (
|
|
405
441
|
<view className="product-card">
|
|
406
|
-
<text className="name">{
|
|
407
|
-
<text className="price">¥{
|
|
408
|
-
{
|
|
442
|
+
<text className="name">{viewData.name}</text>
|
|
443
|
+
<text className="price">¥{viewData.price}</text>
|
|
444
|
+
{viewData.images && (
|
|
409
445
|
<view className="images">
|
|
410
|
-
{
|
|
446
|
+
{viewData.images.map((img, idx) => (
|
|
411
447
|
<image key={idx} src={img} />
|
|
412
448
|
))}
|
|
413
449
|
</view>
|
|
414
450
|
)}
|
|
415
|
-
<text className="category">{
|
|
416
|
-
{!
|
|
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
|
|
679
|
-
console.log('任务列表:',
|
|
712
|
+
const viewData = getViewData<TodoData>();
|
|
713
|
+
console.log('任务列表:', viewData.tasks);
|
|
680
714
|
},
|
|
681
715
|
|
|
682
716
|
render() {
|
|
683
717
|
// render 函数中使用 getViewData() 获取数据
|
|
684
|
-
const
|
|
685
|
-
return <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
|
|
700
|
-
return
|
|
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
|
|
752
|
+
render 函数不再通过参数接收 viewData 和 context,请使用以下方法获取数据和上下文:
|
|
719
753
|
|
|
720
754
|
**推荐做法**:
|
|
721
755
|
```tsx
|
|
722
756
|
// ✅ 推荐:render 函数中使用 getViewData()
|
|
723
757
|
render() {
|
|
724
|
-
const
|
|
725
|
-
return <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
|
|
764
|
+
const viewData = getViewData<WeatherData>();
|
|
731
765
|
// 处理数据...
|
|
732
766
|
}
|
|
733
767
|
|
|
734
768
|
// ✅ 推荐:同时获取数据和上下文
|
|
735
769
|
render() {
|
|
736
|
-
const
|
|
770
|
+
const viewData = getViewData<WeatherData>();
|
|
737
771
|
const context = getViewContext();
|
|
738
|
-
return <text>{
|
|
772
|
+
return <text>{viewData.city} - {context.lang}</text>;
|
|
739
773
|
}
|
|
740
774
|
```
|
|
741
775
|
|
|
@@ -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
|
},
|