lcap-frontend-library 0.0.1
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/README.md +271 -0
- package/bin/lcap-frontend-library.mjs +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +27 -0
- package/dist/init.d.ts +6 -0
- package/dist/init.js +79 -0
- package/dist/sync.d.ts +4 -0
- package/dist/sync.js +70 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.js +101 -0
- package/package.json +34 -0
- package/packages/lcap-frontend-library/LEARNINGS.md +11 -0
- package/packages/lcap-frontend-library/SKILL.md +86 -0
- package/packages/lcap-frontend-library/commands/migrate.check.md +287 -0
- package/packages/lcap-frontend-library/commands/migrate.green.md +190 -0
- package/packages/lcap-frontend-library/commands/migrate.plan.md +169 -0
- package/packages/lcap-frontend-library/commands/migrate.red.md +160 -0
- package/packages/lcap-frontend-library/commands/migrate.scan.md +151 -0
- package/packages/lcap-frontend-library/commands/migrate.spec.md +144 -0
- package/packages/lcap-frontend-library/commands/migrate.tasks.md +179 -0
- package/packages/lcap-frontend-library/commands/speckit.create.md +201 -0
- package/packages/lcap-frontend-library/commands/speckit.implement.md +88 -0
- package/packages/lcap-frontend-library/commands/speckit.plan.md +79 -0
- package/packages/lcap-frontend-library/commands/speckit.self-check.md +177 -0
- package/packages/lcap-frontend-library/commands/speckit.specify.md +91 -0
- package/packages/lcap-frontend-library/commands/speckit.tasks.md +61 -0
- package/packages/lcap-frontend-library/references/frontend-design/LICENSE.txt +177 -0
- package/packages/lcap-frontend-library/references/frontend-design/SKILL.md +42 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/SKILL.md +360 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/api.md +331 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/block.md +160 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/i18n.md +95 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/icon.md +27 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/container.md +728 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/element.md +312 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/expression.md +154 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/index.md +113 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/modal.md +189 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide/popover.md +171 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/ide.md +799 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/implementation-rules.md +242 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/index.md +27 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/nasl-view-component.md +895 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/accessibility.md +185 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/child.md +82 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/data-source.md +261 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/event.md +171 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/form.md +266 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/function.md +80 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/link.md +137 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/slot.md +128 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-ant-design.md +1470 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-cloud-ui.md +259 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-element-plus.md +580 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-element-ui.md +1007 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/platform/theme-variables-mobile-ui.md +85 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/theme.md +234 -0
- package/packages/lcap-frontend-library/references/lcap-extension-component/workflow-guardrails.md +328 -0
- package/packages/lcap-frontend-library/references/nasl-logic-authoring/SKILL.md +201 -0
- package/packages/lcap-frontend-library/scripts/bash/create-component-files.sh +95 -0
- package/packages/lcap-frontend-library/scripts/bash/create-extension-project.sh +109 -0
- package/packages/lcap-frontend-library/scripts/bash/create-logic-files.sh +149 -0
- package/packages/lcap-frontend-library/scripts/bash/create-spec.sh +109 -0
- package/packages/lcap-frontend-library/scripts/bash/get-available-port.sh +35 -0
- package/packages/lcap-frontend-library/scripts/bash/list-specs.sh +19 -0
- package/packages/lcap-frontend-library/scripts/node/setup-extension-project.mjs +166 -0
- package/packages/lcap-frontend-library/templates/component-self-check.md +31 -0
- package/packages/lcap-frontend-library/templates/component-template.md +96 -0
- package/packages/lcap-frontend-library/templates/library-report-template.md +52 -0
- package/packages/lcap-frontend-library/templates/logic-template.md +44 -0
- package/packages/lcap-frontend-library/templates/migration-manifest-template.md +84 -0
- package/packages/lcap-frontend-library/templates/migration-plan-template.md +138 -0
- package/packages/lcap-frontend-library/templates/migration-report-template.md +227 -0
- package/packages/lcap-frontend-library/templates/migration-spec-template.md +135 -0
- package/packages/lcap-frontend-library/templates/migration-tasks-template.md +129 -0
- package/packages/lcap-frontend-library/templates/plan-template.md +299 -0
- package/packages/lcap-frontend-library/templates/self-check-report-template.md +148 -0
- package/packages/lcap-frontend-library/templates/tasks-template.md +81 -0
- package/packages/lcap-frontend-library/workflows/create/flow.md +199 -0
- package/packages/lcap-frontend-library/workflows/evolve/flow.md +249 -0
- package/packages/lcap-frontend-library/workflows/generate/flow.md +10 -0
- package/packages/lcap-frontend-library/workflows/harness/flow.md +82 -0
- package/packages/lcap-frontend-library/workflows/migrate/flow.md +302 -0
- package/packages/lcap-frontend-library/workflows/migrate/knowledge-base.md +564 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lcap-extension-component
|
|
3
|
+
description: 指导 CodeWave/LCAP 扩展组件的接入开发,包括 api.ts 配置、页面设计器 ideusage 适配、block.stories 区块示例。Use when developing LCAP extension components, writing api.ts, configuring IDE page designer adaptation, or working with CodeWave View Component API.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# LCAP 扩展组件开发指南
|
|
7
|
+
|
|
8
|
+
## 适用场景
|
|
9
|
+
|
|
10
|
+
- 接入扩展组件到 CodeWave 智能开发平台
|
|
11
|
+
- 编写 api.ts 组件配置
|
|
12
|
+
- 配置页面设计器(IDE)适配
|
|
13
|
+
- 编写 block.stories 拖拽初始代码
|
|
14
|
+
|
|
15
|
+
## 必要配置文件
|
|
16
|
+
|
|
17
|
+
| 配置 | 说明 |
|
|
18
|
+
|------|------|
|
|
19
|
+
| **api.ts** | 组件配置面板生成、属性/事件/插槽/方法描述 |
|
|
20
|
+
| **block.stories.{js\|tsx}** | 拖拽到画布后的初始代码示例 |
|
|
21
|
+
| **ideusage** | 页面设计器画布适配配置 |
|
|
22
|
+
|
|
23
|
+
## 组件实现规则
|
|
24
|
+
|
|
25
|
+
实现扩展组件时需同时满足以下六条规则。**计划阶段必须将规则转化为具体的配置参数(如具体的变量映射、具体的默认值结构)**,实现阶段严格按计划执行,自检与验收时逐条核对:
|
|
26
|
+
|
|
27
|
+
1. **展示类属性必有默认值**:与展示直接相关的属性(如 `data`、`options`、`config` 等)必须设置合理默认值,确保未传入或传入空数据时也能正常渲染、不报错、不白屏。
|
|
28
|
+
2. **表单类组件 value 双向绑定**:表单类组件的“值”属性须支持双向绑定,内部变更时通过事件回写父组件,详见 `platform/form.md`。
|
|
29
|
+
3. **默认 HTML 属性穿透**:组件根节点须支持 `style`、`class`、`data-*` 透传,不得拦截或丢弃。
|
|
30
|
+
4. **UI 样式规范**:优先使用对应 UI 框架的全局主题变量(见 `platform/theme-variables-*.md`),禁止写死颜色/间距等魔法值。
|
|
31
|
+
5. **图标规范**:组件内部图标须基于 **SVG**(`<svg>`/`<use>`)或 IconSetter/图标库,禁止使用位图、base64 或文字/emoji 充当图标。
|
|
32
|
+
6. **Web Worker(Vite)**:若使用 Worker(含第三方库内置 worker),须由 Vite 解析资源(如 `?url` / `?worker`),前置初始化并做好 SSR 守卫;详见 `implementation-rules.md` §6。
|
|
33
|
+
|
|
34
|
+
**详细说明、实现要点与验收清单**见 **implementation-rules.md**。
|
|
35
|
+
|
|
36
|
+
## 工作流护栏(强烈建议遵守)
|
|
37
|
+
|
|
38
|
+
为避免“脚本权限、CSS Modules 定位、浮点断言精度、E2E strict mode、Storybook 事件绑定”等常见疏漏,建议在计划与实现阶段同时遵守:
|
|
39
|
+
|
|
40
|
+
- **workflow-guardrails.md**
|
|
41
|
+
|
|
42
|
+
## 组件架构设计(复杂组件适用)
|
|
43
|
+
|
|
44
|
+
**涉及复杂布局、第三方渲染库(如图表、PDF、富文本)或强依赖容器尺寸的组件**,在计划阶段须明确以下三要素;简单原子组件(如按钮、文本)可简述或不填。
|
|
45
|
+
|
|
46
|
+
- **尺寸与布局策略 (Sizing)**:明确组件是**容器驱动**(由外部决定大小)还是**内容驱动**(由内容撑开);定义初始化自适应逻辑(填满容器、等比例缩放或固定宽高)。
|
|
47
|
+
- **三方库集成审计 (Library Audit)**:预判库是否会注入内联 `style` 及覆盖方案;明确库在 **Mounted** 还是 **Updated** 时渲染,是否需要 `nextTick` 或 `ResizeObserver`。
|
|
48
|
+
- **测试分层**:逻辑与状态用 **Unit** 验证;涉及 **DOM 尺寸、滚动、弹窗、三方库渲染** 的功能**必须**有 **E2E** 用例,验收可观测的 DOM 状态(如 `clientWidth`、可见性等)。
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## api.ts 核心结构
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
/// <reference types="@nasl/types" />
|
|
55
|
+
namespace nasl.ui {
|
|
56
|
+
@ExtensionComponent({ ideusage: { idetype: "element" } })
|
|
57
|
+
@Component({ title: '按钮', icon: 'button', description: '...', group: 'Display' })
|
|
58
|
+
export class ElButton extends ViewComponent { /* 可访问属性、@Method 方法 */ }
|
|
59
|
+
|
|
60
|
+
export class ElButtonOptions extends ViewComponentOptions {
|
|
61
|
+
@Prop({ group: '主要属性', title: 'Size', setter: { concept: 'InputSetter' } })
|
|
62
|
+
size: nasl.core.String;
|
|
63
|
+
@Event({ title: '点击', description: '...' })
|
|
64
|
+
onClick: (event: { clientX: nasl.core.Integer; /* ... */ }) => void;
|
|
65
|
+
@Slot({ title: 'default', description: '内容' })
|
|
66
|
+
slotDefault: () => Array<nasl.ui.ViewComponent>;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 内置组件 icon 设置
|
|
72
|
+
|
|
73
|
+
`@Component({ icon: '...' })` 中的 `icon` 用于页面设计器组件面板与画布上的图标展示。**仅支持从平台内置组件图标中选择**,取值必须为下列之一(字符串,kebab-case):
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
'absolute-layout', 'affix', 'alert', 'anchor', 'anchor-item', 'anchor-link',
|
|
77
|
+
'backtop', 'badge', 'button', 'calendar', 'card', 'carousel', 'carousel-item',
|
|
78
|
+
'cascade-select', 'checkboxes', 'col', 'collapse', 'collapse-item', 'crumb',
|
|
79
|
+
'date-picker', 'descriptions', 'descriptions-item', 'dialog', 'divider',
|
|
80
|
+
'drawer', 'dropdown-new', 'forcom', 'form', 'icon', 'iframe', 'image', 'input',
|
|
81
|
+
'label', 'linear-layout', 'linear-progress', 'loading', 'modal', 'multi-layout',
|
|
82
|
+
'multi-layout-item', 'navbar-multi', 'number', 'notification', 'option',
|
|
83
|
+
'option-group', 'pageheader', 'pagination', 'popover', 'radio', 'radios', 'rate',
|
|
84
|
+
'result', 'row', 'Scrollbar', 'select', 'slider', 'steps', 'switch', 'table-view',
|
|
85
|
+
'tabs', 'text', 'TimeSelect', 'time-picker', 'timeline', 'timeline-item', 'toast',
|
|
86
|
+
'tooltip', 'transfer', 'tree-view', 'tree-view-new', 'uploader', 'watermark'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**选用规则**:
|
|
90
|
+
|
|
91
|
+
- 按扩展组件的**语义/形态**选择最接近的内置图标(如自定义「统计卡片」→ `card`,自定义「选择器」→ `select`),保证设计器内图标风格统一。
|
|
92
|
+
- 若**无合适匹配**(如全新类型的图表、定制控件),可不设置 `icon`,平台会使用默认占位图标;**禁止**使用上述列表之外的字符串,否则可能不展示或报错。
|
|
93
|
+
|
|
94
|
+
### NASL 类型(必须使用)
|
|
95
|
+
|
|
96
|
+
- **允许**:仅使用平台内置类型
|
|
97
|
+
- 基础:`nasl.core.Boolean`、`Integer`、`Decimal`、`String`、`Date`、`Time`、`DateTime`
|
|
98
|
+
- 集合:`nasl.collection.List<T>`、`Map<K,V>`,其中 `T`、`K`、`V` 也须为上述基础类型或内联对象类型
|
|
99
|
+
- 对象形态:使用**内联对象类型**,字段类型为 `nasl.core.*`
|
|
100
|
+
- **禁止**:`Object`、`Function`、`any`;**禁止自定义类型**(如在 namespace 内 `export class FunnelDataItem extends Base` 等),属性/事件/方法参数/插槽参数的类型均不可使用自定义类名。
|
|
101
|
+
|
|
102
|
+
**错误示例**(自定义类型):
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
// 禁止:自定义 class 作为类型
|
|
106
|
+
export class FunnelDataItem extends Base { ... }
|
|
107
|
+
export class FunnelItemStyle extends Base { ... }
|
|
108
|
+
data: nasl.collection.List<FunnelDataItem>;
|
|
109
|
+
itemStyle: FunnelItemStyle = { ... };
|
|
110
|
+
onFunnelItemClick: (event: { ... FunnelDataItem ... }) => void;
|
|
111
|
+
slotTooltip: (current: { ... }) => Array<...>; // current 中也不可用自定义类型
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**正确示例**(内联对象 + 仅 nasl.core / nasl.collection):
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
data: nasl.collection.List<{ name: nasl.core.String; value: nasl.core.Decimal }> = [];
|
|
118
|
+
|
|
119
|
+
itemStyle: {
|
|
120
|
+
color: nasl.core.String;
|
|
121
|
+
borderColor: nasl.core.String;
|
|
122
|
+
borderWidth: nasl.core.Integer;
|
|
123
|
+
} = { color: '#5470c6', borderColor: '#fff', borderWidth: 2 };
|
|
124
|
+
|
|
125
|
+
// 事件、插槽参数同理:用内联对象 + nasl.core.*,勿用 FunnelDataItem 等自定义类型
|
|
126
|
+
onFunnelItemClick: (event: { index: nasl.core.Integer; name: nasl.core.String; value: nasl.core.Decimal; percentage: nasl.core.Decimal }) => void;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 属性 Setter
|
|
130
|
+
|
|
131
|
+
| concept | 说明 | 适用类型 |
|
|
132
|
+
|---------|------|----------|
|
|
133
|
+
| InputSetter | 输入框(默认) | any |
|
|
134
|
+
| SwitchSetter | 开关 | Boolean |
|
|
135
|
+
| EnumSelectSetter | 枚举选择 | 字符串枚举 |
|
|
136
|
+
| CapsulesSetter | 胶囊 | 字符串枚举 |
|
|
137
|
+
| NumberInputSetter | 数字输入 | Integer/Decimal |
|
|
138
|
+
| IconSetter | 图标 | String |
|
|
139
|
+
| ImageSetter | 图片 | String |
|
|
140
|
+
| PropertySelectSetter | 属性选择 | String |
|
|
141
|
+
| AnonymousFunctionSetter | 匿名函数 | (...args) => any |
|
|
142
|
+
|
|
143
|
+
### 事件规范
|
|
144
|
+
|
|
145
|
+
- 事件名:以 `on` 开头小驼峰,如 `onClick`、`onRowClick`
|
|
146
|
+
- **合法标识符**:api.ts 中事件须为普通属性名,**禁止**使用引号字符串键或含 `:` 的键名。例如与 Vue `update:modelValue` 对应时,不得写成 `'onUpdate:modelValue'`,应写为 `onUpdateModelValue`。
|
|
147
|
+
- 参数:有且仅有一个 `event` 对象;多参数合并为 `onSelect: (event: { value, item }) => void`
|
|
148
|
+
- 返回:`void`
|
|
149
|
+
|
|
150
|
+
### 插槽规范
|
|
151
|
+
|
|
152
|
+
- 属性名:`slotDefault`(默认)、`slotHeader`(具名)
|
|
153
|
+
- 作用域插槽:`slotItem: (current: Current<T>) => Array<ViewComponent>`
|
|
154
|
+
|
|
155
|
+
## ideusage:页面设计器适配 (api.ts)
|
|
156
|
+
|
|
157
|
+
通过 `@ExtensionComponent({ ideusage: { ... } })` 配置。组件类型 `idetype` 与**是否需插槽**的对应关系如下,生成 api.ts 时须严格按此处理,不得误删插槽:
|
|
158
|
+
|
|
159
|
+
| idetype | 说明 | 插槽 |
|
|
160
|
+
|---------|------|------|
|
|
161
|
+
| **element** | 原子组件(如 button、text、input),不可插入子节点 | **不需要插槽**,api.ts 中不定义 Slots |
|
|
162
|
+
| **container** | 可插入子节点的容器 | **需要插槽**,至少 slotDefault 等 |
|
|
163
|
+
| **modal** | 弹窗类(dialog、modal 等) | **需要插槽**(内容区、标题等),按 spec 定义 |
|
|
164
|
+
| **drawer** | 抽屉组件 | **需要插槽**(内容区等),按 spec 定义 |
|
|
165
|
+
| **messager** | 消息弹出 | **需要插槽**,按 spec 定义 |
|
|
166
|
+
| **popover** | 弹出层类(popover、dropdown 等) | **需要插槽**(内容区、触发区等),按 spec 定义 |
|
|
167
|
+
| router | 路由 | 按 spec |
|
|
168
|
+
| board | 自由布局 | 按 spec |
|
|
169
|
+
|
|
170
|
+
**插槽约定**:仅 **element** 类型在 api.ts 中不定义 Slots;**container、modal、drawer、messager、popover** 类型均需根据 spec 在 api.ts 中保留并定义相应插槽,生成或修改 api.ts 时不得删除这些类型的 Slots。**若 spec 或 api.ts 中已定义插槽,则 idetype 不得为 element**,须按组件形态选用 container / modal / drawer / messager / popover,否则设计器与插槽定义矛盾。
|
|
171
|
+
|
|
172
|
+
### element 常用配置
|
|
173
|
+
|
|
174
|
+
<!-- idetype=element:不需要插槽,等 -->
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
ideusage: {
|
|
178
|
+
idetype: "element",
|
|
179
|
+
editable: "text", // 可双击编辑的属性
|
|
180
|
+
textholder: "text", // 显示文本的属性
|
|
181
|
+
useFxOrEg: { property: "text" }, // 表达式与示例切换
|
|
182
|
+
iconEditor: true,
|
|
183
|
+
events: { click: true }
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### container 常用配置
|
|
188
|
+
|
|
189
|
+
<!-- idetype=container:需要插槽,至少 slotDefault 等 -->
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
ideusage: {
|
|
193
|
+
idetype: "container",
|
|
194
|
+
disableSlotAutoFill: ["cover"], // 禁止自动插入的插槽
|
|
195
|
+
structured: true, // 通过"+"添加子组件
|
|
196
|
+
childAccept: "target.tag === 'TableColumn'",
|
|
197
|
+
parentAccept: "target.tag === 'Table'",
|
|
198
|
+
dataSource: {
|
|
199
|
+
display: 3,
|
|
200
|
+
loopElem: "> label[class^='u-radios_radio']:not([data-nodepath])",
|
|
201
|
+
dismiss: "!this.getAttribute('dataSource') && this.getDefaultElements().length > 0"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### modal/drawer/messager 必须配置
|
|
207
|
+
|
|
208
|
+
- `selector`: `{ expression: "this.getElement(el => el.slotTarget === 'body')", cssSelector: "div[class^='u-modal_dialog']" }`
|
|
209
|
+
- `cacheOpenKey`: 控制显隐的属性名,如 `"visible"` 或 `"open"`
|
|
210
|
+
|
|
211
|
+
### 表达式 API(用于 parentAccept、childAccept、containerDirection 等)
|
|
212
|
+
|
|
213
|
+
- `target.tag`:目标组件 tag
|
|
214
|
+
- `this.getAttribute('attr')?.value`:当前属性值
|
|
215
|
+
- `this.getElement(el => el.slotTarget === 'title')`:查找子元素
|
|
216
|
+
- `this.getParent()`、`this.elementsLength()`、`this.getAncestor(tag)`
|
|
217
|
+
|
|
218
|
+
## block.stories
|
|
219
|
+
|
|
220
|
+
拖拽到画布后的**初始代码**,必须满足:
|
|
221
|
+
|
|
222
|
+
- **仅允许静态属性**:所有 props 的值必须直接写在模板/JSX 里,为字面量或内联的静态结构(如数组、对象字面量)。
|
|
223
|
+
- **禁止绑定变量**:不得使用 `setup()`、`data()`、`ref`、`reactive` 等把数据存成变量再绑定到模板;属性一律用内联字面量。
|
|
224
|
+
- **禁止绑定事件**:不得在 block.stories 的模板/JSX 中写 `@click`、`onClick`、`v-on` 等事件绑定。
|
|
225
|
+
|
|
226
|
+
**错误示例**(使用 setup/变量,导致拖入画布后无法还原):
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
export const Default = {
|
|
230
|
+
name: '基本用法',
|
|
231
|
+
render: () => ({
|
|
232
|
+
components: { 'funnel-chart': Component },
|
|
233
|
+
setup() {
|
|
234
|
+
const data = [
|
|
235
|
+
{ name: '未触达客户', value: 1000 },
|
|
236
|
+
{ name: '已触达客户', value: 800 },
|
|
237
|
+
// ...
|
|
238
|
+
];
|
|
239
|
+
return { data };
|
|
240
|
+
},
|
|
241
|
+
template: '<funnel-chart :data="data" height="400px" width="600px"></funnel-chart>',
|
|
242
|
+
}),
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**正确示例**(属性全部内联字面量,无 setup、无变量、无事件):
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
export const Default = {
|
|
250
|
+
name: '基本用法',
|
|
251
|
+
render: () => ({
|
|
252
|
+
components: { 'funnel-chart': Component },
|
|
253
|
+
template: '<funnel-chart :data="[{ name: \'未触达客户\', value: 1000 }, { name: \'已触达客户\', value: 800 }, { name: \'意向客户\', value: 600 }, { name: \'成交客户\', value: 400 }, { name: \'复购客户\', value: 200 }]" height="400px" width="600px"></funnel-chart>',
|
|
254
|
+
}),
|
|
255
|
+
};
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
简单组件可直接写死字符串/无绑定:
|
|
259
|
+
|
|
260
|
+
```javascript
|
|
261
|
+
// block.stories.js (Vue2)
|
|
262
|
+
export const Default = {
|
|
263
|
+
name: '默认按钮',
|
|
264
|
+
render: () => ({ template: '<u-button text="确定"></u-button>' }),
|
|
265
|
+
};
|
|
266
|
+
// block.stories.tsx (React)
|
|
267
|
+
export const Default = { name: '主要按钮', render: () => <Button type="primary" children="确定" /> };
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Playwright e2e 测试规范
|
|
271
|
+
|
|
272
|
+
e2e 测试须与 spec 验收标准一一对应,且**必须**满足以下三点,否则视为不合格:
|
|
273
|
+
|
|
274
|
+
### 1. 基于 example.stories 各功能 demo
|
|
275
|
+
|
|
276
|
+
- 在**组件目录下** **`stories/example.stories.{js|tsx|jsx}`** 中为 spec 的**每个功能**各添加一个 demo story(命名清晰,如 `Default`、`WithTooltip`、`ClickToSelect` 等),用于展示该功能并供 e2e 使用。
|
|
277
|
+
- **Playwright e2e 测试应针对 example.stories 中的这些功能 story 运行**:通过 Storybook iframe URL 访问对应 demo,**storyId 遵循 Storybook 规则**:`<stories 的 kind 名(kebab-case)>--<story 导出名(kebab-case)>`,例如 `funnel-chart-example--default`、`funnel-chart-example--with-tooltip`;完整 URL 形如 `/iframe.html?id=<storyId>&viewMode=story`。e2e 在该页面上执行操作并断言,每个功能既有可手动查看的 demo,又有自动化覆盖。
|
|
278
|
+
|
|
279
|
+
### 2. 监控控制台与页面报错
|
|
280
|
+
|
|
281
|
+
每个 e2e 用例运行期间,**必须监听**浏览器控制台(`console`)与页面错误(`pageerror`),一旦出现**组件自身的 JS 运行时错误**则**将该用例标记为失败**,不得忽略。
|
|
282
|
+
|
|
283
|
+
- 使用 `page.on('pageerror', err => ...)` 监听页面未捕获异常,出现则令用例失败。
|
|
284
|
+
- 使用 `page.on('console', msg => ...)` 监听 `console.error`,**过滤网络资源 404**(Storybook 开发模式下 favicon、addon 资源等可能产生 404 噪音),仅收集组件自身的 JS 错误:
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
page.on('console', (msg) => {
|
|
288
|
+
if (msg.type() === 'error') {
|
|
289
|
+
const text = msg.text();
|
|
290
|
+
// 过滤网络资源404(非组件JS错误)
|
|
291
|
+
if (text.includes('404') || text.includes('net::ERR_')) return;
|
|
292
|
+
consoleErrors.push(text);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
- 在用例末尾断言 `expect(consoleErrors).toHaveLength(0)` 或等效断言。
|
|
298
|
+
|
|
299
|
+
### 3. 每个用例必须有对应断言
|
|
300
|
+
|
|
301
|
+
每个 `test(...)` 必须包含**明确的断言**(`expect(...)`),用于验证该条对应的验收标准是否达成;禁止“只执行操作、不断言结果”或“仅确保不崩溃”的用例。
|
|
302
|
+
|
|
303
|
+
- 渲染类:断言目标 DOM/Canvas 存在、可见、数量或关键内容正确。
|
|
304
|
+
- 交互类:执行点击/输入等后,断言界面状态或事件结果(如某元素出现、文案变化、请求发出等)。
|
|
305
|
+
- 若有事件回调(如 onClick),可通过注入 spy 或检查 DOM 变化等方式断言已触发且结果符合预期。
|
|
306
|
+
|
|
307
|
+
## 注意事项
|
|
308
|
+
|
|
309
|
+
- **透传与插槽**:组件需将 `data-*` 透传到根 DOM;插槽需同时支持 `EmptySlot` 与普通 HTML 内容。
|
|
310
|
+
- **属性分组**:`@Prop({ group: '...' })` 的 `group` 仅支持以下取值:数据属性、主要属性、交互属性、状态属性、样式属性、工具属性。
|
|
311
|
+
- **block.stories 数量**:`block.stories.{js|jsx|tsx}` 中**仅保留一个** story(拖拽到画布用)。若有多个示例或本地调试用例,请写在 `example.stories.{js|jsx|tsx}` 中,勿在 block.stories 中新增。
|
|
312
|
+
- **example.stories 功能 demo**:在组件目录下 `stories/example.stories.{js|tsx|jsx}` 中为 **spec 的每个功能** 各添加一个 demo story(可与验收标准一一对应),用于本地调试、验收对照与 Playwright e2e。
|
|
313
|
+
|
|
314
|
+
完整规范见本 skill 目录:`references/lcap-extension-component/`
|
|
315
|
+
|
|
316
|
+
### 核心必备
|
|
317
|
+
|
|
318
|
+
| 文档 | 说明 |
|
|
319
|
+
|------|------|
|
|
320
|
+
| `api.md` | api.ts 编写、属性/事件/插槽/方法描述 |
|
|
321
|
+
| `block.md` | block.stories 区块示例 |
|
|
322
|
+
| `nasl-view-component.md` | View Component API 书写规范 |
|
|
323
|
+
|
|
324
|
+
### 页面设计器(ideusage)
|
|
325
|
+
|
|
326
|
+
| 文档 | 说明 |
|
|
327
|
+
|------|------|
|
|
328
|
+
| `ide.md` | 页面设计器适配总览 |
|
|
329
|
+
| `ide/index.md` | ideusage 配置索引 |
|
|
330
|
+
| `ide/element.md` | element 原子组件 |
|
|
331
|
+
| `ide/container.md` | container 容器组件 |
|
|
332
|
+
| `ide/modal.md` | modal 弹窗 |
|
|
333
|
+
| `ide/popover.md` | popover 弹出框 |
|
|
334
|
+
| `ide/expression.md` | 表达式 API(parentAccept、childAccept 等)|
|
|
335
|
+
|
|
336
|
+
### 平台能力(platform)
|
|
337
|
+
|
|
338
|
+
| 文档 | 说明 |
|
|
339
|
+
|------|------|
|
|
340
|
+
| `platform/slot.md` | 插槽 @Slot 配置:默认/具名插槽、snippets、emptyBackground,书写规范同 block |
|
|
341
|
+
| `platform/event.md` | 事件 @Event 约定:合法属性名(禁止带 `:` 的引号键如 `'onUpdate:modelValue'`,用 `onUpdateModelValue`)、仅单 event 参数、on 前缀小驼峰、多参数合并为 event 对象、返回 void |
|
|
342
|
+
| `platform/child.md` | 父子组件约束:子组件不上面板,通过父组件「+」添加,snippets 与 emptyBackground 配置 |
|
|
343
|
+
| `platform/form.md` | 表单能力:值双向绑定(sync/update:value)、表单校验;表单项组件必读 |
|
|
344
|
+
| `platform/link.md` | 链接跳转:hrefAndTo 属性、link/destination 及点击跳转实现 |
|
|
345
|
+
| `platform/function.md` | 函数类型属性(AnonymousFunctionSetter):行样式、格式化等,bindOpen 与 Current 参数 |
|
|
346
|
+
| `platform/data-source.md` | 数据源 dataSource:绑定后端、数据类型与字段映射、reload 方法 |
|
|
347
|
+
| `platform/accessibility.md` | 可访问性:属性可读/可写、sync:state 同步状态(当前仅 Vue) |
|
|
348
|
+
|
|
349
|
+
### 可选扩展
|
|
350
|
+
|
|
351
|
+
| 文档 | 说明 |
|
|
352
|
+
|------|------|
|
|
353
|
+
| `icon.md` | IDE组件面板中显示图标配置 |
|
|
354
|
+
| `i18n.md` | 国际化能力适配 |
|
|
355
|
+
| `theme.md` | IDE样式配置方案 |
|
|
356
|
+
| `platform/theme-variables-ant-design.md` | Ant Design 主题变量(React) |
|
|
357
|
+
| `platform/theme-variables-element-plus.md` | Element Plus 主题变量(Vue3) |
|
|
358
|
+
| `platform/theme-variables-element-ui.md` | Element UI 主题变量,旧版(Vue2) |
|
|
359
|
+
| `platform/theme-variables-cloud-ui.md` | Cloud UI 主题变量(Vue2) |
|
|
360
|
+
| `platform/theme-variables-mobile-ui.md` | Mobile UI 主题变量(Vue2 移动端) |
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
---
|
|
2
|
+
outline: deep
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# 组件配置编写说明
|
|
6
|
+
|
|
7
|
+
<div class="yellowBlock">
|
|
8
|
+
|
|
9
|
+
此文档仅简单介绍api.ts如何编写, 详细文档介绍请参考[View Component API 书写指南和规范](../component/nasl-view-component.md)。
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
api.ts用于组件的配置面板生成、应用翻译等,整体的格式参考如下:
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
/// <reference types="@nasl/types" /> // 引用 nasl 类型S
|
|
18
|
+
|
|
19
|
+
namespace nasl.ui { // 命名空间,基础组件库 nasl.ui, 依赖库 extensions.[LibrayName].viewComponents
|
|
20
|
+
|
|
21
|
+
/* 组件描述 */
|
|
22
|
+
@ExtensionComponent({
|
|
23
|
+
show: false,
|
|
24
|
+
})
|
|
25
|
+
@Component({
|
|
26
|
+
title: '按钮',
|
|
27
|
+
icon: 'button',
|
|
28
|
+
description: '常用的操作按钮。',
|
|
29
|
+
})
|
|
30
|
+
export class ElButton extends ViewComponent { // 组件名称为 tag 的大驼峰,例如 el-button => ElButton
|
|
31
|
+
constructor(options?: Partial<ElButtonOptions>) {
|
|
32
|
+
super();
|
|
33
|
+
|
|
34
|
+
/* 提供调用方法描述 */
|
|
35
|
+
@Method({
|
|
36
|
+
title: '打开加载中',
|
|
37
|
+
description: '打开加载中',
|
|
38
|
+
})
|
|
39
|
+
startLoading(): void {}
|
|
40
|
+
|
|
41
|
+
@Method({
|
|
42
|
+
title: '关闭加载中',
|
|
43
|
+
description: '关闭加载中',
|
|
44
|
+
})
|
|
45
|
+
closeLoading(): void {}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export class ElButtonOptions extends ViewComponentOptions { // 参数类名需要与 组件class 名称对齐, 例如 ElButton -> ElButtonOptions, ElSelect -> ElSelectOptions
|
|
50
|
+
/* 配置参数描述 */
|
|
51
|
+
@Prop({
|
|
52
|
+
group: '主要属性',
|
|
53
|
+
title: 'Size',
|
|
54
|
+
description: '尺寸',
|
|
55
|
+
setter: { concept: 'InputSetter' },
|
|
56
|
+
})
|
|
57
|
+
size: nasl.core.String;
|
|
58
|
+
|
|
59
|
+
/* 更多参数描述 */
|
|
60
|
+
|
|
61
|
+
/* 事件描述 */
|
|
62
|
+
@Event({
|
|
63
|
+
title: '点击',
|
|
64
|
+
description: '在元素上按下并释放任意鼠标按钮时触发。',
|
|
65
|
+
})
|
|
66
|
+
onClick: (event: {
|
|
67
|
+
altKey: nasl.core.Boolean;
|
|
68
|
+
button: nasl.core.Integer;
|
|
69
|
+
clientX: nasl.core.Integer;
|
|
70
|
+
clientY: nasl.core.Integer;
|
|
71
|
+
ctrlKey: nasl.core.Boolean;
|
|
72
|
+
metaKey: nasl.core.Boolean;
|
|
73
|
+
movementX: nasl.core.Integer;
|
|
74
|
+
movementY: nasl.core.Integer;
|
|
75
|
+
offsetX: nasl.core.Integer;
|
|
76
|
+
offsetY: nasl.core.Integer;
|
|
77
|
+
pageX: nasl.core.Integer;
|
|
78
|
+
pageY: nasl.core.Integer;
|
|
79
|
+
screenX: nasl.core.Integer;
|
|
80
|
+
screenY: nasl.core.Integer;
|
|
81
|
+
which: nasl.core.Integer;
|
|
82
|
+
}) => any;
|
|
83
|
+
|
|
84
|
+
/* 插槽描述 */
|
|
85
|
+
@Slot({
|
|
86
|
+
title: 'default',
|
|
87
|
+
description: '内容',
|
|
88
|
+
})
|
|
89
|
+
slotDefault: () => Array<nasl.ui.ViewComponent>;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
api.ts 需要提供**组件描述**、**属性描述**、**事件描述**、**插槽描述**、**方法描述**五个方面,使用不同注解。以下分别详细解释这五个方面。
|
|
95
|
+
|
|
96
|
+
## 1. 组件描述
|
|
97
|
+
|
|
98
|
+
使用`@Component`来标注,用于组件面板识别排列。参考如下:
|
|
99
|
+
|
|
100
|
+
- 自定义 icon 请参考文档[自定义组件面板图标](../component/icon.md);
|
|
101
|
+
- 依赖库中的组件无需定义 group ,默认将依赖库名称作为其分组。
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
@Component({
|
|
106
|
+
title: '按钮', // 组件显示名称
|
|
107
|
+
icon: 'button', // 组件显示图标 (平台内置)
|
|
108
|
+
description: '常用的操作按钮。', // 组件描述
|
|
109
|
+
/**
|
|
110
|
+
* 组件分组,目前有
|
|
111
|
+
* Display 展示 Form 表单 Selector 选择器 Layout 布局
|
|
112
|
+
* Container 容器 Navigation 导航 Table 表格
|
|
113
|
+
*/
|
|
114
|
+
group: 'Display', // 依赖库使用 依赖库名称作为分组名称
|
|
115
|
+
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
## 2. 属性描述
|
|
121
|
+
|
|
122
|
+
属性描述即参数配置,使用 `@Prop`来描述参数、渲染参数配置表单。参考如下:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
@Prop({
|
|
126
|
+
// 分组,目前支持 '数据属性' | '主要属性' | '交互属性' | '状态属性' | '样式属性' | '工具属性'
|
|
127
|
+
group: '主要属性',
|
|
128
|
+
// 属性配置面板显示名称
|
|
129
|
+
title: '尺寸',
|
|
130
|
+
// hover 到名称上显示具体描述
|
|
131
|
+
description: '尺寸',
|
|
132
|
+
// 属性设置器,支持参数设置器,请查看 “属性设置器”
|
|
133
|
+
setter: { },
|
|
134
|
+
})
|
|
135
|
+
size: nasl.core.String = 'small'; // = ‘small’ 默认值 'small', nasl.core.String 参数类型,请查看“参数类型设置规范”
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**注意** `group` 目前支持 '数据属性' | '主要属性' | '交互属性' | '状态属性' | '样式属性' | '工具属性'
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
### 属性设置器
|
|
142
|
+
|
|
143
|
+
定义属性的设计器(setter)时,支持参数设计器,大致分为以下几种:
|
|
144
|
+
|
|
145
|
+
| 设置器名称 | 说明 | 支持类型 | 效果图 |
|
|
146
|
+
| :------- | :-------------- | :------- | :------ |
|
|
147
|
+
| `InputSetter` | 输入框设置器(默认) | any | |
|
|
148
|
+
| `SwitchSetter` | 开关设置器 | nasl.core.Boolean | |
|
|
149
|
+
| `EnumSelectSetter` | 枚举选择设置器 | nasl.core.String(字符串枚举形式)| |
|
|
150
|
+
| `CapsulesSetter` | 胶囊设置器 | nasl.core.String(字符串枚举形式)| |
|
|
151
|
+
| `NumberInputSetter` | 数字输入设置器 | nasl.core.Integer \| nasl.core.Decimal | |
|
|
152
|
+
| `IconSetter` | 图标设置器 | nasl.core.String | |
|
|
153
|
+
| `ImageSetter` | 图片设置器 | nasl.core.String | |
|
|
154
|
+
| `PropertySelectSetter` | 属性选择设置器 | nasl.core.String | |
|
|
155
|
+
| `AnonymousFunctionSetter` | 匿名函数设置器 | (...args) => any | |
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
**注意:** `setter` 的 `concept` 属性仅允许以上几种设置,`concept`不能使用例如: `ColorSetter` `ObjectSetter` `XXSetter` 等不在上述表格中的设置器名称
|
|
159
|
+
|
|
160
|
+
**设计器 demo 参考:**
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
Prop({
|
|
164
|
+
group: '主要属性',
|
|
165
|
+
title: '文本',
|
|
166
|
+
description: '按钮内容',
|
|
167
|
+
setter: { concept: 'InputSetter' },
|
|
168
|
+
})
|
|
169
|
+
text: nasl.core.String = '';
|
|
170
|
+
@Prop({
|
|
171
|
+
group: '状态属性',
|
|
172
|
+
title: 'Disabled',
|
|
173
|
+
description: '是否禁用状态',
|
|
174
|
+
setter: { concept: 'SwitchSetter' },
|
|
175
|
+
})
|
|
176
|
+
disabled: nasl.core.Boolean = false;
|
|
177
|
+
|
|
178
|
+
@Prop({
|
|
179
|
+
group: '主要属性',
|
|
180
|
+
title: '图标',
|
|
181
|
+
description: '图标类名',
|
|
182
|
+
setter: { concept: 'IconSetter' },
|
|
183
|
+
})
|
|
184
|
+
icon: nasl.core.String;
|
|
185
|
+
|
|
186
|
+
@Prop({
|
|
187
|
+
title: '图标位置',
|
|
188
|
+
description: '设置图标居左或居右显示',
|
|
189
|
+
setter: {
|
|
190
|
+
concept: 'EnumSelectSetter',
|
|
191
|
+
options: [{ title: '左' }, { title: '右' }],
|
|
192
|
+
},
|
|
193
|
+
})
|
|
194
|
+
iconPosition: 'left' | 'right' = 'left';
|
|
195
|
+
|
|
196
|
+
@Prop({
|
|
197
|
+
title: '尺寸',
|
|
198
|
+
description: '设置图标大小',
|
|
199
|
+
setter: {
|
|
200
|
+
concept: 'CapsulesSetter',
|
|
201
|
+
options: [{ title: '小' }, { title: '大' }],
|
|
202
|
+
},
|
|
203
|
+
})
|
|
204
|
+
size: 'small' | 'big' = 'small';
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
### 属性类型设置规范
|
|
210
|
+
|
|
211
|
+
使用api.ts属性描述,每个属性类型强制要求使用 nasl 提供的类型来写,支持类型如下:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
declare namespace nasl.core {
|
|
215
|
+
export type Boolean = boolean;
|
|
216
|
+
export type Integer = number;
|
|
217
|
+
export type Decimal = number;
|
|
218
|
+
export type String = string;
|
|
219
|
+
|
|
220
|
+
export class Binary {
|
|
221
|
+
accept: 'Binary';
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export class Date { // 组件接收的是string 类型
|
|
225
|
+
accept: 'Date';
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export class Time {// 组件接收的是string 类型
|
|
229
|
+
accept: 'Time';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export class DateTime {// 组件接收的是string 类型
|
|
233
|
+
accept: 'DateTime';
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 集合类型
|
|
238
|
+
nasl.collection.List<T>
|
|
239
|
+
|
|
240
|
+
// union 类型
|
|
241
|
+
'small' | 'large' | 'medium'
|
|
242
|
+
|
|
243
|
+
// 匿名数据结构
|
|
244
|
+
{ list: nasl.collection.List<T>, total: nasl.core.Integer }
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**注意** `api.ts` 中属性或者参数类型仅允许使用上述示例的类型,如果不确定类型可使用 `any`
|
|
248
|
+
错误的类型示例 `nasl.core.Any` `nasl.core.Object` `Object` `Function` 等等
|
|
249
|
+
|
|
250
|
+
## 3. 事件描述
|
|
251
|
+
|
|
252
|
+
使用`@Event`来标注支持的事件,需要注意以下几点:
|
|
253
|
+
|
|
254
|
+
1. 事件名需要以on 开头的小驼峰,例如click 需要写为onClick,row-click需要写为onRowClick;
|
|
255
|
+
2. 事件名须为合法属性名,**禁止**使用引号字符串键或含 `:` 的键名(如 `'onUpdate:modelValue'`);与 Vue `update:modelValue` 对应时须写为 `onUpdateModelValue`;
|
|
256
|
+
3. 事件参数仅允许有一个参数event,多个参数的情况需要转为一个匿名结构对象, 例如onSelect(value, item)需要转换为 onSelect({ value, item })。具体请参考[事件转换](../component/);
|
|
257
|
+
4. 返回参数统一为void,匿名数据结构属性也必须使用 nasl 支持的类型;
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
@Event({
|
|
261
|
+
title: '改变后',
|
|
262
|
+
description: '单选或多选值改变后触发',
|
|
263
|
+
})
|
|
264
|
+
onChange: (event: {
|
|
265
|
+
value: nasl.core.String;
|
|
266
|
+
values: nasl.collection.List<String>;
|
|
267
|
+
oldValues: nasl.collection.List<String>;
|
|
268
|
+
items: nasl.collection.List<String>;
|
|
269
|
+
}) => void;
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## 4. 插槽描述
|
|
273
|
+
|
|
274
|
+
使用`@Slot` 来描述组件插槽,插槽属性名以 slot 开头的小驼峰命名,例如默认插槽 slotDefault。
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
export class XxxOptions extends ViewComponentOptions {
|
|
278
|
+
// ...
|
|
279
|
+
@Slot({
|
|
280
|
+
title: 'Default',
|
|
281
|
+
description: '内容',
|
|
282
|
+
})
|
|
283
|
+
slotDefault: () => Array<nasl.ui.ViewComponent>;
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
<div class="highlight">
|
|
288
|
+
|
|
289
|
+
具体请参考文档[插槽处理](../component/platform/slot.md)。
|
|
290
|
+
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
## 5. 方法描述
|
|
295
|
+
|
|
296
|
+
使用`@Method`来描述组件提供的方法,如果有参数 则需要@Param对参数进行描述
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
@Method({
|
|
300
|
+
title: '导出',
|
|
301
|
+
description: '导出 excel 文件',
|
|
302
|
+
})
|
|
303
|
+
exportExcel(
|
|
304
|
+
@Param({
|
|
305
|
+
title: '当前页码',
|
|
306
|
+
description: '当前页码',
|
|
307
|
+
})
|
|
308
|
+
page: nasl.core.Integer = 1,
|
|
309
|
+
@Param({
|
|
310
|
+
title: '每页条数',
|
|
311
|
+
description: '每页条数',
|
|
312
|
+
})
|
|
313
|
+
size: nasl.core.Integer = 2000,
|
|
314
|
+
// ...
|
|
315
|
+
): void {}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
> 参数描述中的 title 和 description 在IDE中不可见,但仍然建议将其作为标识为参数补全。
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
## 6. 子组件描述
|
|
323
|
+
|
|
324
|
+
<div class="highlight">
|
|
325
|
+
|
|
326
|
+
具体请参考文档[父组件和子组件](../component/platform/child.md)。
|
|
327
|
+
|
|
328
|
+
</div>
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|