docs: 渐进式插件教程(L0→L5)+ DESIGN.md 视觉规范 + plugin-template 脚手架

This commit is contained in:
Rick Ye
2026-09-11 02:18:01 +08:00
parent 8e4b5496e8
commit 4ed31a34fc
16 changed files with 844 additions and 1 deletions
+90
View File
@@ -0,0 +1,90 @@
# L2 · 设置表单
> 前置:[L0](./01-hello-plugin.md)。声明式 schema:插件声明「要什么配置」,宿主负责渲染、持久化、实时回推。不用写任何 UI 代码。
## 1. 声明设置
```js
export default function definePlugin(api) {
api.ui.registerSettings({
items: [
{ type: 'string', key: 'apiKey', label: 'API Token', password: true, placeholder: 'sk-...' },
{ type: 'boolean', key: 'verbose', label: '详细日志', default: false },
{
type: 'select', key: 'endpoint', label: '接入点', default: 'prod',
options: [
{ value: 'prod', label: '生产' },
{ value: 'staging', label: '预发' }
]
},
{ type: 'button', key: 'test', label: '测试连接', variant: 'primary' }
]
})
}
```
保存后(开关切换或重启):
- 设置 → 插件 → **全局/项目** 作用域里,该插件行内出现 ⚙ 按钮(打开配置页)和「一级入口」开关
- **items 为空或不声明 → 两个控件都不出现**(这正是"留空则无一级入口按钮"的规则)
## 2. 一级入口
行内「一级入口」开关打开后,设置弹窗左侧导航「Agent 能力」组末尾出现以插件名命名的入口,点击进入该插件的独立配置页。用户随时可以关掉。
## 3. 读写值
```js
const values = api.ui.getSettingValues() // { apiKey: '...', verbose: false, endpoint: 'prod' }
// schema 里的 default 已合并——没被用户改过的键直接拿默认值
api.ui.onSettingsChange((next) => { // 用户在设置页改值后实时推送
values = next
api.log.info('settings changed', { endpoint: next.endpoint })
})
api.ui.onSettingsAction((key) => { // button 条目点击(key = 按钮项 key)
if (key === 'test') {
const ok = values.apiKey ? '✅' : '❌ 缺少 API Token'
api.ui.setStatusItem('test', { text: `连接测试 ${ok}`, tone: 'accent' })
}
})
```
值持久化在 `userData/aso-plugin-values.json`(按插件隔离),重装插件后仍在。
## 4. 13 种标准控件
| type | 说明 | 关键字段 |
|---|---|---|
| `string` | 单行输入 | `password` 掩码、`placeholder` |
| `text` | 多行文本 | `rows` |
| `number` | 数字 | `min` / `max` / `step` |
| `boolean` | 开关 | — |
| `select` | 下拉单选 | `options[{value,label}]` |
| `multiSelect` | 多选(chip 组) | `options` |
| `slider` | 滑条 | `min` / `max` 必填、`step` |
| `color` | 颜色(#rrggbb) | — |
| `path` | 文件/目录选择 | `mode: 'file' \| 'directory'` |
| `image` | 图片选择 + 缩略图 | — |
| `button` | 动作按钮 | `variant: 'primary' \| 'ghost'` |
| `info` | 静态说明 | — |
| `divider` | 分割线/小节标题 | `label?` |
全部条目支持 `label` / `description` / `default`(button/info/divider 除外)。
## 5. 设计约束(为什么是数据不是代码)
- schema 是**纯数据**:不允许函数/React 元素——宿主跨进程渲染并持久化快照
- 需要动态选项(比如扫描出来的设备列表)?在激活时计算好再 `registerSettings`,每次激活都会重新声明
- 需要复杂交互 UI?那不是设置的职责——走 [L4 React 组件](./05-renderer-components.md)
## 6. 验证
1. 重载插件 → 插件页该行出现 ⚙ 与「一级入口」
2. 打开配置页改一个值 → 日志出现 `settings changed`(`onSettingsChange` 生效)
3. 点按钮 → 状态胶囊出现(动作回调生效)
4. `userData/aso-plugin-values.json` 里能看到写入的键值
---
**上一篇** [L1](./02-tools-and-commands.md) · **下一篇**:[L3 UI 槽位](./04-ui-slots.md)——状态胶囊、面板、视图与 iframe 页。