@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.
- package/dist/421.js +4 -4
- package/dist/cli.js +74 -66
- package/dist/index.d.ts +1 -2
- package/dist/template-empty/README.md +1 -1
- package/dist/template-empty/package.json +2 -2
- package/dist/template-starter/README.md +48 -169
- package/dist/template-starter/package.json +2 -2
- package/dist/template-starter/src/app.config.ts +2 -3
- package/dist/template-starter/src/pages/home/index.scss +38 -172
- package/dist/template-starter/src/pages/home/index.tsx +20 -78
- package/dist/template-starter/src/widgets/hello-world/index.scss +23 -0
- package/dist/template-starter/src/widgets/hello-world/index.tsx +29 -0
- package/package.json +6 -2
- package/dist/template-empty/AGENTS.md +0 -299
- package/dist/template-empty/references/examples/common-patterns.md +0 -589
- package/dist/template-empty/references/examples/component-basics.md +0 -526
- package/dist/template-empty/references/guides/best-practices.md +0 -571
- package/dist/template-empty/references/guides/component-development.md +0 -891
- package/dist/template-empty/references/guides/performance-optimization.md +0 -402
- package/dist/template-empty/references/guides/troubleshooting.md +0 -287
- package/dist/template-empty/references/reference/components-quick-ref.md +0 -103
- package/dist/template-empty/references/reference/framework-api-quick-ref.md +0 -550
- package/dist/template-empty/references/reference/open-api/README.md +0 -8
- package/dist/template-empty/references/reference/open-api.md +0 -11
- package/dist/template-empty/references/rules/dos-and-donts.md +0 -467
- package/dist/template-starter/AGENTS.md +0 -299
- package/dist/template-starter/debug-scene/render-home-page-full.json +0 -6
- package/dist/template-starter/debug-scene/render-home-page.json +0 -5
- package/dist/template-starter/debug-scene/render-react-lynx-page-full.json +0 -6
- package/dist/template-starter/references/examples/common-patterns.md +0 -589
- package/dist/template-starter/references/examples/component-basics.md +0 -526
- package/dist/template-starter/references/guides/best-practices.md +0 -571
- package/dist/template-starter/references/guides/component-development.md +0 -891
- package/dist/template-starter/references/guides/performance-optimization.md +0 -402
- package/dist/template-starter/references/guides/troubleshooting.md +0 -287
- package/dist/template-starter/references/reference/components-quick-ref.md +0 -103
- package/dist/template-starter/references/reference/framework-api-quick-ref.md +0 -550
- package/dist/template-starter/references/reference/open-api/README.md +0 -8
- package/dist/template-starter/references/reference/open-api.md +0 -11
- package/dist/template-starter/references/rules/dos-and-donts.md +0 -467
- package/dist/template-starter/src/pages/applet/index.scss +0 -279
- package/dist/template-starter/src/pages/applet/index.tsx +0 -78
- package/dist/template-starter/src/pages/lynx/index.scss +0 -249
- package/dist/template-starter/src/pages/lynx/index.tsx +0 -78
- package/dist/template-starter/src/pages/react-lynx/index.scss +0 -335
- package/dist/template-starter/src/pages/react-lynx/index.tsx +0 -132
- package/dist/template-starter/src/widgets/weather-card/index.scss +0 -272
- package/dist/template-starter/src/widgets/weather-card/index.tsx +0 -193
|
@@ -1,589 +0,0 @@
|
|
|
1
|
-
# 常用开发模式
|
|
2
|
-
|
|
3
|
-
API 集成、状态管理、页面导航的常用开发模式和最佳实践。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 📋 目录
|
|
8
|
-
|
|
9
|
-
1. [API 集成模式](#api-集成模式)
|
|
10
|
-
2. [状态管理模式](#状态管理模式)
|
|
11
|
-
3. [页面导航模式](#页面导航模式)
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 🌐 API 集成模式
|
|
16
|
-
|
|
17
|
-
### Bridge API 调用
|
|
18
|
-
|
|
19
|
-
使用 Bridge API 访问系统能力(网络请求、存储、设备功能等)。
|
|
20
|
-
|
|
21
|
-
```tsx
|
|
22
|
-
import { useState } from '@doubao-apps/framework';
|
|
23
|
-
import { getLocation, getPhoneNumber, request } from '@doubao-apps/framework/api';
|
|
24
|
-
|
|
25
|
-
function DataFetchExample() {
|
|
26
|
-
const [data, setData] = useState(null);
|
|
27
|
-
const [loading, setLoading] = useState(false);
|
|
28
|
-
const [error, setError] = useState(null);
|
|
29
|
-
|
|
30
|
-
// 1. 网络请求
|
|
31
|
-
const fetchData = async () => {
|
|
32
|
-
try {
|
|
33
|
-
setLoading(true);
|
|
34
|
-
setError(null);
|
|
35
|
-
|
|
36
|
-
const response = await request({
|
|
37
|
-
url: 'https://api.example.com/data',
|
|
38
|
-
method: 'GET',
|
|
39
|
-
header: {
|
|
40
|
-
'Content-Type': 'application/json'
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
setData(response.data);
|
|
45
|
-
} catch (err) {
|
|
46
|
-
setError(err.message);
|
|
47
|
-
} finally {
|
|
48
|
-
setLoading(false);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// 2. 获取手机号(需要用户授权)
|
|
53
|
-
const fetchPhoneNumber = async () => {
|
|
54
|
-
try {
|
|
55
|
-
const result = await getPhoneNumber();
|
|
56
|
-
console.log('手机号信息:', result);
|
|
57
|
-
} catch (err) {
|
|
58
|
-
console.error('获取手机号失败:', err);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
// 3. 获取地理位置
|
|
63
|
-
const fetchLocation = async () => {
|
|
64
|
-
try {
|
|
65
|
-
const location = await getLocation();
|
|
66
|
-
console.log('位置:', location);
|
|
67
|
-
} catch (err) {
|
|
68
|
-
console.error('获取位置失败:', err);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<view>
|
|
74
|
-
<button onClick={fetchData}>获取数据</button>
|
|
75
|
-
<button onClick={fetchPhoneNumber}>获取手机号</button>
|
|
76
|
-
<button onClick={fetchLocation}>获取位置</button>
|
|
77
|
-
{loading && <text>加载中...</text>}
|
|
78
|
-
{error && <text>错误: {error}</text>}
|
|
79
|
-
{data && <text>数据: {JSON.stringify(data)}</text>}
|
|
80
|
-
</view>
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### POST 请求示例
|
|
86
|
-
|
|
87
|
-
```tsx
|
|
88
|
-
const submitForm = async (formData: any) => {
|
|
89
|
-
try {
|
|
90
|
-
const response = await request({
|
|
91
|
-
url: 'https://api.example.com/submit',
|
|
92
|
-
method: 'POST',
|
|
93
|
-
header: {
|
|
94
|
-
'Content-Type': 'application/json'
|
|
95
|
-
},
|
|
96
|
-
data: formData
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
100
|
-
console.log('提交成功');
|
|
101
|
-
}
|
|
102
|
-
} catch (err) {
|
|
103
|
-
console.error('提交失败:', err);
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### 请求拦截和错误处理
|
|
109
|
-
|
|
110
|
-
```tsx
|
|
111
|
-
interface ApiError {
|
|
112
|
-
code: number;
|
|
113
|
-
message: string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function apiRequest<T>(url: string, options: any): Promise<T> {
|
|
117
|
-
try {
|
|
118
|
-
const response = await request({
|
|
119
|
-
url,
|
|
120
|
-
...options
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// 检查响应状态
|
|
124
|
-
if (response.statusCode >= 400) {
|
|
125
|
-
throw {
|
|
126
|
-
code: response.statusCode,
|
|
127
|
-
message: response.data?.message || '请求失败'
|
|
128
|
-
} as ApiError;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return response.data as T;
|
|
132
|
-
} catch (err) {
|
|
133
|
-
// 统一错误处理
|
|
134
|
-
if (err.code === 401) {
|
|
135
|
-
console.error('未授权,请登录');
|
|
136
|
-
} else if (err.code === 404) {
|
|
137
|
-
console.error('资源不存在');
|
|
138
|
-
} else {
|
|
139
|
-
console.error('请求错误:', err.message);
|
|
140
|
-
}
|
|
141
|
-
throw err;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// 使用示例
|
|
146
|
-
async function fetchUserData(userId: string) {
|
|
147
|
-
try {
|
|
148
|
-
const data = await apiRequest<User>(`/api/users/${userId}`, {
|
|
149
|
-
method: 'GET'
|
|
150
|
-
});
|
|
151
|
-
return data;
|
|
152
|
-
} catch (err) {
|
|
153
|
-
// 业务逻辑错误处理
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
## 📊 状态管理模式
|
|
162
|
-
|
|
163
|
-
### 1. 本地状态 (useState)
|
|
164
|
-
|
|
165
|
-
适用于组件内部状态管理。
|
|
166
|
-
|
|
167
|
-
```tsx
|
|
168
|
-
import { useState } from '@doubao-apps/framework';
|
|
169
|
-
|
|
170
|
-
function Counter() {
|
|
171
|
-
const [count, setCount] = useState(0);
|
|
172
|
-
|
|
173
|
-
return (
|
|
174
|
-
<view>
|
|
175
|
-
<text>计数: {count}</text>
|
|
176
|
-
<button onClick={() => setCount(count + 1)}>增加</button>
|
|
177
|
-
<button onClick={() => setCount(count - 1)}>减少</button>
|
|
178
|
-
<button onClick={() => setCount(0)}>重置</button>
|
|
179
|
-
</view>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### 2. 副作用管理 (useEffect)
|
|
185
|
-
|
|
186
|
-
适用于数据获取、订阅、定时器等副作用。
|
|
187
|
-
|
|
188
|
-
```tsx
|
|
189
|
-
import { useState, useEffect } from '@doubao-apps/framework';
|
|
190
|
-
import { request } from '@doubao-apps/framework/api';
|
|
191
|
-
|
|
192
|
-
function DataLoader() {
|
|
193
|
-
const [data, setData] = useState(null);
|
|
194
|
-
|
|
195
|
-
useEffect(() => {
|
|
196
|
-
// 数据获取
|
|
197
|
-
const fetchData = async () => {
|
|
198
|
-
try {
|
|
199
|
-
const response = await request({
|
|
200
|
-
url: '/api/data',
|
|
201
|
-
method: 'GET'
|
|
202
|
-
});
|
|
203
|
-
setData(response.data);
|
|
204
|
-
} catch (error) {
|
|
205
|
-
console.error('获取数据失败:', error);
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
fetchData();
|
|
210
|
-
|
|
211
|
-
// 清理函数
|
|
212
|
-
return () => {
|
|
213
|
-
console.log('组件卸载,清理资源');
|
|
214
|
-
};
|
|
215
|
-
}, []); // 空依赖数组表示只在挂载时执行一次
|
|
216
|
-
|
|
217
|
-
return <view>{data ? <text>{data}</text> : <text>加载中...</text>}</view>;
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### 3. 复杂状态 (useReducer)
|
|
222
|
-
|
|
223
|
-
适用于复杂状态逻辑。
|
|
224
|
-
|
|
225
|
-
```tsx
|
|
226
|
-
import { useReducer } from '@doubao-apps/framework';
|
|
227
|
-
|
|
228
|
-
// 定义状态和动作类型
|
|
229
|
-
interface State {
|
|
230
|
-
count: number;
|
|
231
|
-
step: number;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
type Action =
|
|
235
|
-
| { type: 'increment' }
|
|
236
|
-
| { type: 'decrement' }
|
|
237
|
-
| { type: 'setStep'; step: number }
|
|
238
|
-
| { type: 'reset' };
|
|
239
|
-
|
|
240
|
-
// Reducer 函数
|
|
241
|
-
function reducer(state: State, action: Action): State {
|
|
242
|
-
switch (action.type) {
|
|
243
|
-
case 'increment':
|
|
244
|
-
return { ...state, count: state.count + state.step };
|
|
245
|
-
case 'decrement':
|
|
246
|
-
return { ...state, count: state.count - state.step };
|
|
247
|
-
case 'setStep':
|
|
248
|
-
return { ...state, step: action.step };
|
|
249
|
-
case 'reset':
|
|
250
|
-
return { count: 0, step: 1 };
|
|
251
|
-
default:
|
|
252
|
-
return state;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
function ComplexCounter() {
|
|
257
|
-
const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 });
|
|
258
|
-
|
|
259
|
-
return (
|
|
260
|
-
<view>
|
|
261
|
-
<text>计数: {state.count}</text>
|
|
262
|
-
<text>步长: {state.step}</text>
|
|
263
|
-
<button onClick={() => dispatch({ type: 'increment' })}>增加</button>
|
|
264
|
-
<button onClick={() => dispatch({ type: 'decrement' })}>减少</button>
|
|
265
|
-
<button onClick={() => dispatch({ type: 'setStep', step: 5 })}>
|
|
266
|
-
设置步长为 5
|
|
267
|
-
</button>
|
|
268
|
-
<button onClick={() => dispatch({ type: 'reset' })}>重置</button>
|
|
269
|
-
</view>
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### 4. 跨组件状态共享 (Context)
|
|
275
|
-
|
|
276
|
-
适用于全局或跨组件状态。
|
|
277
|
-
|
|
278
|
-
```tsx
|
|
279
|
-
import { createContext, useContext, useState } from '@doubao-apps/framework';
|
|
280
|
-
|
|
281
|
-
// 1. 创建 Context
|
|
282
|
-
interface ThemeContextValue {
|
|
283
|
-
theme: 'light' | 'dark';
|
|
284
|
-
toggleTheme: () => void;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const ThemeContext = createContext<ThemeContextValue | null>(null);
|
|
288
|
-
|
|
289
|
-
// 2. Provider 组件
|
|
290
|
-
function ThemeProvider({ children }) {
|
|
291
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
292
|
-
|
|
293
|
-
const toggleTheme = () => {
|
|
294
|
-
setTheme(prev => (prev === 'light' ? 'dark' : 'light'));
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
return (
|
|
298
|
-
<ThemeContext.Provider value={{ theme, toggleTheme }}>
|
|
299
|
-
{children}
|
|
300
|
-
</ThemeContext.Provider>
|
|
301
|
-
);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// 3. 使用 Context
|
|
305
|
-
function ThemedButton() {
|
|
306
|
-
const context = useContext(ThemeContext);
|
|
307
|
-
if (!context) throw new Error('必须在 ThemeProvider 内使用');
|
|
308
|
-
|
|
309
|
-
const { theme, toggleTheme } = context;
|
|
310
|
-
|
|
311
|
-
return (
|
|
312
|
-
<button
|
|
313
|
-
className={theme === 'light' ? 'light-button' : 'dark-button'}
|
|
314
|
-
onClick={toggleTheme}
|
|
315
|
-
>
|
|
316
|
-
切换主题
|
|
317
|
-
</button>
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// 4. 应用中使用
|
|
322
|
-
function App() {
|
|
323
|
-
return (
|
|
324
|
-
<ThemeProvider>
|
|
325
|
-
<view>
|
|
326
|
-
<ThemedButton />
|
|
327
|
-
</view>
|
|
328
|
-
</ThemeProvider>
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### 5. 自定义 Hook
|
|
334
|
-
|
|
335
|
-
封装可复用的状态逻辑。
|
|
336
|
-
|
|
337
|
-
```tsx
|
|
338
|
-
import { useState, useEffect } from '@doubao-apps/framework';
|
|
339
|
-
import { request } from '@doubao-apps/framework/api';
|
|
340
|
-
|
|
341
|
-
// 自定义 Hook:数据获取
|
|
342
|
-
function useFetch<T>(url: string) {
|
|
343
|
-
const [data, setData] = useState<T | null>(null);
|
|
344
|
-
const [loading, setLoading] = useState(true);
|
|
345
|
-
const [error, setError] = useState<string | null>(null);
|
|
346
|
-
|
|
347
|
-
useEffect(() => {
|
|
348
|
-
const fetchData = async () => {
|
|
349
|
-
try {
|
|
350
|
-
setLoading(true);
|
|
351
|
-
setError(null);
|
|
352
|
-
const response = await request({ url, method: 'GET' });
|
|
353
|
-
setData(response.data as T);
|
|
354
|
-
} catch (err) {
|
|
355
|
-
setError(err.message);
|
|
356
|
-
} finally {
|
|
357
|
-
setLoading(false);
|
|
358
|
-
}
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
fetchData();
|
|
362
|
-
}, [url]);
|
|
363
|
-
|
|
364
|
-
return { data, loading, error };
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// 使用自定义 Hook
|
|
368
|
-
function UserProfile({ userId }) {
|
|
369
|
-
const { data: user, loading, error } = useFetch<User>(`/api/users/${userId}`);
|
|
370
|
-
|
|
371
|
-
if (loading) return <text>加载中...</text>;
|
|
372
|
-
if (error) return <text>错误: {error}</text>;
|
|
373
|
-
if (!user) return <text>无数据</text>;
|
|
374
|
-
|
|
375
|
-
return (
|
|
376
|
-
<view>
|
|
377
|
-
<text>{user.name}</text>
|
|
378
|
-
<text>{user.email}</text>
|
|
379
|
-
</view>
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
---
|
|
385
|
-
|
|
386
|
-
## 🧭 页面导航模式
|
|
387
|
-
|
|
388
|
-
### 1. 打开新页面
|
|
389
|
-
|
|
390
|
-
```tsx
|
|
391
|
-
import { navigateTo, redirectTo, reLaunch } from '@doubao-apps/framework/api';
|
|
392
|
-
|
|
393
|
-
// 保留当前页面,打开详情页
|
|
394
|
-
function openFullPage() {
|
|
395
|
-
navigateTo({
|
|
396
|
-
url: 'user-profile?userId=12345'
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// 替换当前页面
|
|
401
|
-
function openSettingsPage() {
|
|
402
|
-
redirectTo({
|
|
403
|
-
url: 'settings'
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// 清空页面栈并回到首页
|
|
408
|
-
function relaunchHome() {
|
|
409
|
-
reLaunch({
|
|
410
|
-
url: 'home'
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
这里的 `url` 直接使用目标页面的 `pageId`。显式配置时取 `src/app.config.ts` 中对应 page 的 `id`;不配置时取入口目录名,例如
|
|
416
|
-
`src/pages/detail/index.tsx` 默认为 `detail`。如需传参,可继续拼接 query string。
|
|
417
|
-
|
|
418
|
-
### 2. 页面间传参
|
|
419
|
-
|
|
420
|
-
```tsx
|
|
421
|
-
import { navigateTo } from '@doubao-apps/framework/api';
|
|
422
|
-
|
|
423
|
-
function buildPageUrl(pageId: string, params: Record<string, string | number | boolean>) {
|
|
424
|
-
const query = Object.entries(params)
|
|
425
|
-
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
|
426
|
-
.join('&');
|
|
427
|
-
|
|
428
|
-
return query ? `${pageId}?${query}` : pageId;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// 发送方
|
|
432
|
-
function navigateWithParams() {
|
|
433
|
-
navigateTo({
|
|
434
|
-
url: buildPageUrl('detail-page', {
|
|
435
|
-
id: '123',
|
|
436
|
-
name: '商品名称',
|
|
437
|
-
price: 99.99
|
|
438
|
-
})
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
// 接收方 (detail-page)
|
|
443
|
-
import { getViewData } from '@doubao-apps/framework';
|
|
444
|
-
|
|
445
|
-
interface DetailPageData {
|
|
446
|
-
id: string;
|
|
447
|
-
name: string;
|
|
448
|
-
price: number;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
export default definePage({
|
|
452
|
-
render() {
|
|
453
|
-
// getViewData() 直接返回传入页面的最终对象
|
|
454
|
-
const { id, name, price } = getViewData<DetailPageData>();
|
|
455
|
-
|
|
456
|
-
return (
|
|
457
|
-
<view>
|
|
458
|
-
<text>ID: {id}</text>
|
|
459
|
-
<text>名称: {name}</text>
|
|
460
|
-
<text>价格: {price}</text>
|
|
461
|
-
</view>
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
});
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
### 3. 返回上一页
|
|
468
|
-
|
|
469
|
-
```tsx
|
|
470
|
-
import { navigateBack } from '@doubao-apps/framework/api';
|
|
471
|
-
|
|
472
|
-
function closeCurrentPage() {
|
|
473
|
-
navigateBack();
|
|
474
|
-
}
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
### 4. 页面栈管理
|
|
478
|
-
|
|
479
|
-
```tsx
|
|
480
|
-
import { navigateBack } from '@doubao-apps/framework/api';
|
|
481
|
-
|
|
482
|
-
// 场景 1: 返回上一页
|
|
483
|
-
function goBack() {
|
|
484
|
-
navigateBack();
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// 场景 2: 返回多级页面
|
|
488
|
-
function goBackTwoPages() {
|
|
489
|
-
navigateBack({ delta: 2 });
|
|
490
|
-
}
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
### 5. 页面生命周期导航处理
|
|
494
|
-
|
|
495
|
-
```tsx
|
|
496
|
-
export default definePage({
|
|
497
|
-
onShow() {
|
|
498
|
-
// 页面显示时调用(包括从其他页面返回)
|
|
499
|
-
console.log('页面显示');
|
|
500
|
-
// 可以在这里刷新数据
|
|
501
|
-
},
|
|
502
|
-
onHide() {
|
|
503
|
-
// 页面隐藏时调用
|
|
504
|
-
console.log('页面隐藏');
|
|
505
|
-
// 可以在这里暂停视频、保存草稿等
|
|
506
|
-
},
|
|
507
|
-
onDestroy() {
|
|
508
|
-
// 页面销毁时调用
|
|
509
|
-
console.log('页面销毁');
|
|
510
|
-
// 清理资源、取消订阅等
|
|
511
|
-
},
|
|
512
|
-
render() {
|
|
513
|
-
return <view>页面内容</view>;
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
### 6. 九宫格页面导航
|
|
519
|
-
|
|
520
|
-
```tsx
|
|
521
|
-
import { navigateTo } from '@doubao-apps/framework/api';
|
|
522
|
-
|
|
523
|
-
// 打开九宫格页面
|
|
524
|
-
function openGridPage() {
|
|
525
|
-
navigateTo({
|
|
526
|
-
url: 'app-grid'
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// 九宫格页面定义
|
|
531
|
-
export default definePage({
|
|
532
|
-
render() {
|
|
533
|
-
const apps = [
|
|
534
|
-
{ id: 'app1', name: '应用1', icon: '🎯' },
|
|
535
|
-
{ id: 'app2', name: '应用2', icon: '📱' },
|
|
536
|
-
{ id: 'app3', name: '应用3', icon: '⚡' }
|
|
537
|
-
];
|
|
538
|
-
|
|
539
|
-
return (
|
|
540
|
-
<view className="grid-container">
|
|
541
|
-
{apps.map(app => (
|
|
542
|
-
<view
|
|
543
|
-
key={app.id}
|
|
544
|
-
className="grid-item"
|
|
545
|
-
onClick={() => navigateTo({ url: app.id })}
|
|
546
|
-
>
|
|
547
|
-
<text className="icon">{app.icon}</text>
|
|
548
|
-
<text className="name">{app.name}</text>
|
|
549
|
-
</view>
|
|
550
|
-
))}
|
|
551
|
-
</view>
|
|
552
|
-
);
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
---
|
|
558
|
-
|
|
559
|
-
## 🎯 最佳实践
|
|
560
|
-
|
|
561
|
-
### API 集成
|
|
562
|
-
|
|
563
|
-
1. **统一错误处理** - 封装 API 请求函数,统一处理错误
|
|
564
|
-
2. **请求取消** - 组件卸载时取消未完成的请求
|
|
565
|
-
3. **缓存策略** - 合理使用缓存减少网络请求
|
|
566
|
-
4. **加载状态** - 始终提供加载和错误状态反馈
|
|
567
|
-
|
|
568
|
-
### 状态管理
|
|
569
|
-
|
|
570
|
-
1. **最小化状态** - 只存储必要的状态,能计算的不存储
|
|
571
|
-
2. **状态提升** - 共享状态提升到最近的公共父组件
|
|
572
|
-
3. **避免过度渲染** - 使用 useMemo、useCallback 优化性能
|
|
573
|
-
4. **状态持久化** - 重要状态考虑持久化到本地存储
|
|
574
|
-
|
|
575
|
-
### 页面导航
|
|
576
|
-
|
|
577
|
-
1. **合理的页面层级** - 避免页面栈过深(建议不超过 3-4 层)
|
|
578
|
-
2. **参数验证** - 接收页面参数时进行验证和默认值处理
|
|
579
|
-
3. **返回结果** - 关闭页面时返回必要的结果数据
|
|
580
|
-
4. **生命周期管理** - 合理使用生命周期钩子管理资源
|
|
581
|
-
|
|
582
|
-
---
|
|
583
|
-
|
|
584
|
-
## 📚 延伸阅读
|
|
585
|
-
|
|
586
|
-
- **组件基础** → [./component-basics.md](./component-basics.md)
|
|
587
|
-
- **组件开发完整指南** → [../guides/component-development.md](../guides/component-development.md)
|
|
588
|
-
- **API 参考** → [../reference/framework-api-quick-ref.md](../reference/framework-api-quick-ref.md)
|
|
589
|
-
- **最佳实践** → [../guides/best-practices.md](../guides/best-practices.md)
|