@doubao-apps/create 0.0.33 → 0.0.34

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 (48) hide show
  1. package/dist/421.js +4 -4
  2. package/dist/cli.js +74 -66
  3. package/dist/index.d.ts +1 -2
  4. package/dist/template-empty/README.md +1 -1
  5. package/dist/template-empty/package.json +2 -2
  6. package/dist/template-starter/README.md +48 -169
  7. package/dist/template-starter/package.json +2 -2
  8. package/dist/template-starter/src/app.config.ts +2 -3
  9. package/dist/template-starter/src/pages/home/index.scss +38 -172
  10. package/dist/template-starter/src/pages/home/index.tsx +20 -78
  11. package/dist/template-starter/src/widgets/hello-world/index.scss +23 -0
  12. package/dist/template-starter/src/widgets/hello-world/index.tsx +29 -0
  13. package/package.json +6 -2
  14. package/dist/template-empty/AGENTS.md +0 -299
  15. package/dist/template-empty/references/examples/common-patterns.md +0 -589
  16. package/dist/template-empty/references/examples/component-basics.md +0 -526
  17. package/dist/template-empty/references/guides/best-practices.md +0 -571
  18. package/dist/template-empty/references/guides/component-development.md +0 -891
  19. package/dist/template-empty/references/guides/performance-optimization.md +0 -402
  20. package/dist/template-empty/references/guides/troubleshooting.md +0 -287
  21. package/dist/template-empty/references/reference/components-quick-ref.md +0 -103
  22. package/dist/template-empty/references/reference/framework-api-quick-ref.md +0 -550
  23. package/dist/template-empty/references/reference/open-api/README.md +0 -8
  24. package/dist/template-empty/references/reference/open-api.md +0 -11
  25. package/dist/template-empty/references/rules/dos-and-donts.md +0 -467
  26. package/dist/template-starter/AGENTS.md +0 -299
  27. package/dist/template-starter/debug-scene/render-home-page-full.json +0 -6
  28. package/dist/template-starter/debug-scene/render-home-page.json +0 -5
  29. package/dist/template-starter/debug-scene/render-react-lynx-page-full.json +0 -6
  30. package/dist/template-starter/references/examples/common-patterns.md +0 -589
  31. package/dist/template-starter/references/examples/component-basics.md +0 -526
  32. package/dist/template-starter/references/guides/best-practices.md +0 -571
  33. package/dist/template-starter/references/guides/component-development.md +0 -891
  34. package/dist/template-starter/references/guides/performance-optimization.md +0 -402
  35. package/dist/template-starter/references/guides/troubleshooting.md +0 -287
  36. package/dist/template-starter/references/reference/components-quick-ref.md +0 -103
  37. package/dist/template-starter/references/reference/framework-api-quick-ref.md +0 -550
  38. package/dist/template-starter/references/reference/open-api/README.md +0 -8
  39. package/dist/template-starter/references/reference/open-api.md +0 -11
  40. package/dist/template-starter/references/rules/dos-and-donts.md +0 -467
  41. package/dist/template-starter/src/pages/applet/index.scss +0 -279
  42. package/dist/template-starter/src/pages/applet/index.tsx +0 -78
  43. package/dist/template-starter/src/pages/lynx/index.scss +0 -249
  44. package/dist/template-starter/src/pages/lynx/index.tsx +0 -78
  45. package/dist/template-starter/src/pages/react-lynx/index.scss +0 -335
  46. package/dist/template-starter/src/pages/react-lynx/index.tsx +0 -132
  47. package/dist/template-starter/src/widgets/weather-card/index.scss +0 -272
  48. package/dist/template-starter/src/widgets/weather-card/index.tsx +0 -193
@@ -1,526 +0,0 @@
1
- # 组件基础示例
2
-
3
- Page(页面)和 Widget(卡片)组件的基础用法对比。
4
-
5
- ---
6
-
7
- ## 📋 核心差异
8
-
9
- | 特性 | Page | Widget |
10
- |------|------|--------|
11
- | **使用场景** | 全屏页面、九宫格、浮窗 | 聊天流中的卡片 |
12
- | **定义方式** | `definePage()` | `defineWidget()` |
13
- | **输入数据** | URL 参数、页面配置 | AI 生成的结构化数据 |
14
- | **显示位置** | 独立页面/窗口 | 聊天对话中 |
15
- | **交互方式** | 完整的页面交互 | 卡片内交互 + 消息发送 |
16
- | **生命周期** | `onCreated`, `onMounted`, `onShow`, `onHide`, `onDestroy`,`onError` | `onCreated`, `onMounted`, `onShow`, `onHide`, `onDestroy`,`onError`,`onForeground`, `onBackground` |
17
-
18
- ---
19
-
20
- ## 🎯 Page 基础示例
21
-
22
- ### 用户资料页面
23
-
24
- **文件结构**:
25
- ```
26
- src/pages/user-profile/
27
- ├── index.tsx # 组件逻辑
28
- └── index.scss # 组件样式
29
- ```
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
-
53
- ### index.tsx
54
-
55
- ```tsx
56
- import { definePage, useState, useEffect } from '@doubao-apps/framework';
57
- import './index.scss';
58
-
59
- interface UserProfile {
60
- id: string;
61
- name: string;
62
- avatar: string;
63
- email: string;
64
- stats: {
65
- posts: number;
66
- followers: number;
67
- following: number;
68
- };
69
- }
70
-
71
- function UserProfilePage() {
72
- const [user, setUser] = useState<UserProfile | null>(null);
73
- const [loading, setLoading] = useState(true);
74
- const [error, setError] = useState<string | null>(null);
75
-
76
- // 数据获取
77
- const fetchUserProfile = async () => {
78
- try {
79
- setLoading(true);
80
- setError(null);
81
-
82
- // 模拟 API 请求
83
- await new Promise(resolve => setTimeout(resolve, 1000));
84
-
85
- const mockData: UserProfile = {
86
- id: '12345',
87
- name: '张三',
88
- avatar: 'https://via.placeholder.com/150',
89
- email: 'zhangsan@example.com',
90
- stats: {
91
- posts: 42,
92
- followers: 1234,
93
- following: 567
94
- }
95
- };
96
-
97
- setUser(mockData);
98
- } catch (err) {
99
- setError('加载失败,请重试');
100
- } finally {
101
- setLoading(false);
102
- }
103
- };
104
-
105
- // 编辑按钮
106
- const handleEdit = () => {
107
- console.log('编辑用户资料');
108
- };
109
-
110
- // 渲染
111
- if (loading) {
112
- return (
113
- <view className="profile-container">
114
- <view className="loading">加载中...</view>
115
- </view>
116
- );
117
- }
118
-
119
- if (error) {
120
- return (
121
- <view className="profile-container">
122
- <view className="error">{error}</view>
123
- <button onClick={fetchUserProfile}>重试</button>
124
- </view>
125
- );
126
- }
127
-
128
- if (!user) {
129
- return null;
130
- }
131
-
132
- return (
133
- <view className="profile-container">
134
- {/* 头部 */}
135
- <view className="profile-header">
136
- <image className="avatar" src={user.avatar} />
137
- <text className="name">{user.name}</text>
138
- <text className="email">{user.email}</text>
139
- <button className="edit-btn" onClick={handleEdit}>
140
- 编辑资料
141
- </button>
142
- </view>
143
-
144
- {/* 数据统计 */}
145
- <view className="profile-stats">
146
- <view className="stat-item">
147
- <text className="stat-value">{user.stats.posts}</text>
148
- <text className="stat-label">帖子</text>
149
- </view>
150
- <view className="stat-item">
151
- <text className="stat-value">{user.stats.followers}</text>
152
- <text className="stat-label">关注者</text>
153
- </view>
154
- <view className="stat-item">
155
- <text className="stat-value">{user.stats.following}</text>
156
- <text className="stat-label">关注中</text>
157
- </view>
158
- </view>
159
- </view>
160
- );
161
- }
162
-
163
- export default definePage({
164
- onShow() {
165
- console.log('页面显示');
166
- },
167
- onHide() {
168
- console.log('页面隐藏');
169
- },
170
- render() {
171
- return <UserProfilePage />;
172
- }
173
- });
174
- ```
175
-
176
- ### index.scss
177
-
178
- ```scss
179
- .profile-container {
180
- padding: 32px;
181
- background-color: #f5f5f5;
182
-
183
- .loading,
184
- .error {
185
- text-align: center;
186
- padding: 40px;
187
- font-size: 28px;
188
- color: #666;
189
- }
190
-
191
- .profile-header {
192
- background-color: #fff;
193
- border-radius: 16px;
194
- padding: 40px;
195
- text-align: center;
196
- margin-bottom: 32px;
197
-
198
- .avatar {
199
- width: 160px;
200
- height: 160px;
201
- border-radius: 80px;
202
- margin-bottom: 24px;
203
- }
204
-
205
- .name {
206
- font-size: 36px;
207
- font-weight: bold;
208
- color: #333;
209
- margin-bottom: 12px;
210
- }
211
-
212
- .email {
213
- font-size: 28px;
214
- color: #666;
215
- margin-bottom: 24px;
216
- }
217
-
218
- .edit-btn {
219
- padding: 16px 48px;
220
- background-color: #1890ff;
221
- color: #fff;
222
- border-radius: 8px;
223
- font-size: 28px;
224
- }
225
- }
226
-
227
- .profile-stats {
228
- display: flex;
229
- justify-content: space-around;
230
- background-color: #fff;
231
- border-radius: 16px;
232
- padding: 32px;
233
-
234
- .stat-item {
235
- text-align: center;
236
-
237
- .stat-value {
238
- font-size: 36px;
239
- font-weight: bold;
240
- color: #333;
241
- margin-bottom: 8px;
242
- }
243
-
244
- .stat-label {
245
- font-size: 24px;
246
- color: #999;
247
- }
248
- }
249
- }
250
- }
251
- ```
252
-
253
- ---
254
-
255
- ## 🎴 Widget 基础示例
256
-
257
- ### 天气卡片
258
-
259
- **文件结构**:
260
- ```
261
- src/widgets/weather-card/
262
- ├── index.tsx # 组件逻辑
263
- └── index.scss # 组件样式
264
- ```
265
-
266
- ### index.tsx
267
-
268
- ```tsx
269
- import { defineWidget, getViewData, useState, useEffect } from '@doubao-apps/framework';
270
- import './index.scss';
271
-
272
- interface WeatherData {
273
- city: string;
274
- temperature: number;
275
- condition: string;
276
- humidity: number;
277
- windSpeed: number;
278
- icon: string;
279
- }
280
-
281
- interface WeatherWidgetData {
282
- city: string;
283
- }
284
-
285
- function WeatherCard({ city }: WeatherWidgetData) {
286
- const [weather, setWeather] = useState<WeatherData | null>(null);
287
- const [loading, setLoading] = useState(true);
288
- const [error, setError] = useState<string | null>(null);
289
-
290
- // 获取天气数据
291
- const fetchWeather = async () => {
292
- try {
293
- setLoading(true);
294
- setError(null);
295
-
296
- // 模拟 API 请求
297
- await new Promise(resolve => setTimeout(resolve, 800));
298
-
299
- const mockData: WeatherData = {
300
- city: city,
301
- temperature: 22,
302
- condition: '晴天',
303
- humidity: 65,
304
- windSpeed: 12,
305
- icon: '☀️'
306
- };
307
-
308
- setWeather(mockData);
309
- } catch (err) {
310
- setError('获取天气失败');
311
- } finally {
312
- setLoading(false);
313
- }
314
- };
315
-
316
- useEffect(() => {
317
- fetchWeather();
318
- }, [city]);
319
-
320
- // 刷新按钮
321
- const handleRefresh = () => {
322
- fetchWeather();
323
- };
324
-
325
- // 渲染
326
- if (loading) {
327
- return (
328
- <view className="weather-card">
329
- <text className="loading">加载中...</text>
330
- </view>
331
- );
332
- }
333
-
334
- if (error || !weather) {
335
- return (
336
- <view className="weather-card">
337
- <text className="error">{error || '暂无数据'}</text>
338
- <button onClick={handleRefresh}>重试</button>
339
- </view>
340
- );
341
- }
342
-
343
- return (
344
- <view className="weather-card">
345
- {/* 头部 */}
346
- <view className="weather-header">
347
- <text className="city">{weather.city}</text>
348
- <button className="refresh-btn" onClick={handleRefresh}>
349
- 刷新
350
- </button>
351
- </view>
352
-
353
- {/* 主要信息 */}
354
- <view className="weather-main">
355
- <text className="icon">{weather.icon}</text>
356
- <view className="temperature-section">
357
- <text className="temperature">{weather.temperature}°C</text>
358
- <text className="condition">{weather.condition}</text>
359
- </view>
360
- </view>
361
-
362
- {/* 详细信息 */}
363
- <view className="weather-details">
364
- <view className="detail-item">
365
- <text className="detail-label">湿度</text>
366
- <text className="detail-value">{weather.humidity}%</text>
367
- </view>
368
- <view className="detail-item">
369
- <text className="detail-label">风速</text>
370
- <text className="detail-value">{weather.windSpeed} km/h</text>
371
- </view>
372
- </view>
373
- </view>
374
- );
375
- }
376
-
377
- export default defineWidget({
378
- onMounted() {
379
- console.log('卡片挂载');
380
- },
381
- onDestroy() {
382
- console.log('卡片销毁');
383
- },
384
- render() {
385
- const viewData = getViewData<WeatherWidgetData>();
386
- return <WeatherCard city={viewData.city} />;
387
- }
388
- });
389
- ```
390
-
391
- ### index.scss
392
-
393
- ```scss
394
- .weather-card {
395
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
396
- border-radius: 16px;
397
- padding: 32px;
398
- color: #fff;
399
-
400
- .loading,
401
- .error {
402
- text-align: center;
403
- padding: 32px;
404
- font-size: 28px;
405
- }
406
-
407
- .weather-header {
408
- display: flex;
409
- justify-content: space-between;
410
- align-items: center;
411
- margin-bottom: 32px;
412
-
413
- .city {
414
- font-size: 32px;
415
- font-weight: bold;
416
- }
417
-
418
- .refresh-btn {
419
- padding: 12px 24px;
420
- background-color: rgba(255, 255, 255, 0.2);
421
- color: #fff;
422
- border-radius: 8px;
423
- font-size: 24px;
424
- }
425
- }
426
-
427
- .weather-main {
428
- display: flex;
429
- align-items: center;
430
- margin-bottom: 32px;
431
-
432
- .icon {
433
- font-size: 120px;
434
- margin-right: 32px;
435
- }
436
-
437
- .temperature-section {
438
- .temperature {
439
- font-size: 72px;
440
- font-weight: bold;
441
- margin-bottom: 8px;
442
- }
443
-
444
- .condition {
445
- font-size: 28px;
446
- opacity: 0.9;
447
- }
448
- }
449
- }
450
-
451
- .weather-details {
452
- display: flex;
453
- justify-content: space-around;
454
- padding-top: 24px;
455
- border-top: 1px solid rgba(255, 255, 255, 0.3);
456
-
457
- .detail-item {
458
- text-align: center;
459
-
460
- .detail-label {
461
- font-size: 24px;
462
- opacity: 0.8;
463
- margin-bottom: 8px;
464
- }
465
-
466
- .detail-value {
467
- font-size: 32px;
468
- font-weight: bold;
469
- }
470
- }
471
- }
472
- }
473
- ```
474
-
475
- ---
476
-
477
- ## 🔑 关键要点
478
-
479
- ### Page 开发要点
480
-
481
- 1. **完整的页面生命周期**
482
- - `onShow()` - 页面显示时调用
483
- - `onHide()` - 页面隐藏时调用
484
- - `onDestroy()` - 页面销毁时调用
485
-
486
- 2. **页面配置(可选 pages)**
487
- - 一级目录不写进 `pages` 也会自动发现,默认 `id` 是目录名
488
- - 需要 `title`、`description`、固定首页或多级目录时再配置
489
- - 多级目录需要显式写 `entry`
490
-
491
- 3. **状态管理**
492
- - 使用 React Hooks(useState, useEffect)
493
- - 处理加载、错误、数据状态
494
-
495
- 4. **用户交互**
496
- - 按钮点击、表单提交
497
- - 页面跳转、数据更新
498
-
499
- ### Widget 开发要点
500
-
501
- 1. **卡片生命周期**
502
- - `onShow()` / `onHide()` - 卡片显示/隐藏
503
- - `onForeground()` / `onBackground()` - 应用前后台切换
504
- - `onMounted()` / `onDestroy()` - 挂载/销毁
505
-
506
- 2. **ViewData 定义**
507
- - 使用 TypeScript 类型定义 `getViewData<T>()` 的 viewData 结构
508
- - 对可选字段和空数据做兜底处理
509
- - 避免直接使用 `any`
510
-
511
- 3. **卡片类型 (boxType)**
512
- - `inbox` - 普通卡片
513
- - `full_box` - 全宽卡片
514
-
515
- 4. **消息交互**
516
- - 接收 AI 传入的数据
517
- - 可以发送消息回 Bot
518
- - 支持卡片内交互
519
-
520
- ---
521
-
522
- ## 📚 延伸阅读
523
-
524
- - **组件开发完整指南** → [../guides/component-development.md](../guides/component-development.md)
525
- - **常用开发模式** → [./common-patterns.md](./common-patterns.md)
526
- - **API 参考** → [../reference/framework-api-quick-ref.md](../reference/framework-api-quick-ref.md)