cdp-material-sdk 0.0.5
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/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/DataScope-B7ffH5qN.js +106 -0
- package/dist/components/core/types.d.ts +16 -0
- package/dist/components/data-scope/DataScope.d.ts +45 -0
- package/dist/constants/event.d.ts +22 -0
- package/dist/context/DataContainerRuntimeContext.d.ts +16 -0
- package/dist/context/DataScopeContext.d.ts +51 -0
- package/dist/context/PageContext.d.ts +26 -0
- package/dist/hooks/useConcurrentLoading.d.ts +16 -0
- package/dist/hooks/useDataContainer.d.ts +61 -0
- package/dist/hooks/useDualLoading.d.ts +22 -0
- package/dist/host-react.d.ts +15 -0
- package/dist/host-react.js +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +42 -0
- package/dist/plugin.d.ts +45 -0
- package/dist/portable.d.ts +20 -0
- package/dist/portable.js +33 -0
- package/dist/protocol/adapter.d.ts +50 -0
- package/dist/protocol/common-schemas.d.ts +64 -0
- package/dist/protocol/events.d.ts +48 -0
- package/dist/protocol/manifest-types.d.ts +10 -0
- package/dist/protocol/manifest.d.ts +144 -0
- package/dist/protocol/traits.d.ts +7 -0
- package/dist/types/category.d.ts +15 -0
- package/dist/utils/mergeInitialValue.d.ts +10 -0
- package/dist/validateManifest-CYqjvQe_.js +355 -0
- package/dist/validation/validateManifest.d.ts +59 -0
- package/docs/component-development/FAQ.md +203 -0
- package/docs/component-development/README.md +176 -0
- package/docs/component-development/getting-started/01-/345/210/233/345/273/272/346/210/226/346/216/245/345/205/245/347/273/204/344/273/266/345/272/223/345/267/245/347/250/213.md +172 -0
- package/docs/component-development/getting-started/02-/345/210/233/345/273/272/347/273/204/344/273/266/345/214/205/345/271/266/346/263/250/345/206/214.md +185 -0
- package/docs/component-development/getting-started/03-/345/274/200/345/217/221/346/234/200/345/260/217/345/217/257/350/277/220/350/241/214/347/273/204/344/273/266.md +196 -0
- package/docs/component-development/getting-started/04-/346/236/204/345/273/272/345/217/221/345/270/203/344/270/216/345/256/277/344/270/273/346/216/245/345/205/245.md +147 -0
- package/docs/component-development/getting-started/05-/350/207/252/346/243/200/344/270/216/346/216/222/351/224/231.md +186 -0
- package/docs/component-development/recipes//344/275/277/347/224/250Adapter/351/200/202/351/205/215/347/273/204/344/273/266API.md +131 -0
- package/docs/component-development/recipes//345/243/260/346/230/216/344/272/213/344/273/266.md +229 -0
- package/docs/component-development/recipes//345/243/260/346/230/216/345/212/250/344/275/234/344/270/216/347/212/266/346/200/201.md +188 -0
- package/docs/component-development/recipes//345/243/260/346/230/216/345/270/203/345/261/200/345/256/271/345/231/250/347/273/204/344/273/266.md +221 -0
- package/docs/component-development/recipes//345/243/260/346/230/216/346/217/222/346/247/275.md +141 -0
- package/docs/component-development/recipes//345/243/260/346/230/216/346/225/260/346/215/256/345/255/227/346/256/265/347/273/204/344/273/266.md +147 -0
- package/docs/component-development/recipes//345/243/260/346/230/216/346/225/260/346/215/256/345/256/271/345/231/250/347/273/204/344/273/266.md +258 -0
- package/docs/component-development/recipes//346/216/245/345/205/245/347/254/254/344/270/211/346/226/271React/347/273/204/344/273/266/345/272/223.md +209 -0
- package/docs/component-development/recipes//351/205/215/347/275/256DOM/346/240/271/350/212/202/347/202/271/346/263/250/345/205/245.md +222 -0
- package/docs/component-development/recipes//351/205/215/347/275/256Loading/347/255/226/347/225/245.md +198 -0
- package/docs/component-development/recipes//351/205/215/347/275/256/350/256/276/350/256/241/345/231/250/345/205/203/344/277/241/346/201/257.md +153 -0
- package/docs/component-development/reference/ActionsState/346/250/241/345/236/213.md +124 -0
- package/docs/component-development/reference/DOM/346/240/271/350/212/202/347/202/271/346/263/250/345/205/245/346/250/241/345/236/213.md +125 -0
- package/docs/component-development/reference/Events/346/250/241/345/236/213.md +170 -0
- package/docs/component-development/reference/Loading/347/255/226/347/225/245/346/250/241/345/236/213.md +140 -0
- package/docs/component-development/reference/Manifest/345/255/227/346/256/265/345/217/202/350/200/203.md +251 -0
- package/docs/component-development/reference/SDK/345/257/274/345/205/245/350/276/271/347/225/214.md +119 -0
- package/docs/component-development/reference/Slots/346/250/241/345/236/213.md +110 -0
- package/docs/component-development/reference/Traits/350/203/275/345/212/233/346/250/241/345/236/213.md +165 -0
- package/docs/component-development/reference/validateManifest/346/240/241/351/252/214/350/247/204/345/210/231.md +171 -0
- package/docs/component-development/reference//345/274/225/346/223/216/345/237/272/347/241/200/350/203/275/345/212/233/346/250/241/345/236/213.md +70 -0
- package/docs/component-development/reference//347/244/272/344/276/213/344/273/243/347/240/201/347/264/242/345/274/225.md +163 -0
- package/package.json +67 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: recipe
|
|
3
|
+
capability: third-party-react
|
|
4
|
+
related:
|
|
5
|
+
- recipes/使用Adapter适配组件API.md
|
|
6
|
+
- recipes/配置DOM根节点注入.md
|
|
7
|
+
- recipes/配置Loading策略.md
|
|
8
|
+
- reference/SDK导入边界.md
|
|
9
|
+
- reference/示例代码索引.md
|
|
10
|
+
---
|
|
11
|
+
# 接入第三方 React 组件库
|
|
12
|
+
|
|
13
|
+
本文说明如何将 Ant Design、Arco、Material UI、ECharts 或自研 UI Kit 中的组件包装成 CDP 组件。
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 适用场景
|
|
18
|
+
|
|
19
|
+
- 你不是从零写 UI,而是包装已有 React 组件。
|
|
20
|
+
- 第三方组件的 props、事件或 loading 名称与 CDP 默认约定不同。
|
|
21
|
+
- 第三方组件没有提供宿主根节点属性注入入口。
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 可以跳过的情况
|
|
26
|
+
|
|
27
|
+
如果你完全控制组件源码,并且组件已经按 CDP 契约接收 `value`、`onChange`、`slotProps.root`,可以直接阅读 [开发最小可运行组件](../getting-started/03-开发最小可运行组件.md)。
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 推荐方式:写一层 CDP Wrapper
|
|
32
|
+
|
|
33
|
+
不要直接把第三方组件裸注册给 CDP。推荐写一个 wrapper:
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { forwardRef } from 'react';
|
|
37
|
+
import { Button } from 'antd';
|
|
38
|
+
import type { BaseUIProps } from 'cdp-material-sdk/portable';
|
|
39
|
+
|
|
40
|
+
export interface AcmeButtonProps extends BaseUIProps<HTMLDivElement> {
|
|
41
|
+
text?: string;
|
|
42
|
+
type?: 'primary' | 'default';
|
|
43
|
+
loading?: boolean;
|
|
44
|
+
onClick?: () => void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const AcmeButton = forwardRef<HTMLDivElement, AcmeButtonProps>((props, ref) => {
|
|
48
|
+
const { text = '按钮', type = 'default', loading, onClick, slotProps } = props;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div {...slotProps?.root} ref={ref}>
|
|
52
|
+
<Button type={type} loading={loading} onClick={onClick}>
|
|
53
|
+
{text}
|
|
54
|
+
</Button>
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
这样做的好处:
|
|
61
|
+
|
|
62
|
+
- CDP 的根节点注入有稳定 DOM 目标。
|
|
63
|
+
- 可以把第三方组件 API 转成 CDP 友好的 props。
|
|
64
|
+
- 后续添加 actions、state、events 更容易。
|
|
65
|
+
- 不需要修改第三方组件源码。
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 场景 1:第三方组件 value / onChange 名称不同
|
|
70
|
+
|
|
71
|
+
例如第三方组件使用:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<ThirdSelect selectedValue={value} onSelectedValueChange={onChange} />
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Wrapper 中转换:
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
export const AcmeSelect = forwardRef<HTMLDivElement, AcmeSelectProps>((props, ref) => {
|
|
81
|
+
const { value, onChange, slotProps } = props;
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div {...slotProps?.root} ref={ref}>
|
|
85
|
+
<ThirdSelect
|
|
86
|
+
selectedValue={value}
|
|
87
|
+
onSelectedValueChange={onChange}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
如果只是 props 名称映射,也可以参考 [使用 Adapter 适配组件 API](./使用Adapter适配组件API.md)。
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 场景 2:第三方组件没有根 DOM 注入入口
|
|
99
|
+
|
|
100
|
+
推荐外层包一层 DOM:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
return (
|
|
104
|
+
<div {...slotProps?.root} ref={ref}>
|
|
105
|
+
<ThirdComponent {...thirdProps} />
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
对应 manifest:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { INJECT_PATH_SLOT_PROPS } from 'cdp-material-sdk/portable';
|
|
114
|
+
|
|
115
|
+
engine: {
|
|
116
|
+
render: {
|
|
117
|
+
injection: {
|
|
118
|
+
rootPath: INJECT_PATH_SLOT_PROPS,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
如果无法包裹或不想改 wrapper,可不声明 `rootPath`,由宿主外层 `<div>` 兜底。但这通常只适合临时接入或黑盒组件。
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 场景 3:第三方组件已有 loading 能力
|
|
129
|
+
|
|
130
|
+
如果第三方组件支持 `loading`:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
engine: {
|
|
134
|
+
render: {
|
|
135
|
+
loading: {
|
|
136
|
+
strategy: 'native',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
如果第三方组件的 loading prop 叫 `spinning`:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
engine: {
|
|
146
|
+
render: {
|
|
147
|
+
loading: {
|
|
148
|
+
strategy: 'native',
|
|
149
|
+
propName: 'spinning',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
注意:`native` 不只是显示动画,组件在 loading 时必须阻断用户交互。
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 场景 4:第三方组件没有 loading 能力
|
|
160
|
+
|
|
161
|
+
使用 wrapper 策略:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
engine: {
|
|
165
|
+
render: {
|
|
166
|
+
loading: {
|
|
167
|
+
strategy: 'wrapper',
|
|
168
|
+
wrapperType: 'spin',
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
宿主会在组件外部渲染遮罩或占位效果。
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 场景 5:第三方组件事件名不同
|
|
179
|
+
|
|
180
|
+
例如第三方组件暴露 `onRowClick`,你希望它成为 CDP 的点击事件或自定义事件。
|
|
181
|
+
|
|
182
|
+
可选方案:
|
|
183
|
+
|
|
184
|
+
1. Wrapper 内转换为 CDP 默认事件 prop。
|
|
185
|
+
2. 使用 `adapter.events` 或 `adapter.customEvents` 映射。
|
|
186
|
+
|
|
187
|
+
详见 [声明事件](./声明事件.md) 和 [使用 Adapter 适配组件 API](./使用Adapter适配组件API.md)。
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 自检
|
|
192
|
+
|
|
193
|
+
- [ ] Wrapper 根节点透传了 `slotProps.root`。
|
|
194
|
+
- [ ] Manifest 声明了正确的 `engine.render.injection.rootPath`。
|
|
195
|
+
- [ ] 第三方组件的 value、事件、loading 名称已转换或通过 adapter 映射。
|
|
196
|
+
- [ ] `validateManifest()` 无 error。
|
|
197
|
+
- [ ] React 相关依赖没有打入 bundle。
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 关联文档
|
|
202
|
+
|
|
203
|
+
本文档只保留本层级职责内容:Recipe 提供任务步骤,Reference 提供稳定模型和规则,validateManifest 文档提供校验级别事实源。
|
|
204
|
+
|
|
205
|
+
- 任务 Recipe:[使用Adapter适配组件API](./使用Adapter适配组件API.md)
|
|
206
|
+
- 任务 Recipe:[配置DOM根节点注入](./配置DOM根节点注入.md)
|
|
207
|
+
- 任务 Recipe:[配置Loading策略](./配置Loading策略.md)
|
|
208
|
+
- SDK 导入边界:[SDK导入边界](../reference/SDK导入边界.md)
|
|
209
|
+
- 示例索引:[示例代码索引](../reference/示例代码索引.md)
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: recipe
|
|
3
|
+
capability: rootpath
|
|
4
|
+
related:
|
|
5
|
+
- reference/引擎基础能力模型.md
|
|
6
|
+
- reference/DOM根节点注入模型.md
|
|
7
|
+
- reference/Manifest字段参考.md
|
|
8
|
+
- reference/validateManifest校验规则.md
|
|
9
|
+
- recipes/接入第三方React组件库.md
|
|
10
|
+
---
|
|
11
|
+
# 配置 DOM 根节点注入
|
|
12
|
+
|
|
13
|
+
DOM 根节点注入用于告诉宿主:组件真实 DOM 根节点应该从 props 的哪个位置接收宿主注入。
|
|
14
|
+
|
|
15
|
+
字段路径:`manifest.engine.render.injection.rootPath`。
|
|
16
|
+
|
|
17
|
+
`rootPath` 是 SDK 字段名。对正式组件来说,DOM 根节点注入是必须确认的交付点。它影响宿主赋予的基础能力能否准确落到组件真实根节点,尤其是设计器选中、路径定位和显隐控制。
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 适用场景
|
|
22
|
+
|
|
23
|
+
- 组件需要被设计器选中、定位或控制显隐。
|
|
24
|
+
- 组件希望宿主把基础能力所需的 props 和 ref 注入到真实 DOM 根节点。
|
|
25
|
+
- 组件包装了第三方组件,需要决定注入到 wrapper 还是内部根节点。
|
|
26
|
+
- 组件需要可靠响应宿主基础显隐能力,例如 `setHidden` 和 `toggleHidden`。
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 可以跳过的情况
|
|
31
|
+
|
|
32
|
+
如果组件是完全黑盒组件,或只是临时接入,可以不声明 `rootPath`。宿主会在外层套 `<div>` 兜底。
|
|
33
|
+
|
|
34
|
+
但正式组件建议显式声明并透传根节点属性。
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 引擎基础能力与 DOM 根节点
|
|
39
|
+
|
|
40
|
+
宿主会为所有组件补充基础能力,包括:
|
|
41
|
+
|
|
42
|
+
| 能力 | 说明 | 组件作者要确认什么 |
|
|
43
|
+
|------|------|-------------------|
|
|
44
|
+
| `hidden` prop | 当前组件是否隐藏 | 不要把它误覆盖成其他语义 |
|
|
45
|
+
| `getHidden` / `setHidden` / `toggleHidden` | 获取、设置、切换显隐状态 | 不要在 manifest 中重复声明同名 action |
|
|
46
|
+
| `hidden` state | 暴露当前显隐状态 | 不要在 manifest 中重复声明同名 state |
|
|
47
|
+
| `mount` / `unmount` events | 基础生命周期事件 | 不需要为普通组件重复声明 |
|
|
48
|
+
|
|
49
|
+
组件作者不需要关心宿主内部如何实现这些能力,只需要确认 DOM 根节点注入位置正确。若 `rootPath` 没有指向真实根节点,显隐、选中框和调试定位都可能偏移。
|
|
50
|
+
|
|
51
|
+
完整模型见 [引擎基础能力模型](../reference/引擎基础能力模型.md)。
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 推荐方式:slotProps.root
|
|
56
|
+
|
|
57
|
+
组件:
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { forwardRef } from 'react';
|
|
61
|
+
import type { BaseUIProps } from 'cdp-material-sdk/portable';
|
|
62
|
+
|
|
63
|
+
export const MyCard = forwardRef<HTMLDivElement, BaseUIProps<HTMLDivElement>>((props, ref) => {
|
|
64
|
+
const { slotProps } = props;
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<div {...slotProps?.root} ref={ref}>
|
|
68
|
+
内容
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Manifest:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { INJECT_PATH_SLOT_PROPS } from 'cdp-material-sdk/portable';
|
|
78
|
+
|
|
79
|
+
engine: {
|
|
80
|
+
render: {
|
|
81
|
+
injection: {
|
|
82
|
+
rootPath: INJECT_PATH_SLOT_PROPS,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
确认点:
|
|
89
|
+
|
|
90
|
+
- `slotProps.root` 必须展开到真实 DOM 节点。
|
|
91
|
+
- `ref` 应落到同一个根 DOM,避免系统属性和 ref 分离。
|
|
92
|
+
- 不要只把 `slotProps.root` 传给不会透传 DOM 属性的第三方 React 组件。
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 直接注入根 props
|
|
97
|
+
|
|
98
|
+
如果组件本身的 props 会直接透传到根 DOM,可以使用 `$root`:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
engine: {
|
|
102
|
+
render: {
|
|
103
|
+
injection: {
|
|
104
|
+
rootPath: '$root',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
适合简单原子组件,但要确认组件不会把系统属性传给错误的内部节点。
|
|
111
|
+
|
|
112
|
+
确认点:
|
|
113
|
+
|
|
114
|
+
- 组件根 props 必须最终透传到真实 DOM。
|
|
115
|
+
- 如果组件内部还有 wrapper 或第三方组件,优先改用 `slotProps.root`。
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 自定义 rootPath
|
|
120
|
+
|
|
121
|
+
如果组件的根 DOM 注入入口在自定义路径上,也可以声明:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
engine: {
|
|
125
|
+
render: {
|
|
126
|
+
injection: {
|
|
127
|
+
rootPath: 'containerProps.root',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
组件必须确保该路径最终透传到真实 DOM:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
const { containerProps } = props;
|
|
137
|
+
|
|
138
|
+
return <section {...containerProps?.root}>内容</section>;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
自定义路径是合法选择。`validateManifest()` 可能会给出提示,提醒作者确认透传是否完成;如果已经按规则实现,可以忽略该提示。
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 不声明 DOM 根节点注入
|
|
146
|
+
|
|
147
|
+
不声明时,宿主会外层包裹 `<div>` 兜底。
|
|
148
|
+
|
|
149
|
+
适合:
|
|
150
|
+
|
|
151
|
+
- 黑盒第三方组件。
|
|
152
|
+
- 临时验证组件。
|
|
153
|
+
- 作者无法控制组件根节点。
|
|
154
|
+
|
|
155
|
+
不适合:
|
|
156
|
+
|
|
157
|
+
- 长期维护的正式组件。
|
|
158
|
+
- 对 DOM 结构、布局、选择态有严格要求的组件。
|
|
159
|
+
- 需要精确显隐控制的组件。
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 选择表
|
|
164
|
+
|
|
165
|
+
| 场景 | 推荐 |
|
|
166
|
+
|------|------|
|
|
167
|
+
| 组件可改源码 | `INJECT_PATH_SLOT_PROPS` |
|
|
168
|
+
| props 会直接透传到根 DOM | `$root` |
|
|
169
|
+
| 第三方组件外层 wrapper | `INJECT_PATH_SLOT_PROPS` |
|
|
170
|
+
| 注入入口是自定义路径 | 自定义 `rootPath` |
|
|
171
|
+
| 完全黑盒组件 | 不声明,使用宿主兜底 |
|
|
172
|
+
|
|
173
|
+
如果不确定,正式组件优先选择 `INJECT_PATH_SLOT_PROPS`,并在组件根 DOM 展开 `slotProps.root`。
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 验收步骤
|
|
178
|
+
|
|
179
|
+
1. 在 manifest 中声明 `engine.render.injection.rootPath`。
|
|
180
|
+
2. 在组件实现中把对应 props 展开到真实根 DOM。
|
|
181
|
+
3. 在宿主中选中该组件,确认选中框与真实视觉区域一致。
|
|
182
|
+
4. 触发显隐控制,确认目标组件的显示/隐藏效果符合预期。
|
|
183
|
+
5. 如果使用自定义路径,确认路径上的 props 没有被中间组件吞掉。
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 自检
|
|
188
|
+
|
|
189
|
+
- [ ] rootPath 指向的 props 最终透传到了真实 DOM。
|
|
190
|
+
- [ ] 设计器选中框、路径定位和真实 DOM 区域一致。
|
|
191
|
+
- [ ] `setHidden` / `toggleHidden` 后,目标组件的显示/隐藏效果符合预期。
|
|
192
|
+
- [ ] 没有在 manifest 中重复声明宿主基础 `hidden` action / state。
|
|
193
|
+
- [ ] 不需要 rootPath 时,确认接受宿主外层 `<div>` 兜底。
|
|
194
|
+
- [ ] `validateManifest()` 没有 error。
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 常见错误
|
|
199
|
+
|
|
200
|
+
### 声明了 `INJECT_PATH_SLOT_PROPS`,但组件没有透传 `slotProps.root`
|
|
201
|
+
|
|
202
|
+
设计器可能无法选中组件,或显隐控制不符合预期。
|
|
203
|
+
|
|
204
|
+
### rootPath 只落到了第三方 React 组件
|
|
205
|
+
|
|
206
|
+
如果第三方组件不透传未知 DOM 属性,宿主注入无法到达真实 DOM。请在外层加 wrapper DOM,并把 `slotProps.root` 展开到 wrapper 上。
|
|
207
|
+
|
|
208
|
+
### 自定义 rootPath 指向了非 DOM 组件
|
|
209
|
+
|
|
210
|
+
系统属性必须最终落到真实 DOM 节点。不要只传给不会透传 DOM 属性的第三方组件。
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 关联文档
|
|
215
|
+
|
|
216
|
+
本文档只保留本层级职责内容:Recipe 提供任务步骤,Reference 提供稳定模型和规则,validateManifest 文档提供校验级别事实源。
|
|
217
|
+
|
|
218
|
+
- 模型参考:[DOM根节点注入模型](../reference/DOM根节点注入模型.md)
|
|
219
|
+
- 模型参考:[引擎基础能力模型](../reference/引擎基础能力模型.md)
|
|
220
|
+
- 字段参考:[Manifest字段参考](../reference/Manifest字段参考.md)
|
|
221
|
+
- 校验规则:[validateManifest校验规则](../reference/validateManifest校验规则.md)
|
|
222
|
+
- 任务 Recipe:[接入第三方React组件库](./接入第三方React组件库.md)
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: recipe
|
|
3
|
+
capability: loading
|
|
4
|
+
related:
|
|
5
|
+
- reference/Loading策略模型.md
|
|
6
|
+
- reference/Manifest字段参考.md
|
|
7
|
+
- reference/validateManifest校验规则.md
|
|
8
|
+
- recipes/声明动作与状态.md
|
|
9
|
+
---
|
|
10
|
+
# 配置 Loading 策略
|
|
11
|
+
|
|
12
|
+
Loading 策略用于声明宿主如何控制组件加载态。
|
|
13
|
+
|
|
14
|
+
字段路径:`manifest.engine.render.loading`。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 适用场景
|
|
19
|
+
|
|
20
|
+
- 组件需要响应外部流程的 `setLoading`。
|
|
21
|
+
- 组件已有 loading prop,需要让宿主接管。
|
|
22
|
+
- 组件没有 loading 能力,希望宿主用遮罩兜底。
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 可以跳过的情况
|
|
27
|
+
|
|
28
|
+
- 组件不需要被外部流程控制 Loading。
|
|
29
|
+
- 组件内部有复杂异步状态,并且不希望宿主接管。
|
|
30
|
+
- 组件只是静态展示。
|
|
31
|
+
|
|
32
|
+
不声明时等价于不启用 Loading Feature。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 策略总览
|
|
37
|
+
|
|
38
|
+
| 策略 | 适合场景 | 宿主行为 |
|
|
39
|
+
|------|----------|----------|
|
|
40
|
+
| `native` | 组件已有 loading prop | 注入 `loading` 或 `propName` 指定的 prop |
|
|
41
|
+
| `wrapper` | 组件没有 loading prop,但可以整体遮罩 | 渲染外层遮罩或占位 |
|
|
42
|
+
| `none` | 组件内部自控 loading | 宿主不接管 |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## native
|
|
47
|
+
|
|
48
|
+
适合 Button、Select、Upload 等已有 loading prop 的组件。
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
engine: {
|
|
52
|
+
render: {
|
|
53
|
+
loading: {
|
|
54
|
+
strategy: 'native',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
如果 prop 名不是 `loading`:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
engine: {
|
|
64
|
+
render: {
|
|
65
|
+
loading: {
|
|
66
|
+
strategy: 'native',
|
|
67
|
+
propName: 'spinning',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
作者职责:
|
|
74
|
+
|
|
75
|
+
- 组件必须接收对应 loading prop。
|
|
76
|
+
- loading 为 true 时,组件必须阻断用户交互。
|
|
77
|
+
- 不要只显示动画但仍允许点击或输入。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## wrapper
|
|
82
|
+
|
|
83
|
+
适合 Card、Chart、PreviewPanel 等没有 loading prop 的展示组件。
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
engine: {
|
|
87
|
+
render: {
|
|
88
|
+
loading: {
|
|
89
|
+
strategy: 'wrapper',
|
|
90
|
+
wrapperType: 'spin',
|
|
91
|
+
wrapperProps: {
|
|
92
|
+
size: 'large',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
当前内置 `wrapperType`:
|
|
100
|
+
|
|
101
|
+
| wrapperType | 说明 |
|
|
102
|
+
|-------------|------|
|
|
103
|
+
| `wave` | 默认通用遮罩 |
|
|
104
|
+
| `spin` | 常规加载中 |
|
|
105
|
+
| `skeleton` | 骨架屏占位 |
|
|
106
|
+
| 自定义组件 type | 宿主注册过对应 wrapper 组件时使用 |
|
|
107
|
+
|
|
108
|
+
`spin` 和 `wave` 可使用 `setLoading({ loading: true, text })` 的 `text` 参数。`skeleton` 不使用提示文字。
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## none
|
|
113
|
+
|
|
114
|
+
适合 Table、TreeTable、AsyncSelect、复杂业务面板等内部 loading 状态复杂的组件。
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
engine: {
|
|
118
|
+
render: {
|
|
119
|
+
loading: {
|
|
120
|
+
strategy: 'none',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
如果仍希望外部流程能控制组件 loading,请自己声明并实现 actions:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
actions: {
|
|
130
|
+
setLoading: {
|
|
131
|
+
title: '设置加载状态',
|
|
132
|
+
params: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
required: ['loading'],
|
|
135
|
+
properties: {
|
|
136
|
+
loading: { type: 'boolean', title: '是否加载中' },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
returns: { type: 'boolean' },
|
|
140
|
+
},
|
|
141
|
+
getLoading: {
|
|
142
|
+
title: '获取加载状态',
|
|
143
|
+
returns: { type: 'boolean' },
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 选择表
|
|
151
|
+
|
|
152
|
+
| 组件情况 | 推荐策略 |
|
|
153
|
+
|----------|----------|
|
|
154
|
+
| 已有 `loading` prop,且能禁用交互 | `native` |
|
|
155
|
+
| loading prop 名不是 `loading` | `native + propName` |
|
|
156
|
+
| 没有 loading prop,但可以整体遮罩 | `wrapper` |
|
|
157
|
+
| 适合骨架屏 | `wrapper + skeleton` |
|
|
158
|
+
| 内部有复杂异步状态 | `none` |
|
|
159
|
+
| 复杂组件仍需外部控制 loading | `none + 自定义 actions` |
|
|
160
|
+
| 不确定 | 优先 `wrapper` |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 自检
|
|
165
|
+
|
|
166
|
+
- [ ] 字段路径写成 `engine.render.loading`。
|
|
167
|
+
- [ ] `native` 模式下组件能接收 loading prop,并阻断交互。
|
|
168
|
+
- [ ] `propName` 与组件实际 prop 名一致。
|
|
169
|
+
- [ ] `wrapper` 模式下组件可以被整体遮罩。
|
|
170
|
+
- [ ] `none` 模式下没有误以为宿主会自动注入 loading。
|
|
171
|
+
- [ ] `validateManifest()` 没有 error。
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 常见错误
|
|
176
|
+
|
|
177
|
+
### 把 `loading` 写成 `manifest.engine.loading`
|
|
178
|
+
|
|
179
|
+
正确路径是 `manifest.engine.render.loading`。
|
|
180
|
+
|
|
181
|
+
### native 模式只显示动画,不阻断交互
|
|
182
|
+
|
|
183
|
+
这是组件实现问题。`native` 要求组件在 loading 时不可继续触发用户操作。
|
|
184
|
+
|
|
185
|
+
### Table 使用 wrapper 后局部 loading 体验不符合预期
|
|
186
|
+
|
|
187
|
+
复杂数据组件通常应使用 `none`,由组件内部管理 loading。
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 关联文档
|
|
192
|
+
|
|
193
|
+
本文档只保留本层级职责内容:Recipe 提供任务步骤,Reference 提供稳定模型和规则,validateManifest 文档提供校验级别事实源。
|
|
194
|
+
|
|
195
|
+
- 模型参考:[Loading策略模型](../reference/Loading策略模型.md)
|
|
196
|
+
- 字段参考:[Manifest字段参考](../reference/Manifest字段参考.md)
|
|
197
|
+
- 校验规则:[validateManifest校验规则](../reference/validateManifest校验规则.md)
|
|
198
|
+
- 任务 Recipe:[声明动作与状态](./声明动作与状态.md)
|