@doubao-apps/create 0.0.26 → 0.0.27
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/36.js +4 -4
- package/dist/template-empty/.ai/examples/common-patterns.md +53 -43
- package/dist/template-empty/.ai/examples/component-basics.md +0 -17
- package/dist/template-empty/.ai/guides/component-development.md +96 -214
- package/dist/template-empty/.ai/guides/system-prompt.md +14 -14
- package/dist/template-empty/.ai/reference/framework-api-quick-ref.md +46 -85
- package/dist/template-empty/.ai/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +13 -13
- package/dist/template-empty/.ai/reference/open-api/{02-storage.md → 02-/345/255/230/345/202/250.md} +13 -21
- package/dist/template-empty/.ai/reference/open-api/{03-router.md → 03-/350/267/257/347/224/261.md} +9 -9
- package/dist/{template-starter/.ai/reference/open-api/04-ui- → template-empty/.ai/reference/open-api/04-/347/225/214/351/235/242-}/344/272/244/344/272/222.md +12 -12
- package/dist/template-empty/.ai/reference/open-api/05-/347/225/214/351/235/242-/350/276/223/345/205/245.md +42 -0
- package/dist/template-empty/.ai/reference/open-api/06-/347/275/221/347/273/234.md +148 -0
- package/dist/template-empty/.ai/reference/open-api/{07-media.md → 07-/345/252/222/344/275/223.md} +8 -8
- package/dist/template-empty/.ai/reference/open-api/{08-open- → 08-/345/274/200/346/224/276/350/203/275/345/212/233-}/344/270/232/345/212/241/350/203/275/345/212/233.md +83 -14
- package/dist/{template-starter/.ai/reference/open-api/09-device-bluetooth.md → template-empty/.ai/reference/open-api/09-/350/256/276/345/244/207-/350/223/235/347/211/231.md} +22 -46
- package/dist/{template-starter/.ai/reference/open-api/10-device-wi-fi.md → template-empty/.ai/reference/open-api/10-/350/256/276/345/244/207-wi-fi.md} +9 -9
- package/dist/template-empty/.ai/reference/open-api/11-/350/256/276/345/244/207-/345/212/240/351/200/237/345/272/246/350/256/241.md +104 -0
- package/dist/template-empty/.ai/reference/open-api/12-/350/256/276/345/244/207-ibeacon.md +148 -0
- package/dist/template-empty/.ai/reference/open-api/13-/350/256/276/345/244/207-/347/275/227/347/233/230.md +82 -0
- package/dist/template-empty/.ai/reference/open-api/14-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +70 -0
- package/dist/template-empty/.ai/reference/open-api/15-/350/256/276/345/244/207-/351/231/200/350/236/272/344/273/252.md +104 -0
- package/dist/template-empty/.ai/reference/open-api/16-ui-/350/276/223/345/205/245.md +65 -0
- package/dist/template-empty/.ai/reference/open-api/17-/350/256/276/345/244/207-/347/275/221/347/273/234.md +164 -0
- package/dist/template-empty/.ai/reference/open-api/18-/350/256/276/345/244/207-/347/237/255/344/277/241.md +62 -0
- package/dist/template-empty/.ai/reference/open-api/19-/350/256/276/345/244/207-/346/227/240/351/232/234/347/242/215.md +43 -0
- package/dist/template-empty/.ai/reference/open-api/20-/350/256/276/345/244/207-/347/224/265/346/261/240.md +83 -0
- package/dist/template-empty/.ai/reference/open-api/21-/350/256/276/345/244/207-/346/227/245/345/216/206.md +215 -0
- package/dist/template-empty/.ai/reference/open-api/22-/350/256/276/345/244/207-/345/211/252/350/264/264/346/235/277.md +70 -0
- package/dist/template-empty/.ai/reference/open-api/23-/350/256/276/345/244/207-/350/201/224/347/263/273/344/272/272.md +270 -0
- package/dist/template-empty/.ai/reference/open-api/24-/350/256/276/345/244/207-/345/212/240/345/257/206.md +56 -0
- package/dist/template-empty/.ai/reference/open-api/25-/350/256/276/345/244/207-/347/224/265/350/257/235.md +41 -0
- package/dist/template-empty/.ai/reference/open-api/26-/350/256/276/345/244/207-/346/211/253/347/240/201.md +100 -0
- package/dist/template-empty/.ai/reference/open-api/27-/350/256/276/345/244/207-/345/261/217/345/271/225.md +173 -0
- package/dist/template-empty/.ai/reference/open-api/28-/350/256/276/345/244/207-/351/234/207/345/212/250.md +66 -0
- package/dist/template-empty/.ai/reference/open-api/README.md +27 -11
- package/dist/template-empty/.ai/reference/open-api.md +275 -8
- package/dist/template-empty/.ai/rules/dos-and-donts.md +50 -37
- package/dist/template-empty/AGENTS.md +54 -31
- package/dist/template-empty/README.md +57 -10
- package/dist/template-empty/package.json +2 -2
- package/dist/template-empty/src/app.config.ts +6 -0
- package/dist/template-empty/src/app.ts +0 -6
- package/dist/template-empty/tsconfig.json +2 -0
- package/dist/template-starter/.ai/examples/common-patterns.md +53 -43
- package/dist/template-starter/.ai/examples/component-basics.md +0 -17
- package/dist/template-starter/.ai/guides/component-development.md +96 -214
- package/dist/template-starter/.ai/guides/system-prompt.md +14 -14
- package/dist/template-starter/.ai/reference/framework-api-quick-ref.md +46 -85
- package/dist/template-starter/.ai/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +13 -13
- package/dist/template-starter/.ai/reference/open-api/{02-storage.md → 02-/345/255/230/345/202/250.md} +13 -21
- package/dist/template-starter/.ai/reference/open-api/{03-router.md → 03-/350/267/257/347/224/261.md} +9 -9
- package/dist/{template-empty/.ai/reference/open-api/04-ui- → template-starter/.ai/reference/open-api/04-/347/225/214/351/235/242-}/344/272/244/344/272/222.md +12 -12
- package/dist/template-starter/.ai/reference/open-api/05-/347/225/214/351/235/242-/350/276/223/345/205/245.md +42 -0
- package/dist/template-starter/.ai/reference/open-api/06-/347/275/221/347/273/234.md +148 -0
- package/dist/template-starter/.ai/reference/open-api/{07-media.md → 07-/345/252/222/344/275/223.md} +8 -8
- package/dist/template-starter/.ai/reference/open-api/{08-open- → 08-/345/274/200/346/224/276/350/203/275/345/212/233-}/344/270/232/345/212/241/350/203/275/345/212/233.md +83 -14
- package/dist/{template-empty/.ai/reference/open-api/09-device-bluetooth.md → template-starter/.ai/reference/open-api/09-/350/256/276/345/244/207-/350/223/235/347/211/231.md} +22 -46
- package/dist/{template-empty/.ai/reference/open-api/10-device-wi-fi.md → template-starter/.ai/reference/open-api/10-/350/256/276/345/244/207-wi-fi.md} +9 -9
- package/dist/template-starter/.ai/reference/open-api/11-/350/256/276/345/244/207-/345/212/240/351/200/237/345/272/246/350/256/241.md +104 -0
- package/dist/template-starter/.ai/reference/open-api/12-/350/256/276/345/244/207-ibeacon.md +148 -0
- package/dist/template-starter/.ai/reference/open-api/13-/350/256/276/345/244/207-/347/275/227/347/233/230.md +82 -0
- package/dist/template-starter/.ai/reference/open-api/14-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +70 -0
- package/dist/template-starter/.ai/reference/open-api/15-/350/256/276/345/244/207-/351/231/200/350/236/272/344/273/252.md +104 -0
- package/dist/template-starter/.ai/reference/open-api/16-ui-/350/276/223/345/205/245.md +65 -0
- package/dist/template-starter/.ai/reference/open-api/17-/350/256/276/345/244/207-/347/275/221/347/273/234.md +164 -0
- package/dist/template-starter/.ai/reference/open-api/18-/350/256/276/345/244/207-/347/237/255/344/277/241.md +62 -0
- package/dist/template-starter/.ai/reference/open-api/19-/350/256/276/345/244/207-/346/227/240/351/232/234/347/242/215.md +43 -0
- package/dist/template-starter/.ai/reference/open-api/20-/350/256/276/345/244/207-/347/224/265/346/261/240.md +83 -0
- package/dist/template-starter/.ai/reference/open-api/21-/350/256/276/345/244/207-/346/227/245/345/216/206.md +215 -0
- package/dist/template-starter/.ai/reference/open-api/22-/350/256/276/345/244/207-/345/211/252/350/264/264/346/235/277.md +70 -0
- package/dist/template-starter/.ai/reference/open-api/23-/350/256/276/345/244/207-/350/201/224/347/263/273/344/272/272.md +270 -0
- package/dist/template-starter/.ai/reference/open-api/24-/350/256/276/345/244/207-/345/212/240/345/257/206.md +56 -0
- package/dist/template-starter/.ai/reference/open-api/25-/350/256/276/345/244/207-/347/224/265/350/257/235.md +41 -0
- package/dist/template-starter/.ai/reference/open-api/26-/350/256/276/345/244/207-/346/211/253/347/240/201.md +100 -0
- package/dist/template-starter/.ai/reference/open-api/27-/350/256/276/345/244/207-/345/261/217/345/271/225.md +173 -0
- package/dist/template-starter/.ai/reference/open-api/28-/350/256/276/345/244/207-/351/234/207/345/212/250.md +66 -0
- package/dist/template-starter/.ai/reference/open-api/README.md +27 -11
- package/dist/template-starter/.ai/reference/open-api.md +275 -8
- package/dist/template-starter/.ai/rules/dos-and-donts.md +50 -37
- package/dist/template-starter/AGENTS.md +54 -31
- package/dist/template-starter/README.md +6 -1
- package/dist/template-starter/package.json +2 -2
- package/dist/template-starter/src/app.config.ts +35 -0
- package/dist/template-starter/src/app.ts +0 -6
- package/dist/template-starter/src/pages/applet/index.tsx +0 -5
- package/dist/template-starter/src/pages/home/index.tsx +0 -5
- package/dist/template-starter/src/pages/lynx/index.tsx +0 -4
- package/dist/template-starter/src/pages/react-lynx/index.tsx +0 -5
- package/dist/template-starter/src/widgets/weather-card/index.tsx +0 -4
- package/dist/template-starter/tsconfig.json +2 -0
- package/package.json +1 -1
- package/dist/template-empty/.ai/reference/open-api/05-ui-/350/276/223/345/205/245.md +0 -95
- package/dist/template-empty/.ai/reference/open-api/06-network.md +0 -298
- package/dist/template-empty/.ai/reference/open-api/11-device-/344/274/240/346/204/237/345/231/250.md +0 -372
- package/dist/template-empty/.ai/reference/open-api/12-device-/346/234/254/345/234/260/350/203/275/345/212/233.md +0 -1005
- package/dist/template-starter/.ai/reference/open-api/05-ui-/350/276/223/345/205/245.md +0 -95
- package/dist/template-starter/.ai/reference/open-api/06-network.md +0 -298
- package/dist/template-starter/.ai/reference/open-api/11-device-/344/274/240/346/204/237/345/231/250.md +0 -372
- package/dist/template-starter/.ai/reference/open-api/12-device-/346/234/254/345/234/260/350/203/275/345/212/233.md +0 -1005
package/dist/36.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import"node:module";import e from"node:path";import t,{promises as r}from"node:fs";import{execFileSync as a}from"node:child_process";import{fileURLToPath as o}from"node:url";let i=e.join("src","app.ts");function
|
|
2
|
-
`}return"README.md"===e||"AGENTS.md"===e?
|
|
3
|
-
`)}let
|
|
4
|
-
`)}async function
|
|
1
|
+
import"node:module";import e from"node:path";import t,{promises as r}from"node:fs";import{execFileSync as a}from"node:child_process";import{fileURLToPath as o}from"node:url";let i=e.join("src","app.config.ts"),n=e.join("src","app.ts");function s(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}async function c(t,a,o=""){for(let c of[i,n].map(r=>e.join(t,r))){let e;try{e=await r.readFile(c,"utf8")}catch(e){if(e?.code==="ENOENT")continue;throw e}let t=e.replace("<%= appId %>",s(a)).replace("<%= name %>",s(o));t!==e&&await r.writeFile(c,t,"utf8")}}let l=new Set(["node_modules","dist",".git"]);async function p(t,a,o={}){let{includeAI:i=!0}=o,n=async(t,a)=>{for(let o of(await r.mkdir(a,{recursive:!0}),await r.readdir(t,{withFileTypes:!0}))){let s=e.join(t,o.name),c=e.join(a,o.name);if(o.isDirectory()){if(l.has(o.name)||".ai"===o.name&&!i)continue;await n(s,c)}else{if("AGENTS.md"===o.name&&!i)continue;await r.copyFile(s,c)}}};await n(t,a)}let d=new Set([".js",".cjs",".mjs",".ts",".tsx",".jsx",".json",".md",".txt",".scss",".css",".less",".html",".yml",".yaml"]),u=[["@byted-doubao-apps/framework","@doubao-apps/framework"],["@byted-doubao-apps/kit","@doubao-apps/kit"],["@byted-doubao-apps/ai","@doubao-apps/ai"],["@byted-doubao-apps/create","@doubao-apps/create"],["@byted-doubao-apps/taro-runtime","@doubao-apps/taro-runtime"]],f=["doubao.config.ts"],m=["@byted-doubao-apps/deploy","@doubao-apps/deploy"],y=["deploy"],w=["pnpm run deploy","doubao.config.ts","部署到豆包平台"];function h(e){let t=e;for(let[e,r]of u)t=t.replace(RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),r);return t}async function j(t,a){for(let i of(await r.readdir(t,{withFileTypes:!0}))){var o;let n=e.join(t,i.name);if(function(e){return f.some(t=>t===e)}(i.name)){await r.rm(n,{recursive:!0,force:!0});continue}if(i.isDirectory()){await j(n,a);continue}if(o=i.name,!d.has(e.extname(o))&&"package.json"!==o&&"tsconfig.json"!==o)continue;let s=await r.readFile(n,"utf-8");await r.writeFile(n,function(e,t,r){if("package.json"===e){let e=JSON.parse(h(t));if(e.scripts&&"object"==typeof e.scripts){for(let t of y)delete e.scripts[t];0===Object.keys(e.scripts).length&&delete e.scripts}for(let t of["dependencies","devDependencies","peerDependencies"])if(e[t]&&"object"==typeof e[t]){for(let a of Object.keys(e[t]))m.some(e=>e===a)?delete e[t][a]:a.startsWith("@doubao-apps/")&&(e[t][a]=`^${r}`);0===Object.keys(e[t]).length&&delete e[t]}return`${JSON.stringify(e,null,2)}
|
|
2
|
+
`}return"README.md"===e||"AGENTS.md"===e?h(t).split("\n").filter(e=>!w.some(t=>e.includes(t))).join("\n"):h(t)}(i.name,s,a))}}function b(e){return e?/[<>:"|?*\x00-\x1F]/.test(e)?{valid:!1,error:"Project name contains invalid characters"}:[".",".."].includes(e)?{valid:!1,error:"Project name is reserved"}:{valid:!0}:{valid:!1,error:"Project name is required"}}function g(e){return e.trim().toLowerCase().replace(/\s+/g,"-").replace(/^[._]/,"").replace(/[^a-z0-9-~._]+/g,"-")}async function E(r,a){let o=e.join(r,"package.json");if(!t.existsSync(o))throw Error("package.json not found in template");let i=JSON.parse(t.readFileSync(o,"utf-8"));i.name=a,t.writeFileSync(o,`${JSON.stringify(i,null,2)}
|
|
3
|
+
`)}let N=["starter","empty"],v=[{value:"starter",label:"Starter (default)",hint:"Starter template with example pages"},{value:"empty",label:"Empty",hint:"Minimal template without example pages"}];function S(e){return N.includes(e)}let $=o(import.meta.url),T=e.dirname($),O={".gitignore":["dist","node_modules",".DS_Store"]};async function k(t){for(let[a,o]of Object.entries(O))await r.writeFile(e.join(t,a),`${o.join("\n")}
|
|
4
|
+
`)}async function F(){let t=e.resolve(T,"..","package.json");return JSON.parse(await r.readFile(t,"utf-8")).version??"0.0.1"}async function x(t){let o=e.join(t,".git");if(!await r.stat(o).then(e=>e.isDirectory()).catch(e=>{if(e?.code==="ENOENT")return!1;throw e}))try{a("git",["init"],{cwd:t,stdio:"ignore"})}catch(e){if(e?.code==="ENOENT")return;throw Error(`Failed to initialize git repository: ${t}`,{cause:e})}}async function P({template:t,projectDir:a,public:o=!0,includeAI:i,appId:n,name:s,packageName:l,overwrite:d}){if(!e.isAbsolute(a))throw Error(`Project directory must be an absolute path: ${a}`);if(!S(t))throw Error(`Invalid template: ${t}. Valid options: ${N.join(", ")}`);let u=e.resolve(T,`template-${t}`);try{if(!(await r.stat(u)).isDirectory())throw Error(`Template path is not a directory: ${u}`)}catch(e){if(e?.code==="ENOENT")throw Error(`Template directory not found: ${u}`,{cause:e});throw Error(`Unable to access template directory: ${u}`,{cause:e})}if(await r.stat(a).then(e=>{if(!e.isDirectory())throw Error(`Project path is not a directory: ${a}`);return!0}).catch(e=>{if(e?.code==="ENOENT")return!1;throw Error(`Unable to access project directory: ${a}`,{cause:e})})){if((await r.readdir(a)).length>0&&!d)throw Error(`Project directory is not empty: ${a}`)}else await r.mkdir(a,{recursive:!0});await p(u,a,{includeAI:i}),o&&await j(a,await F()),await k(a),await x(a);let f=l??g(e.basename(a));await E(a,f),await c(a,n??`com.doubao.${f}`,s??"")}export{N as TEMPLATES,v as TEMPLATE_CHOICES,P as create,g as formatProjectName,S as isValidTemplate,t as node_fs,e as node_path,b as validateProjectName};
|
|
5
5
|
//# sourceMappingURL=36.js.map
|
|
@@ -388,62 +388,73 @@ function UserProfile({ userId }) {
|
|
|
388
388
|
### 1. 打开新页面
|
|
389
389
|
|
|
390
390
|
```tsx
|
|
391
|
-
import {
|
|
391
|
+
import { navigateTo, redirectTo, reLaunch } from '@doubao-apps/framework/api';
|
|
392
392
|
|
|
393
|
-
//
|
|
393
|
+
// 保留当前页面,打开详情页
|
|
394
394
|
function openFullPage() {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
pageData: JSON.stringify({ userId: '12345' }),
|
|
398
|
-
context: {},
|
|
399
|
-
pageSettings: {
|
|
400
|
-
title: '用户资料'
|
|
401
|
-
}
|
|
395
|
+
navigateTo({
|
|
396
|
+
url: 'user-profile?userId=12345'
|
|
402
397
|
});
|
|
403
398
|
}
|
|
404
399
|
|
|
405
|
-
//
|
|
406
|
-
function
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
400
|
+
// 替换当前页面
|
|
401
|
+
function openSettingsPage() {
|
|
402
|
+
redirectTo({
|
|
403
|
+
url: 'settings'
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// 清空页面栈并回到首页
|
|
408
|
+
function relaunchHome() {
|
|
409
|
+
reLaunch({
|
|
410
|
+
url: 'home'
|
|
414
411
|
});
|
|
415
412
|
}
|
|
416
413
|
```
|
|
417
414
|
|
|
415
|
+
这里的 `url` 直接使用目标页面的 `pageId`,与页面的 `aiMeta.id` 一致;如需传参,可继续拼接 query string。
|
|
416
|
+
|
|
418
417
|
### 2. 页面间传参
|
|
419
418
|
|
|
420
419
|
```tsx
|
|
420
|
+
import { navigateTo } from '@doubao-apps/framework/api';
|
|
421
|
+
|
|
422
|
+
function buildPageUrl(pageId: string, params: Record<string, string | number | boolean>) {
|
|
423
|
+
const query = Object.entries(params)
|
|
424
|
+
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
|
425
|
+
.join('&');
|
|
426
|
+
|
|
427
|
+
return query ? `${pageId}?${query}` : pageId;
|
|
428
|
+
}
|
|
429
|
+
|
|
421
430
|
// 发送方
|
|
422
431
|
function navigateWithParams() {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
pageData: JSON.stringify({
|
|
432
|
+
navigateTo({
|
|
433
|
+
url: buildPageUrl('detail-page', {
|
|
426
434
|
id: '123',
|
|
427
435
|
name: '商品名称',
|
|
428
436
|
price: 99.99
|
|
429
|
-
})
|
|
430
|
-
context: {}
|
|
437
|
+
})
|
|
431
438
|
});
|
|
432
439
|
}
|
|
433
440
|
|
|
434
441
|
// 接收方 (detail-page)
|
|
435
442
|
import { getViewData } from '@doubao-apps/framework';
|
|
436
443
|
|
|
444
|
+
interface DetailPageInput {
|
|
445
|
+
id: string;
|
|
446
|
+
name: string;
|
|
447
|
+
price: number;
|
|
448
|
+
}
|
|
449
|
+
|
|
437
450
|
export default definePage({
|
|
438
451
|
aiMeta: {
|
|
439
452
|
id: 'detail-page',
|
|
440
453
|
title: '详情页'
|
|
441
454
|
},
|
|
442
455
|
render() {
|
|
443
|
-
//
|
|
444
|
-
const
|
|
445
|
-
const params = JSON.parse(viewData.pageData || '{}');
|
|
446
|
-
const { id, name, price } = params;
|
|
456
|
+
// getViewData() 直接返回传入页面的最终对象
|
|
457
|
+
const { id, name, price } = getViewData<DetailPageInput>();
|
|
447
458
|
|
|
448
459
|
return (
|
|
449
460
|
<view>
|
|
@@ -456,24 +467,29 @@ export default definePage({
|
|
|
456
467
|
});
|
|
457
468
|
```
|
|
458
469
|
|
|
459
|
-
### 3.
|
|
470
|
+
### 3. 返回上一页
|
|
460
471
|
|
|
461
472
|
```tsx
|
|
462
|
-
import {
|
|
473
|
+
import { navigateBack } from '@doubao-apps/framework/api';
|
|
463
474
|
|
|
464
475
|
function closeCurrentPage() {
|
|
465
|
-
|
|
476
|
+
navigateBack();
|
|
466
477
|
}
|
|
467
478
|
```
|
|
468
479
|
|
|
469
480
|
### 4. 页面栈管理
|
|
470
481
|
|
|
471
482
|
```tsx
|
|
472
|
-
import {
|
|
483
|
+
import { navigateBack } from '@doubao-apps/framework/api';
|
|
473
484
|
|
|
474
485
|
// 场景 1: 返回上一页
|
|
475
486
|
function goBack() {
|
|
476
|
-
|
|
487
|
+
navigateBack();
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// 场景 2: 返回多级页面
|
|
491
|
+
function goBackTwoPages() {
|
|
492
|
+
navigateBack({ delta: 2 });
|
|
477
493
|
}
|
|
478
494
|
```
|
|
479
495
|
|
|
@@ -509,13 +525,12 @@ export default definePage({
|
|
|
509
525
|
### 6. 九宫格页面导航
|
|
510
526
|
|
|
511
527
|
```tsx
|
|
528
|
+
import { navigateTo } from '@doubao-apps/framework/api';
|
|
529
|
+
|
|
512
530
|
// 打开九宫格页面
|
|
513
531
|
function openGridPage() {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
pageSettings: {
|
|
517
|
-
title: '应用中心'
|
|
518
|
-
}
|
|
532
|
+
navigateTo({
|
|
533
|
+
url: 'app-grid'
|
|
519
534
|
});
|
|
520
535
|
}
|
|
521
536
|
|
|
@@ -538,12 +553,7 @@ export default definePage({
|
|
|
538
553
|
<view
|
|
539
554
|
key={app.id}
|
|
540
555
|
className="grid-item"
|
|
541
|
-
onClick={() =>
|
|
542
|
-
openPage({
|
|
543
|
-
pageId: app.id,
|
|
544
|
-
context: {}
|
|
545
|
-
})
|
|
546
|
-
}
|
|
556
|
+
onClick={() => navigateTo({ url: app.id })}
|
|
547
557
|
>
|
|
548
558
|
<text className="icon">{app.icon}</text>
|
|
549
559
|
<text className="name">{app.name}</text>
|
|
@@ -358,23 +358,6 @@ function WeatherCard({ city }: WeatherWidgetInput) {
|
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
export default defineWidget({
|
|
361
|
-
aiMeta: {
|
|
362
|
-
id: 'weather-card',
|
|
363
|
-
name: '天气卡片',
|
|
364
|
-
description: '显示指定城市的天气信息',
|
|
365
|
-
boxType: 'inbox',
|
|
366
|
-
input: {
|
|
367
|
-
type: 'object',
|
|
368
|
-
properties: {
|
|
369
|
-
city: {
|
|
370
|
-
type: 'string',
|
|
371
|
-
title: '城市名称',
|
|
372
|
-
description: '要查询天气的城市'
|
|
373
|
-
}
|
|
374
|
-
},
|
|
375
|
-
required: ['city']
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
361
|
onMounted() {
|
|
379
362
|
console.log('卡片挂载');
|
|
380
363
|
},
|
|
@@ -124,45 +124,31 @@ export default definePage({
|
|
|
124
124
|
});
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
###
|
|
127
|
+
### 页面导航
|
|
128
128
|
|
|
129
129
|
```tsx
|
|
130
|
-
import {
|
|
131
|
-
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
mode: 'full', // 或省略此参数,默认为 'full'
|
|
136
|
-
pageData: JSON.stringify({ userId: '123' }),
|
|
137
|
-
context: {},
|
|
138
|
-
pageSettings: {
|
|
139
|
-
title: '页面标题'
|
|
140
|
-
}
|
|
130
|
+
import { navigateTo, redirectTo, reLaunch } from '@doubao-apps/framework/api';
|
|
131
|
+
|
|
132
|
+
// 保留当前页面,打开新页面
|
|
133
|
+
navigateTo({
|
|
134
|
+
url: 'user-detail?userId=123&tab=profile'
|
|
141
135
|
});
|
|
142
136
|
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
mode: 'popup',
|
|
147
|
-
context: {},
|
|
148
|
-
pageSettings: {
|
|
149
|
-
title: '设置',
|
|
150
|
-
heightPercent: 60 // 高度百分比
|
|
151
|
-
}
|
|
137
|
+
// 替换当前页面
|
|
138
|
+
redirectTo({
|
|
139
|
+
url: 'settings'
|
|
152
140
|
});
|
|
153
141
|
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
mode: 'floating',
|
|
158
|
-
context: {},
|
|
159
|
-
pageSettings: {
|
|
160
|
-
width: 300,
|
|
161
|
-
height: 200
|
|
162
|
-
}
|
|
142
|
+
// 关闭所有页面并回到首页
|
|
143
|
+
reLaunch({
|
|
144
|
+
url: 'home'
|
|
163
145
|
});
|
|
164
146
|
```
|
|
165
147
|
|
|
148
|
+
`url` 在常规页面跳转里填写页面的 `pageId`,与该页面的 `aiMeta.id` 一致;需要传参时可直接在后面拼接 query string。
|
|
149
|
+
|
|
150
|
+
页面内可继续通过 `getViewData<PageInput>()` 读取 URL 中传入的参数。
|
|
151
|
+
|
|
166
152
|
### 常用模式
|
|
167
153
|
|
|
168
154
|
**1. 数据加载**
|
|
@@ -207,7 +193,7 @@ function MyPage({ userId }: { userId: string }) {
|
|
|
207
193
|
|
|
208
194
|
```tsx
|
|
209
195
|
import { useState } from '@doubao-apps/framework';
|
|
210
|
-
import {
|
|
196
|
+
import { navigateBack, request, showToast } from '@doubao-apps/framework/api';
|
|
211
197
|
|
|
212
198
|
function FormPage() {
|
|
213
199
|
const [formData, setFormData] = useState({
|
|
@@ -225,7 +211,7 @@ function FormPage() {
|
|
|
225
211
|
data: formData
|
|
226
212
|
});
|
|
227
213
|
showToast({ message: '提交成功' });
|
|
228
|
-
|
|
214
|
+
navigateBack(); // 返回上一页
|
|
229
215
|
} catch (err) {
|
|
230
216
|
showToast({ message: '提交失败' });
|
|
231
217
|
} finally {
|
|
@@ -257,40 +243,38 @@ function FormPage() {
|
|
|
257
243
|
|
|
258
244
|
## 🎴 Widget 开发指南
|
|
259
245
|
|
|
246
|
+
### Metadata 配置
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
import { defineAppConfig } from '@doubao-apps/kit';
|
|
250
|
+
|
|
251
|
+
export default defineAppConfig({
|
|
252
|
+
widgets: {
|
|
253
|
+
'widgets/my-widget': {
|
|
254
|
+
id: 'my-widget', // 卡片唯一标识
|
|
255
|
+
name: '我的卡片', // 卡片名称
|
|
256
|
+
description: '卡片功能描述', // 卡片描述
|
|
257
|
+
boxType: 'inbox', // 卡片类型: inbox | full_box
|
|
258
|
+
border: true,
|
|
259
|
+
keywords: ['demo', 'widget'],
|
|
260
|
+
titleType: 'normal'
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
260
266
|
### 基本结构
|
|
261
267
|
|
|
262
268
|
```tsx
|
|
263
|
-
import { defineWidget, getViewData
|
|
269
|
+
import { defineWidget, getViewData } from '@doubao-apps/framework';
|
|
264
270
|
import './index.scss';
|
|
265
271
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
name: '我的卡片', // 卡片名称
|
|
271
|
-
description: '卡片功能描述', // 卡片描述
|
|
272
|
-
boxType: 'inbox', // 卡片类型: inbox | full_box
|
|
273
|
-
|
|
274
|
-
// 2. 输入数据 Schema(JSON Schema 格式)
|
|
275
|
-
input: {
|
|
276
|
-
type: 'object',
|
|
277
|
-
properties: {
|
|
278
|
-
title: {
|
|
279
|
-
type: 'string',
|
|
280
|
-
title: '标题',
|
|
281
|
-
description: '卡片标题文本'
|
|
282
|
-
},
|
|
283
|
-
content: {
|
|
284
|
-
type: 'string',
|
|
285
|
-
title: '内容',
|
|
286
|
-
description: '卡片内容文本'
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
required: ['title'] // 必填字段
|
|
290
|
-
}
|
|
291
|
-
},
|
|
272
|
+
interface MyWidgetData {
|
|
273
|
+
title: string;
|
|
274
|
+
content?: string;
|
|
275
|
+
}
|
|
292
276
|
|
|
293
|
-
|
|
277
|
+
export default defineWidget({
|
|
294
278
|
onShow() {
|
|
295
279
|
console.log('卡片显示');
|
|
296
280
|
},
|
|
@@ -316,10 +300,8 @@ export default defineWidget({
|
|
|
316
300
|
console.log('卡片销毁');
|
|
317
301
|
},
|
|
318
302
|
|
|
319
|
-
// 4. 渲染函数
|
|
320
303
|
render() {
|
|
321
|
-
const input = getViewData();
|
|
322
|
-
|
|
304
|
+
const input = getViewData<MyWidgetData>();
|
|
323
305
|
return <MyWidgetComponent {...input} />;
|
|
324
306
|
}
|
|
325
307
|
});
|
|
@@ -336,23 +318,26 @@ export default defineWidget({
|
|
|
336
318
|
- 不需要占用整行宽度,希望保持对话流的紧凑阅读体验
|
|
337
319
|
- 交互以按钮、简单表单项为主
|
|
338
320
|
|
|
321
|
+
```ts
|
|
322
|
+
// src/app.config.ts
|
|
323
|
+
import { defineAppConfig } from '@doubao-apps/kit';
|
|
324
|
+
|
|
325
|
+
export default defineAppConfig({
|
|
326
|
+
widgets: {
|
|
327
|
+
'widgets/info-card': {
|
|
328
|
+
id: 'info-card',
|
|
329
|
+
name: '信息卡片',
|
|
330
|
+
boxType: 'inbox'
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
339
336
|
```tsx
|
|
340
337
|
export default defineWidget({
|
|
341
|
-
aiMeta: {
|
|
342
|
-
id: 'info-card',
|
|
343
|
-
name: '信息卡片',
|
|
344
|
-
boxType: 'inbox',
|
|
345
|
-
input: {
|
|
346
|
-
type: 'object',
|
|
347
|
-
properties: {
|
|
348
|
-
title: { type: 'string', title: '标题' },
|
|
349
|
-
content: { type: 'string', title: '内容' }
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
},
|
|
353
338
|
render() {
|
|
354
339
|
const input = getViewData<{ title: string; content: string }>();
|
|
355
|
-
|
|
340
|
+
|
|
356
341
|
return (
|
|
357
342
|
<view className="info-card">
|
|
358
343
|
<text className="title">{input.title}</text>
|
|
@@ -367,20 +352,23 @@ export default defineWidget({
|
|
|
367
352
|
|
|
368
353
|
适用于需要更大展示空间的卡片(例如图表、图片墙、复杂表单等)。
|
|
369
354
|
|
|
355
|
+
```ts
|
|
356
|
+
// src/app.config.ts
|
|
357
|
+
import { defineAppConfig } from '@doubao-apps/kit';
|
|
358
|
+
|
|
359
|
+
export default defineAppConfig({
|
|
360
|
+
widgets: {
|
|
361
|
+
'widgets/user-action-card': {
|
|
362
|
+
id: 'user-action-card',
|
|
363
|
+
name: '全宽卡片示例',
|
|
364
|
+
boxType: 'full_box'
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
```
|
|
369
|
+
|
|
370
370
|
```tsx
|
|
371
371
|
export default defineWidget({
|
|
372
|
-
aiMeta: {
|
|
373
|
-
id: 'user-action-card',
|
|
374
|
-
name: '全宽卡片示例',
|
|
375
|
-
boxType: 'full_box',
|
|
376
|
-
input: {
|
|
377
|
-
type: 'object',
|
|
378
|
-
properties: {
|
|
379
|
-
action: { type: 'string', title: '操作' },
|
|
380
|
-
result: { type: 'string', title: '结果' }
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
},
|
|
384
372
|
render() {
|
|
385
373
|
const input = getViewData<{ action: string; result: string }>();
|
|
386
374
|
return (
|
|
@@ -393,127 +381,26 @@ export default defineWidget({
|
|
|
393
381
|
});
|
|
394
382
|
```
|
|
395
383
|
|
|
396
|
-
###
|
|
384
|
+
### 输入数据类型
|
|
397
385
|
|
|
398
|
-
|
|
386
|
+
Widget 输入数据通过 `getViewData<T>()` 的泛型参数和 TypeScript 接口表达。
|
|
399
387
|
|
|
400
388
|
```tsx
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
// 数字
|
|
412
|
-
{
|
|
413
|
-
type: 'number',
|
|
414
|
-
title: '数量',
|
|
415
|
-
minimum: 0,
|
|
416
|
-
maximum: 100,
|
|
417
|
-
default: 1
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
// 布尔值
|
|
421
|
-
{
|
|
422
|
-
type: 'boolean',
|
|
423
|
-
title: '是否启用',
|
|
424
|
-
default: false
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// 枚举
|
|
428
|
-
{
|
|
429
|
-
type: 'string',
|
|
430
|
-
enum: ['option1', 'option2', 'option3'],
|
|
431
|
-
title: '选项'
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// 数组
|
|
435
|
-
{
|
|
436
|
-
type: 'array',
|
|
437
|
-
items: {
|
|
438
|
-
type: 'string'
|
|
439
|
-
},
|
|
440
|
-
title: '标签列表',
|
|
441
|
-
minItems: 1,
|
|
442
|
-
maxItems: 5
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
// 对象
|
|
446
|
-
{
|
|
447
|
-
type: 'object',
|
|
448
|
-
properties: {
|
|
449
|
-
name: { type: 'string', title: '名称' },
|
|
450
|
-
age: { type: 'number', title: '年龄' }
|
|
451
|
-
},
|
|
452
|
-
required: ['name']
|
|
389
|
+
interface ProductCardData {
|
|
390
|
+
name: string;
|
|
391
|
+
price: number;
|
|
392
|
+
images?: string[];
|
|
393
|
+
category: '电子' | '服装' | '食品' | '图书';
|
|
394
|
+
inStock: boolean;
|
|
395
|
+
specs?: {
|
|
396
|
+
color?: string;
|
|
397
|
+
size?: string;
|
|
398
|
+
};
|
|
453
399
|
}
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
**复杂 Schema 示例**
|
|
457
400
|
|
|
458
|
-
```tsx
|
|
459
401
|
export default defineWidget({
|
|
460
|
-
aiMeta: {
|
|
461
|
-
id: 'product-card',
|
|
462
|
-
name: '商品卡片',
|
|
463
|
-
boxType: 'inbox',
|
|
464
|
-
input: {
|
|
465
|
-
type: 'object',
|
|
466
|
-
properties: {
|
|
467
|
-
name: {
|
|
468
|
-
type: 'string',
|
|
469
|
-
title: '商品名称',
|
|
470
|
-
description: '商品的显示名称'
|
|
471
|
-
},
|
|
472
|
-
price: {
|
|
473
|
-
type: 'number',
|
|
474
|
-
title: '价格',
|
|
475
|
-
minimum: 0,
|
|
476
|
-
description: '商品价格(元)'
|
|
477
|
-
},
|
|
478
|
-
images: {
|
|
479
|
-
type: 'array',
|
|
480
|
-
items: { type: 'string' },
|
|
481
|
-
title: '商品图片',
|
|
482
|
-
description: '商品图片 URL 列表',
|
|
483
|
-
minItems: 1,
|
|
484
|
-
maxItems: 5
|
|
485
|
-
},
|
|
486
|
-
category: {
|
|
487
|
-
type: 'string',
|
|
488
|
-
enum: ['电子', '服装', '食品', '图书'],
|
|
489
|
-
title: '分类'
|
|
490
|
-
},
|
|
491
|
-
inStock: {
|
|
492
|
-
type: 'boolean',
|
|
493
|
-
title: '是否有货',
|
|
494
|
-
default: true
|
|
495
|
-
},
|
|
496
|
-
specs: {
|
|
497
|
-
type: 'object',
|
|
498
|
-
properties: {
|
|
499
|
-
color: { type: 'string', title: '颜色' },
|
|
500
|
-
size: { type: 'string', title: '尺寸' }
|
|
501
|
-
},
|
|
502
|
-
title: '规格'
|
|
503
|
-
}
|
|
504
|
-
},
|
|
505
|
-
required: ['name', 'price']
|
|
506
|
-
}
|
|
507
|
-
},
|
|
508
402
|
render() {
|
|
509
|
-
const input = getViewData<
|
|
510
|
-
name: string;
|
|
511
|
-
price: number;
|
|
512
|
-
images?: string[];
|
|
513
|
-
category: string;
|
|
514
|
-
inStock: boolean;
|
|
515
|
-
specs?: { color?: string; size?: string };
|
|
516
|
-
}>();
|
|
403
|
+
const input = getViewData<ProductCardData>();
|
|
517
404
|
return (
|
|
518
405
|
<view className="product-card">
|
|
519
406
|
<text className="name">{input.name}</text>
|
|
@@ -579,16 +466,17 @@ function WeatherWidget({ city }: { city: string }) {
|
|
|
579
466
|
**2. 用户交互**
|
|
580
467
|
|
|
581
468
|
```tsx
|
|
469
|
+
import { sendQueryMessage } from '@doubao-apps/framework/api';
|
|
470
|
+
|
|
582
471
|
function InteractiveWidget({ initialCount }: { initialCount: number }) {
|
|
583
472
|
const [count, setCount] = useState(initialCount);
|
|
584
473
|
|
|
585
474
|
const handleIncrement = () => {
|
|
586
475
|
setCount(count + 1);
|
|
587
|
-
//
|
|
476
|
+
// 发送一条用户消息到当前会话
|
|
588
477
|
sendQueryMessage({
|
|
589
478
|
content: `计数增加到 ${count + 1}`,
|
|
590
|
-
type: 'text'
|
|
591
|
-
context: {}
|
|
479
|
+
type: 'text'
|
|
592
480
|
});
|
|
593
481
|
};
|
|
594
482
|
|
|
@@ -604,18 +492,12 @@ function InteractiveWidget({ initialCount }: { initialCount: number }) {
|
|
|
604
492
|
**3. 打开页面**
|
|
605
493
|
|
|
606
494
|
```tsx
|
|
607
|
-
import {
|
|
495
|
+
import { navigateTo } from '@doubao-apps/framework/api';
|
|
608
496
|
|
|
609
497
|
function ActionWidget({ itemId }: { itemId: string }) {
|
|
610
498
|
const handleViewDetail = () => {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
mode: 'full', // 全屏页面,可省略(默认)
|
|
614
|
-
pageData: JSON.stringify({ id: itemId }),
|
|
615
|
-
context: {},
|
|
616
|
-
pageSettings: {
|
|
617
|
-
title: '详情'
|
|
618
|
-
}
|
|
499
|
+
navigateTo({
|
|
500
|
+
url: `item-detail?id=${itemId}`
|
|
619
501
|
});
|
|
620
502
|
};
|
|
621
503
|
|