fix: doc format issues, replace wrong links, replace image cdn

This commit is contained in:
JackLian 2022-12-01 16:58:35 +08:00 committed by 刘菊萍(絮黎)
parent 21d5460fd8
commit 7674e27f83
79 changed files with 1772 additions and 1255 deletions

View File

@ -65,7 +65,7 @@ window.AliLowCodeEngine.project.openDocument('docl4xkca5b')
期望: 期望:
- 页面中的xxx部分和预期不符合期望的效果是 xxx - 页面中的 xxx 部分和预期不符合,期望的效果是 xxx
#### 【支持稍慢】通过线上 demo + 完整操作步骤可复现 #### 【支持稍慢】通过线上 demo + 完整操作步骤可复现
**示例** **示例**

View File

@ -43,7 +43,7 @@ common.utils.startTransaction(() => {
``` ```
### createIntl ### createIntl
i18n相关工具 i18n 相关工具
*引擎版本 >= 1.0.17 *引擎版本 >= 1.0.17
```typescript ```typescript
import { common } from '@alilc/lowcode-engine'; import { common } from '@alilc/lowcode-engine';

View File

@ -4,7 +4,7 @@ sidebar_position: 12
--- ---
### 请求数据源 ### 请求数据源
```javascript ```javascript
// 请求userList userList在数据源面板中定义 // 请求 userListuserList 在数据源面板中定义)
this.dataSourceMap['userList'].load({ this.dataSourceMap['userList'].load({
data: {} data: {}
@ -22,7 +22,7 @@ const { userList } = this.state;
// 获取数据源面板中定义的值 // 获取数据源面板中定义的值
const { user } = this.state; const { user } = this.state;
// 修改state值 // 修改 state
this.setState({ this.setState({
user: {} user: {}
}); });

View File

@ -74,7 +74,7 @@ import { event } from '@alilc/lowcode-engine';
class SetterB extends React.Component { class SetterB extends React.Component {
bindFunction = () => { bindFunction = () => {
const { field, value } = this.props; const { field, value } = this.props;
// 这里展示的和插件进行通信, 事件规则是插件名 + 方法 // 这里展示的和插件进行通信事件规则是插件名 + 方法
event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); event.emit('eventBindDialog.openDialog', field.name, this.emitEventName);
} }
} }

View File

@ -41,7 +41,7 @@ interface EngineOptions {
*/ */
enableCanvasLock?: boolean; enableCanvasLock?: boolean;
/** /**
* 容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效, 默认值为false * 容器锁定后容器本身是否可以设置属性仅当画布锁定特性开启时生效默认值为false
*/ */
enableLockedNodeSetting?: boolean; enableLockedNodeSetting?: boolean;
/** /**

View File

@ -35,7 +35,7 @@ import { logger } from '@alilc/lowcode-engine';
// 内部实现logger = getLogger({ level: 'warn', bizName: 'designer:pluginManager' }) // 内部实现logger = getLogger({ level: 'warn', bizName: 'designer:pluginManager' })
// 若在url query中增加 `__logConf__` 可改变打印日志级别和限定业务类型日志 // 若在 url query 中增加 `__logConf__` 可改变打印日志级别和限定业务类型日志
// 默认__logConf__=warn:* // 默认__logConf__=warn:*
logger.log('log'); // 不输出 logger.log('log'); // 不输出
logger.warn('warn'); // 输出 logger.warn('warn'); // 输出

View File

@ -12,7 +12,7 @@ sidebar_position: 2
# 方法签名functions # 方法签名functions
## 资产包 ## 资产包
### setAssets ### setAssets
设置「[资产包](https://www.yuque.com/lce/doc/vgcyf1)」结构 设置「[资产包](/site/docs/specs/lowcode-spec#2-协议结构)」结构
**类型定义** **类型定义**
```typescript ```typescript

View File

@ -83,7 +83,7 @@ interface AltStringSetterProps {
value: string; value: string;
// 默认值 // 默认值
initialValue: string; initialValue: string;
// setter唯一输出 // setter 唯一输出
onChange: (val: string) => void; onChange: (val: string) => void;
// AltStringSetter 特殊配置 // AltStringSetter 特殊配置
placeholder: string; placeholder: string;
@ -254,7 +254,7 @@ interface AltStringSetterProps {
value: string; value: string;
// 默认值 // 默认值
initialValue: string; initialValue: string;
// setter唯一输出 // setter 唯一输出
onChange: (val: string) => void; onChange: (val: string) => void;
// AltStringSetter 特殊配置 // AltStringSetter 特殊配置
placeholder: string; placeholder: string;

View File

@ -3,23 +3,57 @@ title: skeleton - 面板 API
sidebar_position: 1 sidebar_position: 1
--- ---
## 模块简介 ## 模块简介
面板 API 提供了面板扩展和管理的能力,如下图蓝色内容都是扩展出来的。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645442085447-d1822e7f-9e5a-4e06-a770-04b1023d5daf.png#clientId=u9aca70b6-1a98-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=498&id=u2dd3deb2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=996&originWidth=1780&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1549904&status=done&style=none&taskId=u28659b69-981c-416e-bed6-b2f06b8e6fc&title=&width=890)<br />页面上可以扩展的区域共 5 个,具体如下:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645431386085-2710d33d-0652-450a-a993-c804368da1ce.png#clientId=u1724eb73-4c0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=ud138f866&margin=%5Bobject%20Object%5D&name=image.png&originHeight=974&originWidth=1892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=228235&status=done&style=none&taskId=u265d50a5-3700-406e-84b2-0158ebadaae&title=&width=946) 面板 API 提供了面板扩展和管理的能力,如下图蓝色内容都是扩展出来的。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645442085447-d1822e7f-9e5a-4e06-a770-04b1023d5daf.png#clientId=u9aca70b6-1a98-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=498&id=u2dd3deb2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=996&originWidth=1780&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1549904&status=done&style=none&taskId=u28659b69-981c-416e-bed6-b2f06b8e6fc&title=&width=890)
页面上可以扩展的区域共 5 个,具体如下:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645431386085-2710d33d-0652-450a-a993-c804368da1ce.png#clientId=u1724eb73-4c0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=ud138f866&margin=%5Bobject%20Object%5D&name=image.png&originHeight=974&originWidth=1892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=228235&status=done&style=none&taskId=u265d50a5-3700-406e-84b2-0158ebadaae&title=&width=946)
### 基本概念 ### 基本概念
#### 扩展区域位置(area) #### 扩展区域位置 (area)
##### topArea ##### topArea
展示在设计器的顶部区域,常见的相关区域的插件主要是:<br />1注册设计器 Logo<br />2设计器操作回退和撤销按钮<br />3全局操作按钮例如保存、预览等
展示在设计器的顶部区域,常见的相关区域的插件主要是:
1. 注册设计器 Logo
2. 设计器操作回退和撤销按钮;
3. 全局操作按钮,例如:保存、预览等;
##### leftArea ##### leftArea
左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。<br />该区域相关插件的主要有:<br />1大纲树展示展示该设计器设计页面的大纲。<br />2组件库展示注册到设计器中的组件点击之后可以从组件库面板中拖拽到设计器的画布中。<br />3数据源面板<br />4JS 等代码面板。<br />可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。
左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。
该区域相关插件的主要有:
1. 大纲树展示,展示该设计器设计页面的大纲。
2. 组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。
3. 数据源面板
4. JS 等代码面板。
可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。
##### centerArea ##### centerArea
画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有:<br />1画布大小修改<br />2物料选中扩展区域修改
画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有:
1. 画布大小修改
2. 物料选中扩展区域修改
##### rightArea ##### rightArea
右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。
##### toolbar ##### toolbar
跟 topArea 类似,按需放置面板插件~ 跟 topArea 类似,按需放置面板插件~
#### 展示类型(type) #### 展示类型 (type)
展示类型用于区分插件在设计器内可操作的几种不同界面类型。主要的几种类型为PanelDock、Widget、Dock另有Panel类型目前不推荐使用。
展示类型用于区分插件在设计器内可操作的几种不同界面类型。主要的几种类型为 PanelDock、Widget、Dock另有 Panel 类型目前不推荐使用。
##### PanelDock ##### PanelDock
PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。<br />下图是组件库插件的展示效果。<br />![Feb-08-2022 19-44-15.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644320663827-ee9c54a1-f684-40e2-8a6b-875103d04b31.gif#clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=555&id=u5292d9cc&margin=%5Bobject%20Object%5D&name=Feb-08-2022%2019-44-15.gif&originHeight=790&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1381641&status=done&style=stroke&taskId=ub28a13a4-3d80-4a02-bcaa-cc9d6127243&title=&width=1080)<br />其中右上角可以进行固定,可以对弹出的宽度做设定<br />接入可以参考代码
PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。
下图是组件库插件的展示效果。
![Feb-08-2022 19-44-15.gif](https://img.alicdn.com/imgextra/i2/O1CN01i66G5O27bK37nlpxV_!!6000000007815-1-tps-1536-790.gif)
其中右上角可以进行固定,可以对弹出的宽度做设定
接入可以参考代码
```javascript ```javascript
import { skeleton } from "@alilc/lowcode-engine"; import { skeleton } from "@alilc/lowcode-engine";
@ -31,7 +65,7 @@ skeleton.add({
props: { props: {
align: "left", align: "left",
icon: "wenjian", icon: "wenjian",
description: "JS面板", description: "JS 面板",
}, },
panelProps: { panelProps: {
floatable: true, // 是否可浮动 floatable: true, // 是否可浮动
@ -39,13 +73,18 @@ skeleton.add({
hideTitleBar: false, hideTitleBar: false,
maxHeight: 800, maxHeight: 800,
maxWidth: 1200, maxWidth: 1200,
title: "JS面板", title: "JS 面板",
width: 600, width: 600,
}, },
}); });
``` ```
##### Widget ##### Widget
Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320068765-47efc836-30c2-452f-8104-b98b1ea3533d.png#clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=51&id=P60UE&margin=%5Bobject%20Object%5D&name=image.png&originHeight=94&originWidth=1988&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58410&status=done&style=stroke&taskId=u4eadd643-2e63-4be7-8736-b27b9c82b81&title=&width=1080)<br />接入可以参考代码: Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01IRQIZp1m5AJPwBKDv_!!6000000004902-2-tps-1988-94.png)
接入可以参考代码:
```javascript ```javascript
import {skeleton} from "@alilc/lowcode-engine"; import {skeleton} from "@alilc/lowcode-engine";
// 注册 logo 面板 // 注册 logo 面板
@ -53,8 +92,8 @@ skeleton.add({
area: "topArea", area: "topArea",
type: "Widget", type: "Widget",
name: "logo", name: "logo",
content: Logo, // Widget 组件实例 content: Logo, // Widget 组件实例
contentProps: { // Widget 插件props contentProps: { // Widget 插件 props
logo: logo:
"https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png", "https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png",
href: "/", href: "/",
@ -66,7 +105,9 @@ skeleton.add({
}); });
``` ```
##### Dock ##### Dock
一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景
一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景。
```javascript ```javascript
import { skeleton } from "@alilc/lowcode-engine"; import { skeleton } from "@alilc/lowcode-engine";
@ -75,7 +116,7 @@ skeleton.add({
type: "Dock", type: "Dock",
name: "opener", name: "opener",
content: Opener, // Widget 组件实例 content: Opener, // Widget 组件实例
contentProps: { // Widget 插件props contentProps: { // Widget 插件 props
xxx: "1", xxx: "1",
}, },
props: { props: {
@ -89,11 +130,14 @@ skeleton.add({
} }
}); });
``` ```
#### <br />
## 变量variables ## 变量variables
## 方法签名functions ## 方法签名functions
### 1. add ### 1. add
```tsx ```tsx
add(config: IWidgetBaseConfig & { add(config: IWidgetBaseConfig & {
area?: string; area?: string;
@ -116,8 +160,6 @@ IWidgetBaseConfig 定义如下:
| index | 面板的位置,不传默认按插件注册顺序 | | | index | 面板的位置,不传默认按插件注册顺序 | |
### 2. remove ### 2. remove
remove(config: IWidgetBaseConfig) remove(config: IWidgetBaseConfig)
@ -150,13 +192,17 @@ hideWidget(name: string)
enableWidget(name: string) enableWidget(name: string)
将 widget 启用。<br />注:该函数将会触发全局事件 'skeleton.widget.enable' 将 widget 启用。
注:该函数将会触发全局事件 'skeleton.widget.enable'
### 8. disableWidget ### 8. disableWidget
disableWidget(name: string) disableWidget(name: string)
将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。<br />适用场景:在该面板还在进行初始化构造时,可以先禁止掉,防止用户点击报错,待初始化完成,重新启用。 将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。
适用场景:在该面板还在进行初始化构造时,可以先禁止掉,防止用户点击报错,待初始化完成,重新启用。
## 事件events ## 事件events
### 1. onShowPanel ### 1. onShowPanel
@ -166,7 +212,8 @@ onShowPanel(listener: (...args: unknown[]) => void)
监听 Panel 实例显示事件 监听 Panel 实例显示事件
### 2. onHidePanel ### 2. onHidePanel
<br />onHidePanel(listener: (...args: unknown[]) => void)
onHidePanel(listener: (...args: unknown[]) => void)
监听 Panel 实例隐藏事件 监听 Panel 实例隐藏事件
@ -177,10 +224,12 @@ onShowWidget(listener: (...args: unknown[]) => void)
监听 Widget 实例显示事件 监听 Widget 实例显示事件
### 4. onHideWidget ### 4. onHideWidget
<br />onHideWidget(listener: (...args: unknown[]) => void)
onHideWidget(listener: (...args: unknown[]) => void)
监听 Widget 实例隐藏事件 监听 Widget 实例隐藏事件
## 使用示例 ## 使用示例
```typescript ```typescript
import { skeleton } from '@alilc/lowcode-engine'; import { skeleton } from '@alilc/lowcode-engine';
@ -199,7 +248,7 @@ skeleton.add({
props: { props: {
align: 'top', align: 'top',
icon: 'wenjian', icon: 'wenjian',
description: 'JS面板', description: 'JS 面板',
}, },
panelProps: { panelProps: {
floatable: true, floatable: true,
@ -208,7 +257,7 @@ skeleton.add({
hideTitleBar: false, hideTitleBar: false,
maxHeight: 800, maxHeight: 800,
maxWidth: 1200, maxWidth: 1200,
title: 'JS面板', title: 'JS 面板',
width: 600, width: 600,
}, },
content: SourceEditor, content: SourceEditor,

View File

@ -13,13 +13,13 @@ title: 低代码引擎相关文章资料
- [2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) - [2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw)
- [阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA) - [阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA)
## Portal设计项目实战 ## Portal 设计项目实战
#### 直播回放 #### 直播回放
[https://www.bilibili.com/video/BV1AS4y1K7DP/](https://www.bilibili.com/video/BV1AS4y1K7DP/) [https://www.bilibili.com/video/BV1AS4y1K7DP/](https://www.bilibili.com/video/BV1AS4y1K7DP/)
#### 示例项目 #### 示例项目
- 前端: [https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) - 前端 [https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal)
- 后端: [https://github.com/mark-ck/document-solution-site](https://github.com/mark-ck/document-solution-site) - 后端 [https://github.com/mark-ck/document-solution-site](https://github.com/mark-ck/document-solution-site)
- 组件库:[https://github.com/mark-ck/portal-components](https://github.com/mark-ck/portal-components) - 组件库:[https://github.com/mark-ck/portal-components](https://github.com/mark-ck/portal-components)
**注意** **注意**
@ -27,12 +27,12 @@ title: 低代码引擎相关文章资料
2. 后端项目要把 config.default.js 里的 yuque 和 oss 配置补全; 2. 后端项目要把 config.default.js 里的 yuque 和 oss 配置补全;
#### 视频链接 #### 视频链接
- [阿里低代码引擎项目实战(1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) - [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/)
- [【有翻车】阿里低代码引擎项目实战(2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) - [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/)
- [阿里巴巴低代码引擎项目实战(3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) - [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/)
- [阿里低代码引擎项目实战(4)-自定义插件-页面管理](https://www.bilibili.com/video/BV17a411i73f/) - [阿里低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/)
- [阿里低代码引擎项目实战(4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/) - [阿里低代码引擎项目实战 (4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/)
- [【有翻车】阿里低代码引擎项目实战(5)-表单回显](https://www.bilibili.com/video/BV1UY4y1v7D7/) - [【有翻车】阿里低代码引擎项目实战 (5)-表单回显](https://www.bilibili.com/video/BV1UY4y1v7D7/)
- [阿里低代码引擎项目实战(6)-自定义插件-页面管理-后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) - [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/)
- [阿里低代码引擎项目实战(6)-自定义插件-页面管理-前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) - [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/)
- [阿里低代码引擎项目实战(7)-自定义插件-页面管理(完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/) - [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/)

View File

@ -3,15 +3,15 @@ title: 如何使用循环值
sidebar_position: 0 sidebar_position: 0
--- ---
1.设置循环数据 1.设置循环数据
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975447215-026bd3ae-ae2a-4f90-805e-df0d5c4bb7d2.png#clientId=ubd100ffc-952a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=950&id=u6413eee5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1900&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=339030&status=done&style=none&taskId=ued46d732-83a2-441f-a80f-23061587689&title=&width=1920) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01Gw1kXO1qaXulQCWap_!!6000000005512-2-tps-3840-1900.png)
2.给需要的变量绑定 this.item 2.给需要的变量绑定 this.item
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975499246-f9d14ef4-6736-46a5-8b24-8eedd4477617.png#clientId=ubd100ffc-952a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=946&id=u0b50f02a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1892&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=451804&status=done&style=none&taskId=uf4916102-2e3d-4277-ac81-604c6761615&title=&width=1920) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01RpP2Ev24lRxjqpHdY_!!6000000007431-2-tps-3840-1892.png)
绑定之后的效果如下: 绑定之后的效果如下:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975540038-ccf3aabc-3f7c-4e33-a701-a9b005b1cf25.png#clientId=uc887596b-8aed-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=942&id=u32901b3a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1884&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=333998&status=done&style=none&taskId=u2853d459-4432-4d0a-ba12-494e79e892a&title=&width=1920) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN019qa1J31m7ugsXcnaA_!!6000000004908-2-tps-3840-1884.png)
其中 this.item 的 item 是可以配置的。配置不同的 key 可以方便在多层循环中使用不同层级的循环 item 值。 其中 this.item 的 item 是可以配置的。配置不同的 key 可以方便在多层循环中使用不同层级的循环 item 值。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975569197-33d90389-7394-4e65-bc6a-582b7ceb9fee.png#clientId=uc887596b-8aed-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=948&id=u6e6741d2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1896&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=311961&status=done&style=none&taskId=u14bbcfbb-e7cf-4307-a58d-3cb58afe8f7&title=&width=1920) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XQfnYL1P4wxn01oXv_!!6000000001788-2-tps-3840-1896.png)
this.index 是当前循环的索引值。 this.index 是当前循环的索引值。

View File

@ -29,7 +29,7 @@ sidebar_position: 0
它们操作的数据关系是: 它们操作的数据关系是:
- 页面中的 Schema 数据:保存在低代码引擎中的 Schema点击 Schema 面板中的“保存 Schema” 时将修改引擎中的值,此外低代码引擎中的所有操作都可能修改到 Schema - 页面中的 Schema 数据:保存在低代码引擎中的 Schema点击 Schema 面板中的“保存 Schema”时将修改引擎中的值此外低代码引擎中的所有操作都可能修改到 Schema
- localStorage 数据:由“保存到本地”保存到 localStorage 中,页面初始化时将读取,预览页面时也会读取 - localStorage 数据:由“保存到本地”保存到 localStorage 中,页面初始化时将读取,预览页面时也会读取
- 默认 Schema保存在 Demo 项目中的默认 Schema`public/schema.json`),初始化页面时如果不存在 localStorage 数据即会读取,点击“重置页面”时,也会读取 - 默认 Schema保存在 Demo 项目中的默认 Schema`public/schema.json`),初始化页面时如果不存在 localStorage 数据即会读取,点击“重置页面”时,也会读取

View File

@ -2,28 +2,28 @@
title: 3. 如何通过按钮展示/隐藏弹窗 title: 3. 如何通过按钮展示/隐藏弹窗
sidebar_position: 1 sidebar_position: 1
--- ---
### 1.拖拽一个按钮 ## 1.拖拽一个按钮
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355202273-1a84b1e5-e33c-4686-b92b-633936423141.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=906&id=u81f6abfa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1812&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=749009&status=done&style=none&taskId=u6f4bf7e1-db67-4fca-8107-04021936c00&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01kLaWA31D6WwTui9VW_!!6000000000167-2-tps-3584-1812.png)
### 2.拖拽一个弹窗 ## 2.拖拽一个弹窗
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355233863-6d65ee77-b2fa-4d51-a04c-f0582c99eb72.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=811&id=u848a34e1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1622&originWidth=3578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=774132&status=done&style=none&taskId=ue713e331-7ce0-4bd8-b41d-3ae1e07c69b&title=&width=1789) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01rfRzLa1quEwUyulPc_!!6000000005555-2-tps-3578-1622.png)
### 3.查看弹窗 refId ## 3.查看弹窗 refId
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355269097-3e5282ed-2fdd-4a3b-b9b8-d78fac69c42e.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=794&id=ufd9346c1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1588&originWidth=3574&originalType=binary&ratio=1&rotation=0&showTitle=false&size=843332&status=done&style=none&taskId=ubc630826-e577-4dee-a2c3-5478bdf266a&title=&width=1787) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01rEgPnW1cSqdWpG0YE_!!6000000003600-2-tps-3574-1588.png)
- 点击弹窗 - 点击弹窗
- 点击右侧面板中的高级 - 点击右侧面板中的高级
- 找到 refId - 找到 refId
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355320821-dd2c85f7-a75e-495d-896a-67e4761561ac.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=898&id=u4bf6b721&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1796&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=993930&status=done&style=none&taskId=u8c648fa2-c660-4979-8991-1cf138d2372&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01MXMfqn1rj4uKzlOh2_!!6000000005666-2-tps-3584-1796.png)
这里我们的 refId 是 "pro-dialog-entryl32xgrus" 这里我们的 refId 是 "pro-dialog-entryl32xgrus"
### 4.隐藏弹窗 ## 4.隐藏弹窗
点击工具栏的隐藏小图标,将弹窗在画布中隐藏 点击工具栏的隐藏小图标,将弹窗在画布中隐藏
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355400766-f7bdca37-7ba9-497d-a7e2-ad1d92233a26.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=784&id=ucbbe5086&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1568&originWidth=3578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=774518&status=done&style=none&taskId=u2c8e73cd-10c5-47d3-b96e-30e6840d1af&title=&width=1789) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN017Kamt71HFvWkpeK8j_!!6000000000729-2-tps-3578-1568.png)
### 5.按钮绑定事件 ## 5.按钮绑定事件
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355486231-172c5797-c376-4f6f-94f7-8c3c593caa02.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=907&id=ufcf7d50e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1814&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=845218&status=done&style=none&taskId=u7c2c54ce-9c18-4b29-a066-f3024a95443&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01SwJ0xx1u3LfX2h8yt_!!6000000005981-2-tps-3584-1814.png)
**通过下面的代码即可打开弹窗** **通过下面的代码即可打开弹窗**

View File

@ -2,30 +2,33 @@
title: 2. 如何制作表格 title: 2. 如何制作表格
sidebar_position: 0 sidebar_position: 0
--- ---
# 步骤详解 ## 步骤详解
## 拖入组件 ### 拖入组件
一个常见的表格页面会包含查询框、表格和分页按钮。这些都在 Fusion UI 中进行了相应的封装,我们可以在左侧组件面板处找到他们。 一个常见的表格页面会包含查询框、表格和分页按钮。这些都在 Fusion UI 中进行了相应的封装,我们可以在左侧组件面板处找到他们。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645011856718-ed2aa0b1-0c5c-4ec0-a72b-377bc500faf3.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=824&id=ue90ea461&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=3032&originalType=binary&ratio=1&rotation=0&showTitle=false&size=963971&status=done&style=stroke&taskId=u3b1dfd98-44b7-4a13-be2a-e0124084288&title=&width=1516)
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01UU8pVT26XN1A0ExVG_!!6000000007671-2-tps-3032-1648.png)
将他们拖到画布之中: 将他们拖到画布之中:
![Feb-16-2022 16-58-59.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645002115004-4f01eb8d-cf68-4a7c-b0db-bc5aaf2604a3.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=uf69dc239&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2016-58-59.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7510570&status=done&style=stroke&taskId=ua6ea2651-6c6c-4762-98cc-cc3ab5734cd&title=&width=767) ![Feb-16-2022 16-58-59.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645002115004-4f01eb8d-cf68-4a7c-b0db-bc5aaf2604a3.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=uf69dc239&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2016-58-59.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7510570&status=done&style=stroke&taskId=ua6ea2651-6c6c-4762-98cc-cc3ab5734cd&title=&width=767)
## 配置组件 ### 配置组件
选中刚拖入的“查询筛选”组件,您可以配置此组件: 选中刚拖入的“查询筛选”组件,您可以配置此组件:
![Feb-14-2022 17-59-47.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644832912542-4b2e66ae-ba15-4e38-ab79-9f83e413a493.gif#clientId=uec0ffd6f-d4e1-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u83c491b2&margin=%5Bobject%20Object%5D&name=Feb-14-2022%2017-59-47.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2147213&status=done&style=stroke&taskId=uffd7092e-a247-4f48-b831-aaffe3646f7&title=) ![Feb-14-2022 17-59-47.gif](https://img.alicdn.com/imgextra/i2/O1CN01RiDUy31aufSeVk8IN_!!6000000003390-1-tps-1532-792.gif)
对于形如 Array 的配置项目,我们可以增删项目、修改常用项、修改顺序。 对于形如 Array 的配置项目,我们可以增删项目、修改常用项、修改顺序。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012184644-444d82fa-a226-4784-b0df-92a5a52748bc.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=738&id=uc4ea8ded&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1476&originWidth=3060&originalType=binary&ratio=1&rotation=0&showTitle=false&size=375890&status=done&style=none&taskId=u7a1f43d8-eac4-405e-a3c9-38d3047f452&title=&width=1530) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01eWOK0d1fOfsF9PZu9_!!6000000003997-2-tps-3060-1476.png)
掌握组件配置功能,我们就可以完成一个常用的查询框的配置: 掌握组件配置功能,我们就可以完成一个常用的查询框的配置:
![Feb-21-2022 18-05-52.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645437973453-1fd1dc10-99ad-4c18-af49-2741bd81c4ae.gif#clientId=u022fc577-71a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u964ae52f&margin=%5Bobject%20Object%5D&name=Feb-21-2022%2018-05-52.gif&originHeight=790&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7210902&status=done&style=stroke&taskId=u9e39c54a-7467-4a96-b716-681cf598f09&title=&width=766) ![Feb-21-2022 18-05-52.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645437973453-1fd1dc10-99ad-4c18-af49-2741bd81c4ae.gif#clientId=u022fc577-71a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u964ae52f&margin=%5Bobject%20Object%5D&name=Feb-21-2022%2018-05-52.gif&originHeight=790&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7210902&status=done&style=stroke&taskId=u9e39c54a-7467-4a96-b716-681cf598f09&title=&width=766)
## 绑定数据 ### 绑定数据
低代码场景下,我们需要绑定动态的数据。通过左侧的源码编辑面板,我们可以创建动态数据和它的相关处理函数: 低代码场景下,我们需要绑定动态的数据。通过左侧的源码编辑面板,我们可以创建动态数据和它的相关处理函数:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012532562-596d4a96-908e-4094-836c-974bda61d8a2.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=739&id=ufa7b81f8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1478&originWidth=2976&originalType=binary&ratio=1&rotation=0&showTitle=false&size=816197&status=done&style=none&taskId=u5ab9656e-26b6-427a-a52e-5e11dbc4a7a&title=&width=1488) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN015Bw2aQ1jaMRWoYzv5_!!6000000004564-2-tps-2976-1478.png)
如图,我们配入如下自定义值进 state 里: 如图,我们配入如下自定义值进 state 里:
```json ```json
"companies": [ "companies": [
@ -35,18 +38,25 @@ sidebar_position: 0
] ]
``` ```
定义动态数据以后,我们需要绑定它到组件的属性中,我们找到相关属性的配置: 定义动态数据以后,我们需要绑定它到组件的属性中,我们找到相关属性的配置:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012714358-f3f39d5f-1790-4196-9f16-b45f51fa8f28.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=896&id=u1126fd65&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1792&originWidth=3546&originalType=binary&ratio=1&rotation=0&showTitle=false&size=413958&status=done&style=none&taskId=u976689ac-18a1-4f15-9fc2-60681670fc7&title=&width=1773)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012791356-4fed1bea-bec2-4be9-85ea-b366d0acb4ab.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=820&id=ub81b6dc8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1640&originWidth=3428&originalType=binary&ratio=1&rotation=0&showTitle=false&size=354847&status=done&style=none&taskId=uc645e654-b293-4c18-86da-a6637083e55&title=&width=1714) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN013Cu5OE1CXGRhyEmbJ_!!6000000000090-2-tps-3546-1792.png)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01iaK15j1bgIeO65svI_!!6000000003494-2-tps-3428-1640.png)
如图,输入表达式: 如图,输入表达式:
```json
```javascript
this.state.companies this.state.companies
``` ```
再结合上一节的“配置组件”操作,我们已经可以把表格的主体配置出来了:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645013130950-4219cf27-760c-4749-8d4e-013dd53dbc83.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=820&id=u73c837e3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1640&originWidth=3058&originalType=binary&ratio=1&rotation=0&showTitle=false&size=408420&status=done&style=stroke&taskId=u23f7f045-8077-4e9d-9335-fea3ba54273&title=&width=1529)
## 动态请求 再结合上一节的“配置组件”操作,我们已经可以把表格的主体配置出来了:
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01p8QJ5C1buxKDTS1cU_!!6000000003526-2-tps-3058-1640.png)
### 动态请求
我们进入代码区块,使用生命周期方法来完成动态数据的请求。假设提供数据的接口是:[http://rap2api.taobao.org/app/mock/250089/testCompanies](http://rap2api.taobao.org/app/mock/250089/testCompanies),那么,我们可以在源码面板进行如下配置: 我们进入代码区块,使用生命周期方法来完成动态数据的请求。假设提供数据的接口是:[http://rap2api.taobao.org/app/mock/250089/testCompanies](http://rap2api.taobao.org/app/mock/250089/testCompanies),那么,我们可以在源码面板进行如下配置:
```typescript ```typescript
class LowcodeComponent extends Component { class LowcodeComponent extends Component {
state = { state = {
@ -54,9 +64,9 @@ class LowcodeComponent extends Component {
"isShowDialog": false, "isShowDialog": false,
"loading": false, "loading": false,
"companies": [ "companies": [
{ company: '测试公司1', id: 1, createTime: +new Date() }, { company: '测试公司 1', id: 1, createTime: +new Date() },
{ company: '测试公司2', id: 2, createTime: +new Date() }, { company: '测试公司 2', id: 2, createTime: +new Date() },
{ company: '测试公司3', id: 3, createTime: +new Date() }, { company: '测试公司 3', id: 3, createTime: +new Date() },
] ]
} }
componentDidMount() { componentDidMount() {
@ -75,36 +85,46 @@ class LowcodeComponent extends Component {
} }
} }
``` ```
`componentDidMount` 生命周期,将请求接口并设置 loading 和数据字段。
点击保存或叉关闭源码面板后,我们可以看到代码已经生效了:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645013883960-ca217c38-5c40-4ecc-9e05-277098fef16a.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=817&id=u1a3f852b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1634&originWidth=3058&originalType=binary&ratio=1&rotation=0&showTitle=false&size=427572&status=done&style=stroke&taskId=ubd2291b7-36c3-48c1-b489-9c61f0f6230&title=&width=1529)
## 配置插槽 `componentDidMount` 生命周期,将请求接口并设置 loading 和数据字段。
点击保存或叉关闭源码面板后,我们可以看到代码已经生效了:
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01lqjW8e1f39G8Zm7hQ_!!6000000003950-2-tps-3058-1634.png)
### 配置插槽
我们可以用绑定数据的方法把 loading 绑在加载指示上: 我们可以用绑定数据的方法把 loading 绑在加载指示上:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645014111323-c45f9b9a-77dd-4724-b6ee-78572863a871.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=952&id=u3bdd353b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1904&originWidth=3170&originalType=binary&ratio=1&rotation=0&showTitle=false&size=503197&status=done&style=none&taskId=u1faed9f0-3c68-4385-8d08-e59e2a1600a&title=&width=1585)
![Feb-16-2022 20-24-35.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014292272-68e07740-47dc-4c94-8437-beded0b07c63.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4506fc72&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-24-35.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6960677&status=done&style=stroke&taskId=u9fe02184-e6dc-4886-b371-c48ca1e2832&title=&width=766)
将 Loading 的“是否显示”字段绑定 `this.state.loading` 后,我们可以看到,这里暴露了一个插槽。插槽是可以任意扩展的预设部分,我们可以把其他的部分拖进插槽:
![Feb-16-2022 20-27-03.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014436894-9b975ae6-76cc-412b-829a-fae3605277dc.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u407467ac&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-27-03.gif&originHeight=792&originWidth=1528&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3443266&status=done&style=stroke&taskId=u0a091444-8b12-49a0-a57a-bfa758d351a&title=&width=764)
点击右上角的预览,我们能够看到完整的动态请求效果了:
![Feb-16-2022 20-28-36.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014527841-b621f38f-2c03-40f1-aa41-19293f96b08f.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u6ee6beea&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-28-36.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1968612&status=done&style=stroke&taskId=u2bdcee3f-91c5-4cb3-8405-f44f995cc78&title=&width=767)
## 列挂钩浮层 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01K3Pwjo1PKWQcoBl5K_!!6000000001822-2-tps-3170-1904.png)
![Feb-16-2022 20-24-35.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014292272-68e07740-47dc-4c94-8437-beded0b07c63.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4506fc72&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-24-35.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6960677&status=done&style=stroke&taskId=u9fe02184-e6dc-4886-b371-c48ca1e2832&title=&width=766)
将 Loading 的“是否显示”字段绑定 `this.state.loading` 后,我们可以看到,这里暴露了一个插槽。插槽是可以任意扩展的预设部分,我们可以把其他的部分拖进插槽:
![Feb-16-2022 20-27-03.gif](https://img.alicdn.com/imgextra/i2/O1CN01HSBncU1XWRfPdwlPK_!!6000000002931-1-tps-1528-792.gif)
点击右上角的预览,我们能够看到完整的动态请求效果了:
![Feb-16-2022 20-28-36.gif](https://img.alicdn.com/imgextra/i3/O1CN01o5THZf1fkesw2nZEC_!!6000000004045-1-tps-1534-792.gif)
### 列挂钩浮层
为了能够让表格里的操作挂钩浮层,我们先拖入一个浮层: 为了能够让表格里的操作挂钩浮层,我们先拖入一个浮层:
![Feb-16-2022 20-32-09.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014772471-0fce9b50-0f70-492e-bb53-5f875c00f5b4.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4d33cd05&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-09.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7475148&status=done&style=stroke&taskId=u9dc26cba-41eb-4fe8-b96f-fe391968861&title=&width=766) ![Feb-16-2022 20-32-09.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014772471-0fce9b50-0f70-492e-bb53-5f875c00f5b4.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4d33cd05&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-09.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7475148&status=done&style=stroke&taskId=u9dc26cba-41eb-4fe8-b96f-fe391968861&title=&width=766)
使用大纲树能够临时显示和隐藏此浮层: 使用大纲树能够临时显示和隐藏此浮层:
![Feb-16-2022 20-32-39.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014828329-b2de4db6-9032-4280-b886-db17070eea21.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=ue27e6676&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-39.gif&originHeight=792&originWidth=1530&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7335022&status=done&style=stroke&taskId=u73554a5d-5ebe-48d1-a861-426ba8501b1&title=&width=765) ![Feb-16-2022 20-32-39.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014828329-b2de4db6-9032-4280-b886-db17070eea21.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=ue27e6676&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-39.gif&originHeight=792&originWidth=1530&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7335022&status=done&style=stroke&taskId=u73554a5d-5ebe-48d1-a861-426ba8501b1&title=&width=765)
我们给表格增加一个数据列:
![Feb-16-2022 20-39-41.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015242447-3e019714-4b86-4c10-9bf7-01e19201bf0c.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=uc2c35de3&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-39-41.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3415710&status=done&style=stroke&taskId=u5aedc5dd-f361-4e45-88b0-be09af09a6a&title=&width=766) 我们给表格增加一个数据列:
![Feb-16-2022 20-39-41.gif](https://img.alicdn.com/imgextra/i2/O1CN012K6qWI1hgCG6KwRF7_!!6000000004306-1-tps-1532-792.gif)
然后配置它的行为为“弹窗”: 然后配置它的行为为“弹窗”:
![Feb-16-2022 20-40-05.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015223838-7f180e28-43e0-442b-a47e-ea5ff69d4900.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u80f44f38&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-40-05.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7261162&status=done&style=stroke&taskId=u3828503a-ecac-452a-8d20-02e4a46ad02&title=&width=766) ![Feb-16-2022 20-40-05.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015223838-7f180e28-43e0-442b-a47e-ea5ff69d4900.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u80f44f38&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-40-05.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7261162&status=done&style=stroke&taskId=u3828503a-ecac-452a-8d20-02e4a46ad02&title=&width=766)
实现的效果如下: 实现的效果如下:
![Feb-16-2022 20-42-51.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015379808-7d7852b1-5902-42d0-b951-c9c5d8f4c893.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=ua2e7ceda&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-42-51.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=588625&status=done&style=stroke&taskId=uf0466dde-ca4c-41d9-bf42-1ff443d02c5&title=&width=767) ![Feb-16-2022 20-42-51.gif](https://img.alicdn.com/imgextra/i4/O1CN018iana91j4l71QTmpE_!!6000000004495-1-tps-1534-792.gif)
## 事件回调 ### 事件回调
上述功能点中,我们是把操作行为绑定在数据列上的,这一节我们绑定到操作列中。在操作列按钮处,点击下方的“添加一项”: 上述功能点中,我们是把操作行为绑定在数据列上的,这一节我们绑定到操作列中。在操作列按钮处,点击下方的“添加一项”:
![Feb-23-2022 11-58-02.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645588703676-2a36cab4-52f4-4f31-9018-d56b41a55283.gif#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u18d8ea0b&margin=%5Bobject%20Object%5D&name=Feb-23-2022%2011-58-02.gif&originHeight=790&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8440133&status=done&style=stroke&taskId=u73e25800-c0fa-486b-9b68-4df7db9b9f1&title=&width=767) ![Feb-23-2022 11-58-02.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645588703676-2a36cab4-52f4-4f31-9018-d56b41a55283.gif#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u18d8ea0b&margin=%5Bobject%20Object%5D&name=Feb-23-2022%2011-58-02.gif&originHeight=790&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8440133&status=done&style=stroke&taskId=u73e25800-c0fa-486b-9b68-4df7db9b9f1&title=&width=767)
@ -119,10 +139,10 @@ onClick_new(e, { rowKey, rowIndex, rowRecord }){
} }
``` ```
保存。预览时我们可以看到效果了: 保存。预览时我们可以看到效果了:
![Feb-23-2022 12-05-25.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645589138764-d6514256-2a1f-4127-9591-747b4808848e.gif#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u9f09d078&margin=%5Bobject%20Object%5D&name=Feb-23-2022%2012-05-25.gif&originHeight=790&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2238638&status=done&style=stroke&taskId=u460c90f3-d692-45f9-9028-cf45d4cea98&title=&width=766) ![Feb-23-2022 12-05-25.gif](https://img.alicdn.com/imgextra/i3/O1CN01CXi1zJ1N302paKUre_!!6000000001513-1-tps-1532-790.gif)
# 研究本例的 schema ## 研究本例的 schema
我们把本例的 schema 保存在云端,您可以自行下载研究:[https://mo.m.taobao.com/marquex/lowcode-showcase-table](https://mo.m.taobao.com/marquex/lowcode-showcase-table) 我们把本例的 schema 保存在云端,您可以自行下载研究:[https://mo.m.taobao.com/marquex/lowcode-showcase-table](https://mo.m.taobao.com/marquex/lowcode-showcase-table)
您可以通过左下角的 Schema 面板直接导入本例子的 Schema。 您可以通过左下角的 Schema 面板直接导入本例子的 Schema。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645589288482-0ce8ea2f-c4e1-4956-be9c-143c9b71654b.png#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=810&id=u713729c6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1620&originWidth=3054&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1074154&status=done&style=stroke&taskId=u783f33a5-241d-43ec-8b46-8385b733810&title=&width=1527) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01z2LXgW1iFSklNRzTN_!!6000000004383-2-tps-3054-1620.png)

View File

@ -3,7 +3,8 @@ title: 4. 组件面板详解
sidebar_position: 0 sidebar_position: 0
--- ---
## 概述 ## 概述
组件面板顾名思义就是承载组件的面板,组件面板会获取并解析传入给低代码引擎的资产包数据(数据结构[点此查看](https://lowcode-engine.cn/assets)),得到需要被展示的组件列表,并根据分类、排序规则对组件进行排列,同时也提供了搜索功能。 组件面板顾名思义就是承载组件的面板,组件面板会获取并解析传入给低代码引擎的资产包数据 (数据结构[点此查看](https://lowcode-engine.cn/assets)),得到需要被展示的组件列表,并根据分类、排序规则对组件进行排列,同时也提供了搜索功能。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647964501932-33676243-c42b-4e7c-8663-77c5898d3343.png#clientId=uf38e3cbf-9388-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=438&id=ubb9e4616&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1672&originWidth=3056&originalType=binary&ratio=1&rotation=0&showTitle=true&size=451947&status=done&style=stroke&taskId=u0fc240e1-a792-4bd1-b84d-5bbc8e8fc8b&title=%E7%BB%84%E4%BB%B6%E9%9D%A2%E6%9D%BF&width=800 "组件面板") ![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647964501932-33676243-c42b-4e7c-8663-77c5898d3343.png#clientId=uf38e3cbf-9388-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=438&id=ubb9e4616&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1672&originWidth=3056&originalType=binary&ratio=1&rotation=0&showTitle=true&size=451947&status=done&style=stroke&taskId=u0fc240e1-a792-4bd1-b84d-5bbc8e8fc8b&title=%E7%BB%84%E4%BB%B6%E9%9D%A2%E6%9D%BF&width=800 "组件面板")
## 组件信息 ## 组件信息
组件面板承载的组件信息有: 组件面板承载的组件信息有:

View File

@ -3,8 +3,10 @@ title: 8. 数据源面板详解
sidebar_position: 4 sidebar_position: 4
--- ---
## 🪚 概述 ## 🪚 概述
数据源面板主要负责管理低代码中远程数据源内容通过可视化编辑的方式操作低代码协议中的数据源Schema配合 [数据源引擎](https://www.yuque.com/lce/doc/datasource-engine) 即可实现低代码中数据源的生产和消费; 数据源面板主要负责管理低代码中远程数据源内容,通过可视化编辑的方式操作低代码协议中的数据源 Schema配合 [数据源引擎](/site/docs/guide/design/datasourceEngine) 即可实现低代码中数据源的生产和消费;
![image.png](https://cdn.nlark.com/yuque/0/2022/png/84508/1648397674378-aec10892-5ee4-414d-807e-39f55f3a5be5.png#clientId=u38847497-05f3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=821&id=u07e82f8a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1642&originWidth=2878&originalType=binary&ratio=1&rotation=0&showTitle=false&size=246032&status=done&style=none&taskId=uc18acbc5-1404-4266-a499-e952d1084c4&title=&width=1439) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/84508/1648397674378-aec10892-5ee4-414d-807e-39f55f3a5be5.png#clientId=u38847497-05f3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=821&id=u07e82f8a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1642&originWidth=2878&originalType=binary&ratio=1&rotation=0&showTitle=false&size=246032&status=done&style=none&taskId=uc18acbc5-1404-4266-a499-e952d1084c4&title=&width=1439)
数据源面板 数据源面板
## ❓如何使用 ## ❓如何使用
> 面板内包含了数据源创建、删除、编辑、排序、导入导出、复制以及搜索等能力,内置支持了 `fecth` & `JSONP`两种常用远程请求类型; > 面板内包含了数据源创建、删除、编辑、排序、导入导出、复制以及搜索等能力,内置支持了 `fecth` & `JSONP`两种常用远程请求类型;
@ -24,11 +26,13 @@ TODO
### 如何定制数据源 ### 如何定制数据源
#### 定制数据源类型(设计态) #### 定制数据源类型(设计态)
#### 定制数据源请求实现(运行态) #### 定制数据源请求实现(运行态)
> 当出现以下两种情况的时,我们需要定制数据源请求实现, > 当出现以下两种情况的时,我们需要定制数据源请求实现,
> - 当你默认提供的 `handler`无法满足你的需求 > - 当你默认提供的 `handler`无法满足你的需求
> - 定制了数据源类型,比如 `GraphQL`,需要实现一个对应的 `handler` > - 定制了数据源类型,比如 `GraphQL`,需要实现一个对应的 `handler`
接下来我们来看一个例子,如何实现一个 `handler` 接下来我们来看一个例子,如何实现一个 `handler`
```javascript ```javascript
import { RuntimeOptionsConfig } from '@alilc/lowcode-datasource-types'; import { RuntimeOptionsConfig } from '@alilc/lowcode-datasource-types';
@ -50,9 +54,9 @@ export function createFetchHandler(config?: Record<string, unknown>) {
}; };
} }
``` ```
低代码fetch-handler默认实现 低代码 fetch-handler 默认实现
以上代码是低代码内置的fetch-handler默认实现内部使用了 `universal-request`,假如你们内部使用的 `axios`,你完全重新实现一个; 以上代码是低代码内置的 fetch-handler 默认实现,内部使用了 `universal-request`,假如你们内部使用的 `axios`,你完全重新实现一个;
```javascript ```javascript
import axios from 'axios'; import axios from 'axios';
export function createAxiosFetchHandler(config?: Record<string, unknown>) { export function createAxiosFetchHandler(config?: Record<string, unknown>) {
@ -71,10 +75,10 @@ export function createAxiosFetchHandler(config?: Record<string, unknown>) {
} }
``` ```
##### 注册到render ##### 注册到 render
完成一个Handler后你可以通过以下方式接入到render或者出码中使用 完成一个 Handler 后你可以通过以下方式接入到 render 或者出码中使用
###### 渲染Render ###### 渲染 Render
```tsx ```tsx
import React, { memo } from 'react'; import React, { memo } from 'react';
import ReactRenderer from '@alilc/lowcode-react-renderer'; import ReactRenderer from '@alilc/lowcode-react-renderer';
@ -95,11 +99,11 @@ const SamplePreview = memo(() => {
}); });
``` ```
###### 出码 ###### 出码
> 目前自定义只能通过重新定义类型来完成接下来我们会给出码添加requestHandlersMap映射能力如有需求请联系 荣彬(github-id:xingmolu) > 目前自定义只能通过重新定义类型来完成,接下来我们会给出码添加 requestHandlersMap 映射能力;如有需求请联系 荣彬 (github-id:xingmolu)
### 设计态启用数据源引擎 ### 设计态启用数据源引擎
> 默认情况下设计态没有开启数据源引擎我们可以在设计器init的时候来传递`requstHandlersMap`来开启;具体代码如下: > 默认情况下设计态没有开启数据源引擎,我们可以在设计器 init 的时候来传递`requstHandlersMap`来开启;具体代码如下:
```javascript ```javascript
import { init, plugins } from '@alilc/lowcode-engine'; import { init, plugins } from '@alilc/lowcode-engine';
@ -139,12 +143,12 @@ const preference = new Map();
| isInit | 是否为初始数据 | Boolean | ✅ | true | 值为 true 时,将在组件初始化渲染时自动发送当前数据请求 | | isInit | 是否为初始数据 | Boolean | ✅ | true | 值为 true 时,将在组件初始化渲染时自动发送当前数据请求 |
| isSync | 是否需要串行执行 | Boolean | ✅ | false | 值为 true 时,当前请求将被串行执行 | | isSync | 是否需要串行执行 | Boolean | ✅ | false | 值为 true 时,当前请求将被串行执行 |
| type | 数据请求类型 | String | - | fetch | 支持四种类型fetch/mtop/jsonp/custom | | type | 数据请求类型 | String | - | fetch | 支持四种类型fetch/mtop/jsonp/custom |
| shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | () => true | function 参数参考 [ComponentDataSourceItemOptions 对象描述](https://lowcode-engine.cn/lowcode#2315-componentdatasourceitemoptions-%E5%AF%B9%E8%B1%A1%E6%8F%8F%E8%BF%B0) | | shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | () => true | function 参数参考 [ComponentDataSourceItemOptions 对象描述](/site/docs/specs/lowcode-spec#2315-componentdatasourceitemoptions-对象描述) |
| willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数options返回值作为请求的 options当处理异常时使用原 options。也可以返回一个 Promiseresolve 的值作为请求的 optionsreject 时,使用原 options | | willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数options返回值作为请求的 options当处理异常时使用原 options。也可以返回一个 Promiseresolve 的值作为请求的 optionsreject 时,使用原 options |
| requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type=custom 时生效 | | requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type=custom时生效 |
| dataHandler | request 成功后的回调函数 | Function | - | response => response.data | 参数: 请求成功后 promise 的 value 值 | | dataHandler | request 成功后的回调函数 | Function | - | response => response.data | 参数请求成功后 promise 的 value 值 |
| errorHandler | request 失败后的回调函数 | Function | - | - | 参数: 请求出错 promise 的 error 内容 | | errorHandler | request 失败后的回调函数 | Function | - | - | 参数请求出错 promise 的 error 内容 |
| options {} | 请求参数 | **ComponentDataSourceItemOptions** | - | - | 每种请求类型对应不同参数, 详见 [ComponentDataSourceItemOptions 对象描述](https://lowcode-engine.cn/lowcode#2315-componentdatasourceitemoptions-%E5%AF%B9%E8%B1%A1%E6%8F%8F%E8%BF%B0) | | options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见见 [ComponentDataSourceItemOptions 对象描述](/site/docs/specs/lowcode-spec#2315-componentdatasourceitemoptions-对象描述) |
### 运行时实现层:数据源引擎设计 ### 运行时实现层:数据源引擎设计
[https://www.yuque.com/lce/doc/datasource-engine](https://www.yuque.com/lce/doc/datasource-engine) [数据源引擎设计](/site/docs/guide/design/datasourceEngine)

View File

@ -28,23 +28,23 @@ sidebar_position: 2
| BoolSetter | 布尔型数据设置器, | | BoolSetter | 布尔型数据设置器, |
| SelectSetter | 枚举型数据设置器,采用下拉的形式展现 | | SelectSetter | 枚举型数据设置器,采用下拉的形式展现 |
| VariableSetter | 变量型数据设置器, | | VariableSetter | 变量型数据设置器, |
| RadioGroupSetter | 枚举型数据设置器采用tab选择的形式展现 | | RadioGroupSetter | 枚举型数据设置器,采用 tab 选择的形式展现 |
| TextAreaSetter | 长文本型数据设置器,可换行 | | TextAreaSetter | 长文本型数据设置器,可换行 |
| DateSetter | 日期型数据设置器 | | DateSetter | 日期型数据设置器 |
| TimePicker | 时间型数据设置器 | | TimePicker | 时间型数据设置器 |
| DateYearSetter | 日期型-年数据设置器 | | DateYearSetter | 日期型 - 年数据设置器 |
| DateMonthSetter | 日期型-月数据设置器 | | DateMonthSetter | 日期型 - 月数据设置器 |
| DateRangeSetter | 日期型数据设置器,可选择时间区间 | | DateRangeSetter | 日期型数据设置器,可选择时间区间 |
| EventsSetter | 事件绑定设置器 | | EventsSetter | 事件绑定设置器 |
| ColorSetter | 颜色设置器 | | ColorSetter | 颜色设置器 |
| JsonSetter | json型数据设置器 | | JsonSetter | json 型数据设置器 |
| StyleSetter | 样式设置器 | | StyleSetter | 样式设置器 |
| ClassNameSetter | 样式名设置器 | | ClassNameSetter | 样式名设置器 |
| FunctionSetter | 函数型数据设置器 | | FunctionSetter | 函数型数据设置器 |
| MixedSetter | 混合型数据设置器 | | MixedSetter | 混合型数据设置器 |
| SlotSetter | 节点型数据设置器 | | SlotSetter | 节点型数据设置器 |
| ArraySetter | 列表数组行数据设置器 | | ArraySetter | 列表数组行数据设置器 |
| ObjectSetter | 对象数据设置器一般内嵌在ArraySetter中 | | ObjectSetter | 对象数据设置器,一般内嵌在 ArraySetter 中 |
# 设置器定制 # 设置器定制
@ -60,7 +60,7 @@ interface AltStringSetterProps {
value: string; value: string;
// 默认值 // 默认值
defaultValue: string; defaultValue: string;
// setter唯一输出 // setter 唯一输出
onChange: (val: string) => void; onChange: (val: string) => void;
// AltStringSetter 特殊配置 // AltStringSetter 特殊配置
placeholder: string; placeholder: string;
@ -73,7 +73,7 @@ export default class AltStringSetter extends React.PureComponent<AltStringSetter
} }
} }
// 声明Setter的title // 声明 Setter title
static displayName = 'AltStringSetter'; static displayName = 'AltStringSetter';
render() { render() {
@ -95,7 +95,7 @@ export default class AltStringSetter extends React.PureComponent<AltStringSetter
import { event } from '@ali/lowcode-engine'; import { event } from '@ali/lowcode-engine';
componentDidMount() { componentDidMount() {
// 这里由于面板上会有多个setter这里我用field.id来标记setter名 // 这里由于面板上会有多个 setter这里我用 field.id 来标记 setter
this.emitEventName = `${SETTER_NAME}-${this.props.field.id}`; this.emitEventName = `${SETTER_NAME}-${this.props.field.id}`;
event.on(`${this.emitEventName}.bindEvent`, this.bindEvent) event.on(`${this.emitEventName}.bindEvent`, this.bindEvent)
} }
@ -105,7 +105,7 @@ bindEvent = (eventName) => {
} }
componentWillUnmount() { componentWillUnmount() {
// setter是以实例为单位的每个setter注销的时候需要把事件也注销掉避免事件池过多 // setter 是以实例为单位的,每个 setter 注销的时候需要把事件也注销掉,避免事件池过多
event.off(`${this.emitEventName}.bindEvent`, this.bindEvent) event.off(`${this.emitEventName}.bindEvent`, this.bindEvent)
} }
``` ```
@ -115,7 +115,7 @@ import { event } from '@ali/lowcode-engine';
bindFunction = () => { bindFunction = () => {
const { field, value } = this.props; const { field, value } = this.props;
// 这里展示的和插件进行通信,事件规则是插件名+方法 // 这里展示的和插件进行通信,事件规则是插件名 + 方法
event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); event.emit('eventBindDialog.openDialog', field.name, this.emitEventName);
} }
``` ```
@ -125,9 +125,9 @@ setter 本身只影响其中一个 props 的值,如果需要影响其他组件
bindFunction = () => { bindFunction = () => {
const { field, value } = this.props; const { field, value } = this.props;
const propsField = field.parent; const propsField = field.parent;
// 获取同级其他属性showJump的值 // 获取同级其他属性 showJump 的值
const otherValue = propsField.getPropValue('showJump'); const otherValue = propsField.getPropValue('showJump');
// set同级其他属性showJump的值 // set 同级其他属性 showJump 的值
propsField.setPropValue('showJump', false); propsField.setPropValue('showJump', false);
} }
``` ```

View File

@ -6,12 +6,12 @@ tags: [FAQ]
背景: 背景:
- [Antd Table 下 button 点击事件怎么拿到行数据?](https://github.com/alibaba/lowcode-engine/issues/341) - [Antd Table 下 button 点击事件怎么拿到行数据?](https://github.com/alibaba/lowcode-engine/issues/341)
## 方式1 ## 方式 1
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593243427-fb5641b2-4987-475e-88ab-c68d2085edbd.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=563&id=u5167bf33&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1126&originWidth=3342&originalType=binary&ratio=1&rotation=0&showTitle=false&size=225551&status=done&style=none&taskId=ud1b89a63-4b6a-4986-a6df-2a463fcf08a&title=&width=1671) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593243427-fb5641b2-4987-475e-88ab-c68d2085edbd.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=563&id=u5167bf33&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1126&originWidth=3342&originalType=binary&ratio=1&rotation=0&showTitle=false&size=225551&status=done&style=none&taskId=ud1b89a63-4b6a-4986-a6df-2a463fcf08a&title=&width=1671)
参考 fusion protable 将操作列直接耦合 button 组件,因为 col.render 函数能拿到 行数据record那么 pro-table 组件封装的时候,就可以在渲染操作列按钮的时候,将 col.render 参数透传给 button 组件 参考 fusion protable将操作列直接耦合 button 组件,因为 col.render 函数能拿到 行数据 record那么 pro-table 组件封装的时候,就可以在渲染操作列按钮的时候,将 col.render 参数透传给 button 组件
## 方式2 ## 方式 2
slot + 扩展参数 slot + 扩展参数
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593299698-9628db14-7b48-4c06-9e6f-bda637c209a8.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=574&id=u20b07439&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1148&originWidth=3284&originalType=binary&ratio=1&rotation=0&showTitle=false&size=232140&status=done&style=none&taskId=ubc80905d-0607-4e73-9386-5dde706e572&title=&width=1642) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593299698-9628db14-7b48-4c06-9e6f-bda637c209a8.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=574&id=u20b07439&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1148&originWidth=3284&originalType=binary&ratio=1&rotation=0&showTitle=false&size=232140&status=done&style=none&taskId=ubc80905d-0607-4e73-9386-5dde706e572&title=&width=1642)

View File

@ -5,7 +5,7 @@ tags: [FAQ]
--- ---
## 设计器 ## 设计器
### 通过引擎 API 配置 ### 通过引擎 API 配置
[https://www.yuque.com/lce/doc/dffghx](https://www.yuque.com/lce/doc/dffghx) [API-init](/site/docs/api/init)
### 通过资产包 ### 通过资产包
@ -20,4 +20,4 @@ PS需要在 packages 中有相关的资源配置,例如:
否则在画布中可能会访问不到对应的资源。 否则在画布中可能会访问不到对应的资源。
## 预览态 ## 预览态
参考:[https://www.yuque.com/lce/doc/nhilce#appHelper](https://www.yuque.com/lce/doc/nhilce#appHelper) [参考资料](/site/docs/guide/expand/runtime/renderer#apphelper)

View File

@ -3,4 +3,4 @@ title: 如何通过 API 手动调用数据源请求
sidebar_position: 6 sidebar_position: 6
tags: [FAQ] tags: [FAQ]
--- ---
参考:[https://www.yuque.com/lce/doc/erckcn](https://www.yuque.com/lce/doc/erckcn) 参考:[DataSource API](/site/docs/api/datasource)

View File

@ -1,9 +1,9 @@
--- ---
title: 设置面板中的高级tab如何配置 title: 设置面板中的高级 tab 如何配置
sidebar_position: 7 sidebar_position: 7
tags: [FAQ] tags: [FAQ]
--- ---
![93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png](https://cdn.nlark.com/yuque/0/2022/png/1053439/1657161085153-a26657ae-2c6e-4124-b9ab-6f8cf8126d1f.png#clientId=u300df630-5bbe-4&crop=0&crop=0&crop=1&crop=1&from=ui&height=591&id=u2ff7824e&margin=%5Bobject%20Object%5D&name=93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png&originHeight=1714&originWidth=960&originalType=binary&ratio=1&rotation=0&showTitle=false&size=107040&status=done&style=none&taskId=ub377dc1d-db5a-4234-980f-66f7143950d&title=&width=331) ![93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png](https://cdn.nlark.com/yuque/0/2022/png/1053439/1657161085153-a26657ae-2c6e-4124-b9ab-6f8cf8126d1f.png#clientId=u300df630-5bbe-4&crop=0&crop=0&crop=1&crop=1&from=ui&height=591&id=u2ff7824e&margin=%5Bobject%20Object%5D&name=93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png&originHeight=1714&originWidth=960&originalType=binary&ratio=1&rotation=0&showTitle=false&size=107040&status=done&style=none&taskId=ub377dc1d-db5a-4234-980f-66f7143950d&title=&width=331)
默认这个tab下的内容为引擎内置如需要定制可以使用以下API 默认这个 tab 下的内容为引擎内置,如需要定制,可以使用以下 API
[https://lowcode-engine.cn/docV2/mu7lml#lIK37](https://lowcode-engine.cn/docV2/mu7lml#lIK37) [https://lowcode-engine.cn/docV2/mu7lml#lIK37](https://lowcode-engine.cn/docV2/mu7lml#lIK37)

View File

@ -1,7 +1,7 @@
--- ---
title: 某某npm包对应的源码在哪里 title: 某某 npm 包对应的源码在哪里?
sidebar_position: 8 sidebar_position: 8
tags: [FAQ] tags: [FAQ]
--- ---
详见 [NPM包对应源码位置汇总](https://www.yuque.com/lce/doc/ngm44i) 详见 [NPM 包对应源码位置汇总](/site/docs/guide/appendix/npms)

View File

@ -9,7 +9,7 @@ tags: [FAQ]
**解决方案** **解决方案**
LowCodeEngine 升级到 1.0.8 LowCodeEngine 升级到 1.0.8
> 相关PR[https://github.com/alibaba/lowcode-engine/pull/383](https://github.com/alibaba/lowcode-engine/pull/383) > 相关 PR[https://github.com/alibaba/lowcode-engine/pull/383](https://github.com/alibaba/lowcode-engine/pull/383)
## 编辑态snippets 和注入组件不对应 ## 编辑态snippets 和注入组件不对应

View File

@ -87,4 +87,4 @@ const snippets: Snippet[] = [
``` ```
### 如何全局生效 ### 如何全局生效
通过 [https://www.yuque.com/lce/doc/mu7lml#LRXhp](https://www.yuque.com/lce/doc/mu7lml#LRXhp) 来修改元数据信息,注意如果有 snippets 相关配置也需要修改相关的配置。 通过 [registerMetadataTransducer API](/site/docs/api/material#registermetadatatransducer) 来修改元数据信息,注意如果有 snippets 相关配置也需要修改相关的配置。

View File

@ -4,7 +4,7 @@ sidebar_position: 13
tags: [FAQ] tags: [FAQ]
--- ---
## 注意 ## 注意
弹窗的正确弹出方式请参考:[https://www.yuque.com/lce/usage/ozsg2m](https://www.yuque.com/lce/usage/ozsg2m) 弹窗的正确弹出方式请参考:[如何通过按钮展示/隐藏弹窗](/site/docs/demoUsage/makeStuff/dialog)
## 问题原因 ## 问题原因
由于 hidden 属性,导致 Modal 组件在预览的时候不渲染,也就无法获取到实例。 由于 hidden 属性,导致 Modal 组件在预览的时候不渲染,也就无法获取到实例。
## 处理方式 ## 处理方式

View File

@ -3,5 +3,5 @@ title: 已有组件如何快速接入引擎
sidebar_position: 15 sidebar_position: 15
tags: [FAQ] tags: [FAQ]
--- ---
你可以通过在线工具 「Parts造物」生产物料描述协议然后使用到你的项目中去。 你可以通过在线工具「Parts 造物」生产物料描述协议,然后使用到你的项目中去。
文档地址:[https://www.yuque.com/lce/xhk5hf/qa9pbx](https://www.yuque.com/lce/xhk5hf/qa9pbx) 文档地址:[利用 Parts 造物快速使用 react 组件](/site/docs/guide/expand/editor/partsIntro)

View File

@ -7,7 +7,7 @@ tags: [FAQ]
需要在资产包中检查是否有下列代码: 需要在资产包中检查是否有下列代码:
```typescript ```typescript
{ {
"title": "fusion组件库", "title": "fusion 组件库",
"package": "@alifd/next", "package": "@alifd/next",
"version": "1.23.0", "version": "1.23.0",
"urls": [ "urls": [

View File

@ -2,4 +2,4 @@
title: 名词解释 title: 名词解释
sidebar_position: 0 sidebar_position: 0
--- ---
![glossary](https://cdn.nlark.com/yuque/0/2022/jpeg/2622706/1648103397469-00227a70-e7ab-4a90-8378-c4da977250b2.jpeg) ![glossary](https://img.alicdn.com/imgextra/i2/O1CN01vPZjCM1jT26YujpGk_!!6000000004548-0-tps-2284-4301.jpg)

View File

@ -2,6 +2,6 @@
title: 搭建组件协议结构 title: 搭建组件协议结构
sidebar_position: 1 sidebar_position: 1
--- ---
完整协议请查看:[http://lowcode-engine.cn/material](http://lowcode-engine.cn/material) 完整协议[查看](/site/docs/specs/material-spec)
![](https://cdn.nlark.com/yuque/0/2022/jpeg/2622706/1646040400808-9a4a4d7d-6ad2-43be-8c97-d88f0cab7cc6.jpeg) ![](https://img.alicdn.com/imgextra/i4/O1CN01hozDem1apAhnvdESN_!!6000000003378-0-tps-2474-4128.jpg)

View File

@ -1,5 +1,5 @@
--- ---
title: NPM包对应源码位置汇总 title: NPM 包对应源码位置汇总
sidebar_position: 3 sidebar_position: 3
--- ---
| 包名 | 仓库 | 路径 | | 包名 | 仓库 | 路径 |

View File

@ -2,7 +2,7 @@
title: 低代码仓库列表 title: 低代码仓库列表
sidebar_position: 2 sidebar_position: 2
--- ---
### 1. 引擎主包 ## 1. 引擎主包
包含引擎的 4 大模块,入料、编排、渲染和出码。 包含引擎的 4 大模块,入料、编排、渲染和出码。
仓库地址:[https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) 仓库地址:[https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine)
@ -25,7 +25,7 @@ sidebar_position: 2
15. material-parser 15. material-parser
16. code-generator 16. code-generator
### 2. 引擎官方扩展包 ## 2. 引擎官方扩展包
包含了常用的设置器setter、跟 setter 绑定的插件等 包含了常用的设置器setter、跟 setter 绑定的插件等
仓库地址:[https://github.com/alibaba/lowcode-engine-ext](https://github.com/alibaba/lowcode-engine-ext) 仓库地址:[https://github.com/alibaba/lowcode-engine-ext](https://github.com/alibaba/lowcode-engine-ext)
@ -56,7 +56,7 @@ sidebar_position: 2
- 插件 plugin - 插件 plugin
- plugin-event-bind-dialog 事件绑定浮层 - plugin-event-bind-dialog 事件绑定浮层
- plugin-variable-bind-dialog 变量绑定浮层 - plugin-variable-bind-dialog 变量绑定浮层
### 3. 低代码插件 ## 3. 低代码插件
包含了常用的插件等 包含了常用的插件等
仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins)
@ -70,18 +70,18 @@ sidebar_position: 2
- plugin-undo-redo 前进/后退功能 - plugin-undo-redo 前进/后退功能
- plugin-zh-cn 中英文切换功能 - plugin-zh-cn 中英文切换功能
### 4. 引擎 demo ## 4. 引擎 demo
展示使用引擎编排和渲染等模块以及相应的依赖资源配置基础 demo 展示使用引擎编排和渲染等模块以及相应的依赖资源配置基础 demo
仓库地址:[https://github.com/alibaba/lowcode-demo](https://github.com/alibaba/lowcode-demo) 仓库地址:[https://github.com/alibaba/lowcode-demo](https://github.com/alibaba/lowcode-demo)
### 5. 工具链包 ## 5. 工具链包
包含生成引擎生态元素setter、物料、插件的脚手架启动脚本调试插件等 包含生成引擎生态元素setter、物料、插件的脚手架启动脚本调试插件等
仓库地址:[https://github.com/alibaba/lowcode-tools](https://github.com/alibaba/lowcode-tools) 仓库地址:[https://github.com/alibaba/lowcode-tools](https://github.com/alibaba/lowcode-tools)
### 6. 低代码数据源引擎 ## 6. 低代码数据源引擎
负责在渲染&出码两种运行时实现数据源管理,承担低代码搭建数据请求的能力; 负责在渲染&出码两种运行时实现数据源管理,承担低代码搭建数据请求的能力;
仓库地址:[https://github.com/alibaba/lowcode-datasource](https://github.com/alibaba/lowcode-datasource) 仓库地址:[https://github.com/alibaba/lowcode-datasource](https://github.com/alibaba/lowcode-datasource)
### 7. 基础物料 & 物料描述 ## 7. 基础物料 & 物料描述
仓库地址:[https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) 仓库地址:[https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials)
### 8. 出码 demo ## 8. 出码 demo
仓库地址:[https://github.com/alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo) 仓库地址:[https://github.com/alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo)

View File

@ -2,12 +2,12 @@
title: ArraySetter title: ArraySetter
--- ---
#### 简介 ## 简介
用来展示属性类型为数组的setter 用来展示属性类型为数组的 setter
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395220128-b5d948e3-6a5a-420f-9a7a-a29be25c507d.png#clientId=ud56bf956-0414-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=181&id=u27259ecd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=362&originWidth=584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=27221&status=done&style=none&taskId=u72065990-9557-4dbc-a0ba-eada448e228&title=&width=292) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01BXCpnh1OFebSSyeDQ_!!6000000001676-2-tps-584-362.png)
#### 配置示例 ## 配置示例
```javascript ```json
"setter": { "setter": {
"componentName": "ArraySetter", "componentName": "ArraySetter",
"props": { "props": {
@ -18,7 +18,7 @@ title: ArraySetter
"items": [{ "items": [{
"name": "title", "name": "title",
"description": "标题", "description": "标题",
"setter": "StringSetter", "setter": "StringSetter"
}, },
{ {
"name": "callback", "name": "callback",
@ -32,37 +32,36 @@ title: ArraySetter
}, },
"initialValue": { "initialValue": {
"title": "I am title", "title": "I am title",
"callback": null, "callback": null
} }
} }
} }
} }
``` ```
#### ArraySetter 配置 ## ArraySetter 配置
| **属性名** | **类型** | **说明** |
| --- | --- | --- |
| itemSetter | ObjectSetter | ArraySetter的子节点内容必须用ObjectSetter包裹 |
#### itemSetter 配置
| **属性名** | **类型** | **说明** | | **属性名** | **类型** | **说明** |
| --- | --- | --- | | --- | --- | --- |
| componentName | String | | itemSetter | ObjectSetter | ArraySetter 的子节点内容必须用 ObjectSetter 包裹 |
|
## itemSetter 配置
| **属性名** | **类型** | **说明** |
| --- | --- | --- |
| componentName | String ||
| props | | | | props | | |
| initialValue | Object | 新增一项的初始值 | | initialValue | Object | 新增一项的初始值 |
#### ObjectSetter 配置 ## ObjectSetter 配置
| **属性名** | **类型** | **说明** | | **属性名** | **类型** | **说明** |
| --- | --- | --- | | --- | --- | --- |
| descriptor | String | Item在列表中展示的item.key名需要和 config.items[] 中key对应 默认为 “项目X” | descriptor | String | Item 在列表中展示的 item.key 名,需要和 config.items[] 中key对应 默认为 “项目X” ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Okz1DY1Q17GGJBPDf_!!6000000001915-2-tps-640-372.png) |
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448651683-6c44787a-cb6c-4066-9a47-2b22f862cb9c.png#clientId=u05af0495-3e67-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=186&id=ufb6e3681&margin=%5Bobject%20Object%5D&name=image.png&originHeight=372&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=103250&status=done&style=none&taskId=u7a61b6f7-4e26-4d8b-a9e6-a30b5e9e73d&title=&width=320) |
| config | Object | 配置项 | | config | Object | 配置项 |
| config.items | Array | 子属性列表数据 | | config.items | Array | 子属性列表数据 |
| config.items[].name | String | 子属性名称 | | config.items[].name | String | 子属性名称 |
| config.items[].description | String | 子属性描述 | | config.items[].description | String | 子属性描述 |
| config.items[].setter | Object &#124; String | 子属性setter配置 &#124; 子属性setter组件名 | | config.items[].setter | Object &#124; String | 子属性setter配置 &#124; 子属性setter组件名 |
| config.items[].isRequired | Boolean | 子属性是否开启快捷编辑,最多开启4个 | config.items[].isRequired | Boolean | 子属性是否开启快捷编辑,最多开启4个 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01EflYAK1IPpiChvjHz_!!6000000000886-2-tps-614-422.png) |
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448651860-f4f80e87-4e80-463d-a1e0-99be8bf2a84f.png#clientId=u6ba2ab37-e0fb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=211&id=ueea652b0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=422&originWidth=614&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32465&status=done&style=none&taskId=u343405fd-5773-4ebd-b6fc-1367a769fe2&title=&width=307) |
| config.items[].condition | Boolean &#124; () => Boolean | 是否展示 | | config.items[].condition | Boolean &#124; () => Boolean | 是否展示 |
| config.items[].getValue | (target, value) => value | 数据获取的 hook可修改获取数据 | | config.items[].getValue | (target, value) => value | 数据获取的 hook可修改获取数据 |
| config.items[].setValue | (target, value) => value | 数据获取的 hook可修改设置数据 | | config.items[].setValue | (target, value) => value | 数据获取的 hook可修改设置数据 |

View File

@ -1,15 +1,18 @@
--- ---
title: BoolSetter title: BoolSetter
--- ---
#### 简介 ## 简介
开关选择器 开关选择器
#### 展示 ## 展示
![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448646757-b61019f4-d502-473a-8a11-4974479c55dc.png#from=url&id=dnn2b&margin=%5Bobject%20Object%5D&originHeight=82&originWidth=320&originalType=binary&ratio=1&status=done&style=none)
#### setter 配置 ![](https://img.alicdn.com/imgextra/i3/O1CN01KS7ndr1mHX0MITGPH_!!6000000004929-2-tps-320-82.png)
## setter 配置
| 属性名 | 说明 | | 属性名 | 说明 |
| --- | --- | | --- | --- |
| disabled | 是否可选 | | disabled | 是否可选 |
| defaultValue | 默认值 | | defaultValue | 默认值 |
#### 返回类型 ## 返回类型
Boolean Boolean

View File

@ -2,13 +2,15 @@
title: ColorSetter title: ColorSetter
--- ---
用来选择颜色。 用来选择颜色。
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448646203-3eb11d27-0195-4608-91f3-0f3cfb6b7140.png#clientId=u09a8f665-5383-4&from=paste&height=416&id=u417e185d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=728&originWidth=590&originalType=binary&ratio=1&size=230281&status=done&style=none&taskId=u3d246b17-94ab-4eb3-af66-3ffb7fd3145&width=337) <img src="https://img.alicdn.com/imgextra/i4/O1CN01iYKRA920aDn1uhs3M_!!6000000006865-2-tps-590-728.png" width="300"/>
#### setter 配置
## setter 配置
| 属性名 | 说明 | | 属性名 | 说明 |
| --- | --- | | --- | --- |
| defaultValue | 默认值 | | defaultValue | 默认值 |
#### 返回类型 ## 返回类型
String String
会返回options中的value值
会返回 options 中的 value 值

View File

@ -1,20 +1,23 @@
--- ---
title: EventSetter title: EventSetter
--- ---
#### 简介 ## 简介
可以将事件绑定在物料上 可以将事件绑定在物料上
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394906292-0eb3ab0e-0bb0-4c8d-bbc5-7217b33cdcab.png#clientId=ub4e2d6f6-4877-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=507&id=u2a295c86&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1014&originWidth=1202&originalType=binary&ratio=1&rotation=0&showTitle=false&size=293824&status=done&style=none&taskId=u37e95d95-4425-450a-b4aa-9805d9dcf97&title=&width=601)
<img src="https://img.alicdn.com/imgextra/i3/O1CN01mAMfxZ20WYca6KqJb_!!6000000006857-2-tps-1202-1014.png" width="300"/>
## 组件自带事件列表
在物料协议的 configure.supports.events 中声明
#### 组件自带事件列表
在物料协议的configure.supports.events 中声明
```json ```json
{ {
"configure ": { "configure ": {
"supports": { "supports": {
"style": true, "style": true,
"events": [{ "events": [{
"name": "onChange", "name": "onChange"
}, { }, {
"name": "onExpand" "name": "onExpand"
}, { }, {
@ -25,34 +28,38 @@ title: EventSetter
} }
``` ```
#### 事件绑定 ## 事件绑定
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448650540-8b403233-44a5-4b1f-9379-2c55d4694f12.png#clientId=uf9b6db87-aae9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=621&id=u95bb9c9a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1242&originWidth=2540&originalType=binary&ratio=1&rotation=0&showTitle=false&size=356836&status=done&style=none&taskId=u13bc14bd-d85c-46c9-aebd-586dcb32f96&title=&width=1270) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Q5gHFy1uSzqUeEqQK_!!6000000006037-2-tps-2540-1242.png)
可以选择已有的事件(schema中的**methods**节点)进行绑定也可以选择新建事件选择新建事件默认会增加_new的事件后缀命名点确定以后会跳转到对应代码插件对应区块
#### 可以选择已有的事件 (schema 中的**methods**节点) 进行绑定也可以选择新建事件选择新建事件默认会增加_new 的事件后缀命名,点确定以后会跳转到对应代码插件对应区块。
#### 参数设置
如果需要额外传参,需要将扩展参数设置打开,在代码面板中,编辑参数内容 ## 参数设置
如果需要额外传参,需要将扩展参数设置打开,在代码面板中,编辑参数内容。
注意: 注意:
- 额外参数必须被包装成一个对象,如参数模板中所示 - 额外参数必须被包装成一个对象,如参数模板中所示
- 可以使用动态变量例如 (this.itemsthis.state.xxx) - 可以使用动态变量例如 (this.itemsthis.state.xxx)
```json ```javascript
{ {
"testKey":this.state.text testKey: this.state.text,
} }
``` ```
- 该参数是额外参数会加在原有参数后面例如在onClick中加入扩展传参最终函数消费的时候应该如下所示 - 该参数是额外参数,会加在原有参数后面,例如在 onClick 中加入扩展传参,最终函数消费的时候应该如下所示
```javascript ```javascript
// e为onClick原有函数传参extParams为自定义传参 // e 为 onClick 原有函数传参extParams 为自定义传参
onClick(e, extParams) { onClick(e, extParams) {
this.setState({ this.setState({
isShowDialog: extParams.isShowDialog isShowDialog: extParams.isShowDialog,
}) });
} }
``` ```
#### 事件新建函数模板 ## 事件新建函数模板
有时候我们创建的函数会有用到一些通用的函数模板我们可以在物料协议的events.template中创建一个模板如下 有时候我们创建的函数会有用到一些通用的函数模板,我们可以在物料协议的 events.template 中创建一个模板,如下
```javascript
```json
{ {
"configure ": { "configure ": {
"supports": { "supports": {
@ -69,5 +76,7 @@ onClick(e, extParams) {
} }
} }
``` ```
其中 ${extParams} 为扩展参数占位符,如果用户没有声明扩展参数,会移除对应的参数声明,定义模板后,每次创建完函数会自动生成模板函数,如下图 其中 ${extParams} 为扩展参数占位符,如果用户没有声明扩展参数,会移除对应的参数声明,定义模板后,每次创建完函数会自动生成模板函数,如下图
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448650786-62270a89-65d5-42b1-8efd-90b090155c82.png#clientId=uf9b6db87-aae9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=141&id=u4bb4387b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=282&originWidth=1292&originalType=binary&ratio=1&rotation=0&showTitle=false&size=84790&status=done&style=none&taskId=u2b911f77-a018-4f17-a5df-36c2c142d18&title=&width=646)
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XUoXnS1XiLxlxXniw_!!6000000002957-2-tps-1292-282.png)

View File

@ -1,25 +1,28 @@
--- ---
title: IconSetter title: IconSetter
--- ---
#### 简介 ## 简介
用来选择图标 用来选择图标
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394747068-9b8f47e1-06f7-48de-ba73-9ed3d389f913.png#clientId=u144a54e7-b111-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=290&id=uae8bb869&margin=%5Bobject%20Object%5D&name=image.png&originHeight=579&originWidth=1172&originalType=binary&ratio=1&rotation=0&showTitle=false&size=148927&status=done&style=none&taskId=ud281e100-e277-493d-8d4a-0e7b2c1b8f2&title=&width=586) <img src="https://img.alicdn.com/imgextra/i1/O1CN01hdJPHx1zwNKa78YgN_!!6000000006778-2-tps-1172-579.png" width="500"/>
#### setter 配置
## setter 配置
| **属性名** | **类型** | **说明** | | **属性名** | **类型** | **说明** |
| --- | --- | --- | | --- | --- | --- |
| type | String | 选择器返回类型 | type | String | 选择器返回类型 **可选值**: "string" \| "node" |
**可选值**:
"string" &#124; "node" |
| defaultValue | String &#124; ReactNode | 默认值 | | defaultValue | String &#124; ReactNode | 默认值 |
| hasClear | Boolean | 选择器是否显示清除按钮 | | hasClear | Boolean | 选择器是否显示清除按钮 |
| icons | Array | 自定义icon集合默认值详见[图标可选值](#SWnNn) | | icons | Array | 自定义 icon 集合;默认值详见[图标可选值](#图标可选值) |
| placeholder | String | 没有值的时候的占位符 | | placeholder | String | 没有值的时候的占位符 |
#### 返回类型 ## 返回类型
String | ReactNode String | ReactNode
#### 图标可选值
```json ## 图标可选值
```javascript
[ [
'smile', 'smile',
'cry', 'cry',

View File

@ -1,13 +1,15 @@
--- ---
title: MixedSetter title: MixedSetter
--- ---
#### 简介 ## 简介
可以让属性同时支持多个setter 可以让属性同时支持多个 setter
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394866233-4b9127cd-3825-4763-9e2a-526ea2b48140.png#clientId=u7c96c5f7-4dd4-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=240&id=u7ca1df47&margin=%5Bobject%20Object%5D&name=image.png&originHeight=480&originWidth=1552&originalType=binary&ratio=1&rotation=0&showTitle=false&size=272344&status=done&style=none&taskId=u07037884-fbf4-411a-be82-29296ad1fb2&title=&width=776)
<img src="https://img.alicdn.com/imgextra/i4/O1CN01zlCJu21iBLBnxmIn2_!!6000000004374-2-tps-1552-480.png" width="500"/>
## 配置
#### 配置
| **属性名** | **类型** | **说明** | | **属性名** | **类型** | **说明** |
| --- | --- | --- | | --- | --- | --- |
| setters | Array<String\> | SetterName | | setters | Array<String\> | SetterName |

View File

@ -1,11 +1,13 @@
--- ---
title: NumberSetter title: NumberSetter
--- ---
#### 简介 ## 简介
用于输入数字。 用于输入数字。
#### 展示 ## 展示
![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448648108-fae36b4c-fb3d-4a4e-b83e-c5233e8bae5d.png#from=url&id=czSyt&margin=%5Bobject%20Object%5D&originHeight=402&originWidth=576&originalType=binary&ratio=1&status=done&style=none)
#### setter 配置 <img src="https://img.alicdn.com/imgextra/i3/O1CN01b9bRiX1C6F4pCV7GB_!!6000000000031-2-tps-576-402.png" width="300"/>
## setter 配置
| 属性名 | 说明 | | 属性名 | 说明 |
| --- | --- | | --- | --- |
| min, max | 指定最大最小值 | | min, max | 指定最大最小值 |
@ -14,6 +16,7 @@ title: NumberSetter
| units | 指定单位 string | | units | 指定单位 string |
| precision | 设置小数位数 number | | precision | 设置小数位数 number |
#### 返回类型 ## 返回类型
#### Number Number
会返回value值
会返回 value 值

View File

@ -1,24 +1,18 @@
--- ---
title: RadioGroupSetter title: RadioGroupSetter
--- ---
#### 简介 ## 简介
用于直观的展示选择并选择。 用于直观的展示选择并选择。
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395469783-17a5f8b5-112a-420b-a64f-09fffea55067.png#clientId=u8044d585-4c1d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=49&id=ucafe75f2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=98&originWidth=564&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9843&status=done&style=none&taskId=ud3ff8182-f29c-4b81-b4de-e23baa325c1&title=&width=282)
#### setter 配置 <img src="https://img.alicdn.com/imgextra/i2/O1CN01rId9td25yYv0my5Hd_!!6000000007595-2-tps-564-98.png" width="300"/>
## setter 配置
| 属性名 | 说明 | | 属性名 | 说明 |
| --- | --- | | --- | --- |
| defaultValue | 默认值 | | defaultValue | 默认值 |
| options | 传入的数据源, | options | 传入的数据源,**参数格式**: [{img: 'url', value: 'text', label/title: 'text'}, ...] \| [ 'text', 'text', ...] |
**参数格式**:
[
{img: 'url',
value: 'text',
label/title: 'text'}, ...
]
&#124;&#124;
[ 'text', 'text', ...] |
#### 返回类型 ## 返回类型
String | Number | Boolean String | Number | Boolean
会返回options中的value值 会返回 options 中的 value 值

View File

@ -1,24 +1,20 @@
--- ---
title: SelectSetter title: SelectSetter
--- ---
#### 简介 ## 简介
用来选择组件。在限定的可选性内进行选择,核心能力是选择 用来选择组件。在限定的可选性内进行选择,核心能力是选择
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395925308-538eb962-f035-43b9-bdb3-ecc5bc9d1e85.png#clientId=u8b43103b-f292-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=301&id=u7a9a7786&margin=%5Bobject%20Object%5D&name=image.png&originHeight=602&originWidth=574&originalType=binary&ratio=1&rotation=0&showTitle=false&size=36601&status=done&style=none&taskId=u089007a6-76ec-44e8-94b5-127a8ba1a51&title=&width=287)
#### setter 配置 <img src="https://img.alicdn.com/imgextra/i4/O1CN013arqCy1f1JfwdTGQo_!!6000000003946-2-tps-574-602.png" width="300"/>
## setter 配置
| 属性名 | 说明 | | 属性名 | 说明 |
| --- | --- | | --- | --- |
| mode | 选择器模式 | mode | 选择器模式 可选值: 'single', 'multiple', 'tag' |
可选值:
'single', 'multiple', 'tag' |
| defaultValue | 默认值 | | defaultValue | 默认值 |
| options | 传入的数据源, | options | 传入的数据源,**参数格式**: [ {label/title: '文字', value: 'text'}, ...] |
**参数格式**:
[ ## 返回类型
{label/title: '文字', value: 'text'}, ...
] |
#### 返回类型
String | Number | Boolean String | Number | Boolean
会返回options中的value值 会返回 options 中的 value

View File

@ -2,92 +2,92 @@
title: SlotSetter title: SlotSetter
--- ---
## 简介 ## 简介
通过一个开启一个slot插槽可以在物料特定的一个位置渲染一个或者多个节点。slot比较适合物料的局部自定义渲染。 通过一个开启一个 slot插槽可以在物料特定的一个位置渲染一个或者多个节点。slot 比较适合物料的局部自定义渲染。
## 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448654034-6f527cc2-cf65-4e79-b904-21416800b5b8.png#clientId=u091bb73f-2e93-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=227&id=gAVIU&margin=%5Bobject%20Object%5D&name=image.png&originHeight=454&originWidth=588&originalType=binary&ratio=1&rotation=0&showTitle=false&size=103838&status=done&style=none&taskId=u45d2e179-54ea-40d1-a654-66151c337ff&title=&width=294)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395677385-84c39b6d-2356-4d86-a741-edbb7daffd6c.png#clientId=udcc199c0-6236-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=82&id=u999c2367&margin=%5Bobject%20Object%5D&name=image.png&originHeight=164&originWidth=644&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18486&status=done&style=none&taskId=u6c13f469-173f-4ba0-9bfa-866122ef7a4&title=&width=322) <img src="https://img.alicdn.com/imgextra/i3/O1CN01DwFQ221ks3MDXhk36_!!6000000004738-2-tps-588-454.png" width="300"/>
<br/>
<br/>
<img src="https://img.alicdn.com/imgextra/i1/O1CN01pQC6EE1bWDwIkVq2z_!!6000000003472-2-tps-644-164.png" width="300"/>
## setter 配置 ## setter 配置
| 属性名 | 类型 | 说明 | | 属性名 | 类型 | 说明 |
| --- | --- | --- | | --- | --- | --- |
| initialValue | Object | 默认值 | initialValue | Object | 默认值 { "type": "JSSlot", "params": [ "module" ], "value": [] } params:接收函数的入参可以直接在slot节点中消费通过this.module (这里module是示例值可根据实际函数入参更改) value:可以定义一个节点,每次打开插槽的时候默认填充一个节点 |
{ | hideParams | boolean | 是否隐藏入参,注意该值只能隐藏入参的输入框,适合单行展示,实际渲染的时候,还是会传入 params 的参数,和 params:[]不同 |
"type": "JSSlot", | checkedText | string | switch 选中文案,默认显示"启用" |
"params": [ | unCheckedText | string | switch 取消文案,默认显示"关闭" |
"module"
],
"value": []
}
params:接收函数的入参可以直接在slot节点中消费通过this.module (这里module是示例值可根据实际函数入参更改)
value:可以定义一个节点,每次打开插槽的时候默认填充一个节点
|
| hideParams | boolean | 是否隐藏入参注意该值只能隐藏入参的输入框适合单行展示实际渲染的时候还是会传入params的参数和params:[]不同 |
| checkedText | string | switch选中文案默认显示"启用" |
| unCheckedText | string | switch取消文案默认显示"关闭" |
## 配置示例 ## 配置示例
### 普通示例 ### 配置
#### 配置
```typescript ```typescript
{ {
name: "propName", name: 'propName',
title: "propTitle", title: 'propTitle',
setter: { setter: {
componentName: "SlotSetter", componentName: 'SlotSetter',
isRequired: true, isRequired: true,
title: "组件坑位", title: '组件坑位',
initialValue: { initialValue: {
type: "JSSlot", type: 'JSSlot',
value: [] value: [],
}, },
} }
} }
``` ```
#### 组件 ### 组件
```typescript ```typescript
function A(props) { function A(props) {
return props.propName; return props.propName;
} }
``` ```
### 带参数的插槽示例 ## 带参数的插槽示例
#### 配置 ### 配置
```typescript ```typescript
{ {
name: "propName", name: 'propName',
title: "propTitle", title: 'propTitle',
setter: { setter: {
componentName: "SlotSetter", componentName: 'SlotSetter',
isRequired: true, isRequired: true,
title: "组件坑位", title: '组件坑位',
initialValue: { initialValue: {
type: "JSSlot", type: 'JSSlot',
params: [ params: [ 'module'],
"module" value: [],
], },
value: []
},
}
} }
}
``` ```
#### 组件 ### 组件
组件需要传参数进行渲染,和普通示例的使用不一样。 组件需要传参数进行渲染,和普通示例的使用不一样。
```typescript ```typescript
function A(props) { function A(props) {
const module = [] const module = [];
return props.propName(module); return props.propName(module);
} }
``` ```
#### param 使用示例 ### param 使用示例
1.开启插槽 1.开启插槽
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652877673290-7a377a36-7da9-40c1-baff-1c7c8ad04a67.png#clientId=udd177887-e136-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=900&id=u9ba2344a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1800&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1291582&status=done&style=none&taskId=u60418282-46e2-46b4-95d2-156288bcbd7&title=&width=1792)
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01RlOXAV1TbFMBZa6xq_!!6000000002400-2-tps-3584-1800.png)
2.拖拽组件到插槽中 2.拖拽组件到插槽中
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652877759606-6de16048-a5d9-477c-b38b-962690a39254.png#clientId=udd177887-e136-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=903&id=u43b38264&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1230647&status=done&style=none&taskId=u96d44a1e-033f-4cd0-ac81-df6cac8ea18&title=&width=1792)
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01NNiWLs26961orvk9i_!!6000000007618-2-tps-3584-1806.png)
3.在插槽内组件中使用变量绑定,绑定 this.xxx 3.在插槽内组件中使用变量绑定,绑定 this.xxx
xxx 入参的配置 xxx 入参的配置
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652877586491-904d6b18-a41a-4ba2-8664-088cd5feca72.png#clientId=udd177887-e136-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=903&id=u165f1564&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1278387&status=done&style=none&taskId=uc060e73a-b190-480a-8aad-8c20b27290c&title=&width=1792)
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01cBn2ym1XF2cDZo5Yp_!!6000000002893-2-tps-3584-1806.png)

View File

@ -1,14 +1,18 @@
--- ---
title: StringSetter title: StringSetter
--- ---
#### 简介 ## 简介
用来展示和修改字符串类型的属性值,不可换行 用来展示和修改字符串类型的属性值,不可换行
#### 展示 ## 展示
![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448645493-4a30f02e-1869-4963-8d39-40501891ae84.png#from=url&id=mEkyy&margin=%5Bobject%20Object%5D&originHeight=88&originWidth=714&originalType=binary&ratio=1&status=done&style=none)
#### setter 配置 <img src="https://img.alicdn.com/imgextra/i4/O1CN0102tNBy1eEJIMDVZju_!!6000000003839-2-tps-714-88.png" width="300"/>
## setter 配置
| 属性名 | 说明 | | 属性名 | 说明 |
| --- | --- | | --- | --- |
| placeholder | 输入提示 | | placeholder | 输入提示 |
#### 返回类型 ## 返回类型
String String

View File

@ -2,48 +2,27 @@
title: StyleSetter title: StyleSetter
--- ---
## 简介 ## 简介
通过开启StyleSetter,我们可以将样式配置面板来配置样式属性。 通过开启 StyleSetter我们可以将样式配置面板来配置样式属性。
## 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658650544358-3d97f6b1-6269-4627-ab4a-62a43219fd08.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=739&id=u3f141635&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1478&originWidth=596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=75996&status=done&style=none&taskId=u16f49c5d-a32e-4cf8-95ab-e0c1059fbef&title=&width=298)
<img src="https://img.alicdn.com/imgextra/i1/O1CN01plhL0t1DH43CZ8hAa_!!6000000000190-2-tps-596-1478.png" width="300"/>
## setter 配置 ## setter 配置
| 属性名 | 类型 | 说明 | | 属性名 | 类型 | 说明 |
| --- | --- | --- | | --- | --- | --- |
| unit | String | 默认值 px | unit | String | 默认值 px <img src="https://img.alicdn.com/imgextra/i4/O1CN014BRbq41TKIhXjQuOf_!!6000000002363-2-tps-576-98.png" width="250"/> |
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658650635878-fd920e86-ea28-4e08-8676-238ac367a0ee.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=49&id=u3f243c11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=98&originWidth=576&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9796&status=done&style=none&taskId=ucc541aa4-0765-4da9-820c-cee48ed0635&title=&width=288) | placeholderScale | Number | 默认计算尺寸缩放 默认值为 1 <img src="https://img.alicdn.com/imgextra/i4/O1CN01OLWb2g1Yd94uAC6ax_!!6000000003081-2-tps-250-98.png" width="100"/> 在没有设定数值的时候,系统会通过 window.getComputedStyle 来计算展示的数值。在某些场景下,例如手机场景,在编辑器展示的是 375 的实际宽度,但是实际设计尺寸是 750 的宽度,这个时候需要对这个计算尺寸设成 2 |
| | showModuleList | String[] | 默认值 ['background', 'border', 'font', 'layout', 'position'] 分别对应背景、边框、文字、布局、位置五个区块,可以针对不同的场景按需进行展示。 例如文字的组件,我不需要修改边框的样式,就可以把边框模块隐藏掉 |
| placeholderScale | Number | 默认计算尺寸缩放 默认值为1
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658650773475-7ecba070-c81e-4a6c-b346-7aad7dd6a897.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=49&id=u27842257&margin=%5Bobject%20Object%5D&name=image.png&originHeight=98&originWidth=250&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7116&status=done&style=none&taskId=u8ac18c79-d14b-49a6-8788-476524e69da&title=&width=125)
在没有设定数值的时候系统会通过window.getComputedStyle来计算展示的数值。
在某些场景下例如手机场景在编辑器展示的是375的实际宽度但是实际设计尺寸是750的宽度这个时候需要对这个计算尺寸设成2 |
| showModuleList | String[] | 默认值
['background', 'border', 'font', 'layout', 'position']
分别对应背景、边框、文字、布局、位置五个区块,可以针对不同的场景按需进行展示。
例如文字的组件,我不需要修改边框的样式,就可以把边框模块隐藏掉 |
| isShowCssCode | Boolean | 默认值: true, 是否展示css源码编辑 | | isShowCssCode | Boolean | 默认值: true, 是否展示css源码编辑 |
| layoutPropsConfig | Object | 布局样式设置 | | layoutPropsConfig | Object | 布局样式设置 |
| layoutPropsConfig.showDisPlayList | String[] | 默认值 ['inline', 'flex', 'block', 'inline-block', 'none'] | layoutPropsConfig.showDisPlayList | String[] | 默认值 ['inline', 'flex', 'block', 'inline-block', 'none'] <img src="https://img.alicdn.com/imgextra/i3/O1CN01nucfjP1gT5Iu6IMua_!!6000000004142-2-tps-474-72.png" width="250"/> 可按需展示 |
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651295786-48ca3773-1b4e-4f2e-9521-0ebbfcfe5361.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=36&id=u50dae00c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=72&originWidth=474&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7621&status=done&style=none&taskId=ub5804835-d0b2-45d7-a419-66ac1005afa&title=&width=237) | layoutPropsConfig.isShowPadding | String | 默认值 true <img src="https://img.alicdn.com/imgextra/i4/O1CN01frOzt81uLfVjYIR8I_!!6000000006021-2-tps-548-382.png" width="250"/> 是否展示内边距(四个边) ||
可按需展示 | layoutPropsConfig.isShowMargin | Boolean | 默认值 true <img src="https://img.alicdn.com/imgextra/i3/O1CN01H2qo0N1dVssDYT8EN_!!6000000003742-2-tps-536-482.png" width="250"/> 是否展示外边距(四个边) ||
| | layoutPropsConfig.isShowWidthHeight | Boolean | 默认值 true <img src="https://img.alicdn.com/imgextra/i2/O1CN01A0pqoz1CAp2KUv230_!!6000000000041-2-tps-546-102.png" width="250"/> 是否展示宽高 |
| layoutPropsConfig.isShowPadding | String | 默认值 true
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651496157-c84348d4-a47f-44b4-b2c5-74b21e97747a.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=191&id=u70235603&margin=%5Bobject%20Object%5D&name=image.png&originHeight=382&originWidth=548&originalType=binary&ratio=1&rotation=0&showTitle=false&size=20439&status=done&style=none&taskId=udae33336-ce05-41a9-89c5-361a63d061a&title=&width=274)
是否展示内边距 (四个边) |
| layoutPropsConfig.isShowMargin | Boolean | 默认值 true
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651539776-090de3e1-6293-4660-b74f-9bcf027381c6.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=241&id=uab3771c7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=482&originWidth=536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29325&status=done&style=none&taskId=uc287d55d-5363-4b37-978b-6e150f36141&title=&width=268)
是否展示外边距 (四个边) |
| layoutPropsConfig.isShowWidthHeight | Boolean | 默认值 true
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651621765-06e81934-9a90-4290-89dd-75ffb56808a5.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=51&id=u02aa5918&margin=%5Bobject%20Object%5D&name=image.png&originHeight=102&originWidth=546&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9945&status=done&style=none&taskId=u394451ef-266c-440d-a86e-fc1a01320ea&title=&width=273)
是否展示宽高 |
| fontPropsConfig | Object | 文字样式设置 | | fontPropsConfig | Object | 文字样式设置 |
| fontPropsConfig.fontFamilyList | Array | [ | fontPropsConfig.fontFamilyList | Array | [ { value: 'Helvetica', label: 'Helvetica' }, { value: 'Arial', label: 'Arial' },] 可以定制文字字体选项 |
{ value: 'Helvetica', label: 'Helvetica' },
{ value: 'Arial', label: 'Arial' },
{ value: 'serif', label: 'serif' },
]
可以定制文字字体选项 |
| positionPropsConfig | Object | 位置样式设置 | | positionPropsConfig | Object | 位置样式设置 |
| positionPropsConfig.isShowFloat | Boolean | 默认true 是否展示浮动 | | positionPropsConfig.isShowFloat | Boolean | 默认 true 是否展示浮动 |
| positionPropsConfig.isShowClear | Boolean | 默认true 是否展示清除浮动 | | positionPropsConfig.isShowClear | Boolean | 默认 true 是否展示清除浮动 |

View File

@ -1,14 +1,16 @@
--- ---
title: StyleSetter title: TextAreaSetter
--- ---
#### 简介 ## 简介
表单输入组件。 表单输入组件。
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395839676-9feaa4d6-dbec-40c0-a93c-6014006a50c5.png#clientId=u01f23b13-e688-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=146&id=u29c456c5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=1026&originalType=binary&ratio=1&rotation=0&showTitle=false&size=304205&status=done&style=none&taskId=u83ca85c2-3a04-4c41-a055-31d1bb86d84&title=&width=513)
#### setter 配置 <img src="https://img.alicdn.com/imgextra/i3/O1CN012p7cxS1KsLbETRYpY_!!6000000001219-2-tps-1026-292.png" width="300"/>
## setter 配置
| **属性名** | **类型** | **说明** | | **属性名** | **类型** | **说明** |
| --- | --- | --- | | --- | --- | --- |
| placeholder | String | 输入提示 | | placeholder | String | 输入提示 |
#### 返回类型 ## 返回类型
String String

View File

@ -1,12 +1,16 @@
--- ---
title: VariableSetter title: VariableSetter
--- ---
#### 简介 ## 简介
用来给属性值设定变量 用来给属性值设定变量
#### 展示 ## 展示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395534301-67aaf74b-2561-4682-a0b2-dcde642a8d7c.png#clientId=u46178fa3-bc0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=46&id=ucd7e6f91&margin=%5Bobject%20Object%5D&name=image.png&originHeight=92&originWidth=578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=10671&status=done&style=none&taskId=u854e606f-bbd1-42f4-81a2-d161aa4e2d3&title=&width=289)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448653288-1b5b46c8-5ea1-455d-9ce4-19abade13b31.png#clientId=udec6352b-e220-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=595&id=u2395a6a5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1190&originWidth=1564&originalType=binary&ratio=1&rotation=0&showTitle=false&size=256705&status=done&style=none&taskId=u3f3418f8-b6ad-464e-8fe6-89586fbc07d&title=&width=782) <img src="https://img.alicdn.com/imgextra/i3/O1CN01RhKkpP1QexivgHNVB_!!6000000002002-2-tps-578-92.png" width="300"/>
#### <br/>
#### 变量列表
包含所有的在协议中的**state**(state属性)节点数据和**methods**(自定义处理函数)节点数据 <img src="https://img.alicdn.com/imgextra/i3/O1CN014GxSj41xovf3cpX6y_!!6000000006491-2-tps-1564-1190.png" width="500"/>
## 变量列表
包含所有的在协议中的**state**(state 属性) 节点数据和**methods**(自定义处理函数) 节点数据

View File

@ -4,38 +4,26 @@ sidebar_position: 4
--- ---
| 预置 Setter | 返回类型 | 用途 | 截图 | | 预置 Setter | 返回类型 | 用途 | 截图 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| [ArraySetter](https://www.yuque.com/lce/doc/eiegwf?view=doc_embed&from=kb&from=kb&outline=1&title=1) | T[] | 列表数组行数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395227012-97d27c4d-e053-4aae-9de1-726015081a4d.png#crop=0&crop=0&crop=1&crop=1&from=url&id=MHREr&margin=%5Bobject%20Object%5D&originHeight=362&originWidth=584&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | [ArraySetter](./setterDetails/array) | T[] | 列表数组行数据设置器 | ![](https://img.alicdn.com/imgextra/i1/O1CN01UNmb7429mtHsbTHg3_!!6000000008111-2-tps-584-362.png) |
| [BoolSetter](https://www.yuque.com/lce/doc/mdxryw?view=doc_embed&from=kb&from=kb&outline=1&title=1) | boolean | 布尔型数据设置器, | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394538926-81adaab2-fe44-4cf4-93a0-4f46d790cfc6.png#crop=0&crop=0&crop=1&crop=1&from=url&id=yVcL4&margin=%5Bobject%20Object%5D&originHeight=82&originWidth=320&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | [BoolSetter](./setterDetails/behavior) | boolean | 布尔型数据设置器, | ![](https://img.alicdn.com/imgextra/i2/O1CN01gZlHyx24MiZfjU61A_!!6000000007377-2-tps-320-82.png) |
| ClassNameSetter | string | 样式名设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644417220734-fd13e249-43f0-4caa-8122-9c1a791cd30f.png#crop=0&crop=0&crop=1&crop=1&from=url&id=RNQQQ&margin=%5Bobject%20Object%5D&originHeight=180&originWidth=502&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | ClassNameSetter | string | 样式名设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01ResoVi1PtKWxwuww8_!!6000000001898-2-tps-502-180.png) |
| [ColorSetter](https://www.yuque.com/lce/doc/hu5ir6?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 颜色设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394553552-2c8c3982-1671-47b3-a569-297bcb838b79.png#crop=0&crop=0&crop=1&crop=1&from=url&id=CxWyj&margin=%5Bobject%20Object%5D&originHeight=728&originWidth=590&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | [ColorSetter](./setterDetails/color) | string | 颜色设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN018gsNdw1Qt9zsZWP9K_!!6000000002033-2-tps-590-728.png) |
| DateMonthSetter | | DateMonthSetter | | 日期型 - 月数据设置器 | |
| 日期型-月数据设置器 | | DateRangeSetter | | 日期型数据设置器,可选择时间区间 | |
| | DateSetter | | 日期型数据设置器 | |
| DateRangeSetter | | DateYearSetter || 日期型 - 年数据设置器 | |
| 日期型数据设置器,可选择时间区间 | | [EventSetter](./setterDetails/event) | function | 事件绑定设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN01qxIYiO1ksVknhTpnW_!!6000000004739-2-tps-1202-1014.png) |
| | [IconSetter](./setterDetails/icon) | string | 图标设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01zsOMxo1TXaBmjHCRc_!!6000000002392-2-tps-1172-579.png) |
| DateSetter | | FunctionSetter | any | 函数型数据设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN01jLiJBo1ZIp7OmDLp0_!!6000000003172-2-tps-794-110.png) |
| 日期型数据设置器 | | JsonSetter | object | json 型数据设置器 | ![](https://img.alicdn.com/imgextra/i2/O1CN01mQTFjY1YiBQzWYj64_!!6000000003092-2-tps-1076-1068.png) |
| | [MixedSetter](./setterDetails/mixed) | any | 混合型数据设置器 | ![](https://img.alicdn.com/imgextra/i1/O1CN01ZxomFY1JW4j7wIGuQ_!!6000000001035-2-tps-1552-480.png) |
| DateYearSetter | | [NumberSetter](./setterDetails/number) | number | 数值型数据设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01dSfSgg1WS2EpbqJIO_!!6000000002786-2-tps-1152-328.png) |
| 日期型-年数据设置器 | | ObjectSetter | Record<string, any> | 对象数据设置器,一般内嵌在 ArraySetter 中 ||
| | [RadioGroupSetter](./setterDetails/radioGroup)| string &#124; number &#124; boolean | 枚举型数据设置器,采用 tab 选择的形式展现 || ![](https://img.alicdn.com/imgextra/i4/O1CN01Z0Zgi51W10s5L2Hce_!!6000000002727-2-tps-564-98.png) |
| [EventSetter](https://www.yuque.com/lce/doc/fiu8cz?view=doc_embed&from=kb&from=kb&outline=1&title=1) | function | 事件绑定设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394913684-e50d5fb4-50f4-4f6a-b5f8-5a6269b56676.png#crop=0&crop=0&crop=1&crop=1&from=url&id=lCP5h&margin=%5Bobject%20Object%5D&originHeight=1014&originWidth=1202&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | [SelectSetter](./setterDetails/select) | string &#124; number &#124; boolean | 枚举型数据设置器,采用下拉的形式展现 | ![](https://img.alicdn.com/imgextra/i1/O1CN01sfUEgZ1I0BXCl60LM_!!6000000000830-2-tps-582-282.png) |
| [IconSetter](https://www.yuque.com/lce/doc/ry138x?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 图标设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394768487-d7b9a492-254e-46bd-a755-f8f73d76b932.png#crop=0&crop=0&crop=1&crop=1&from=url&id=pbQvJ&margin=%5Bobject%20Object%5D&originHeight=579&originWidth=1172&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | [SlotSetter](./setterDetails/slot) | Element &#124; Element[] | 节点型数据设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01wulNGt1qNip0IlEsF_!!6000000005484-2-tps-644-164.png) |
| FunctionSetter | any | 函数型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644417386132-50215eb0-ca7e-499b-8ca8-bd0b19ce89e1.png#crop=0&crop=0&crop=1&crop=1&from=url&id=YZ16c&margin=%5Bobject%20Object%5D&originHeight=110&originWidth=794&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | [StringSetter](./setterDetails/string) | string | 短文本型数据设置器,不可换行 | ![](https://img.alicdn.com/imgextra/i4/O1CN01iYalzO1xVh1ikLvSr_!!6000000006449-2-tps-414-102.png) |
| JsonSetter | object | json型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644418044457-a50b1621-090a-440d-9735-b3e9b7b3abd8.png#crop=0&crop=0&crop=1&crop=1&from=url&id=OywYO&margin=%5Bobject%20Object%5D&originHeight=1068&originWidth=1076&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | StyleSetter || 样式设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN01ZwX2pO26UAFKuYfuF_!!6000000007664-2-tps-788-1214.png) |
| [MixedSetter](https://www.yuque.com/lce/doc/ah6o2c?view=doc_embed&from=kb&from=kb&outline=1&title=1) | any | 混合型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394872594-bb8f8de1-824a-4ba7-8b83-e408434a7d29.png#crop=0&crop=0&crop=1&crop=1&from=url&id=it6Xz&margin=%5Bobject%20Object%5D&originHeight=480&originWidth=1552&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | [TextAreaSetter](./setterDetails/textArea) | string | 长文本型数据设置器,可换行 | ![](https://img.alicdn.com/imgextra/i4/O1CN01GMu8YJ1nqAZoYQ3xi_!!6000000005140-2-tps-1026-292.png) |
| [NumberSetter](https://www.yuque.com/lce/doc/hk65u5?view=doc_embed&from=kb&from=kb&outline=1&title=1) | number | 数值型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394982613-b1a43863-fd63-4bb4-b5fe-2f36109c449b.png#crop=0&crop=0&crop=1&crop=1&from=url&id=bEZjH&margin=%5Bobject%20Object%5D&originHeight=328&originWidth=1152&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | | TimePicker | | 时间型数据设置器 ||
| ObjectSetter | Record<string, any> | 对象数据设置器一般内嵌在ArraySetter中 | | [VariableSetter](./setterDetails/variable) | any | 变量型数据设置器, | ![](https://img.alicdn.com/imgextra/i1/O1CN015V5AAY1v3B8XxQ75k_!!6000000006116-2-tps-578-92.png) |
|
| [RadioGroupSetter](https://www.yuque.com/lce/doc/cmpf0b?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string &#124; number &#124; boolean | 枚举型数据设置器采用tab选择的形式展现 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395460363-1fdb034c-69d7-404d-9226-37f1d4562210.png#crop=0&crop=0&crop=1&crop=1&from=url&id=XSyl3&margin=%5Bobject%20Object%5D&originHeight=98&originWidth=564&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) |
| [SelectSetter](https://www.yuque.com/lce/doc/po1t1r?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string &#124; number &#124; boolean | 枚举型数据设置器,采用下拉的形式展现 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395970016-dfe95495-53b1-4f86-afc6-a0c621917440.png#crop=0&crop=0&crop=1&crop=1&from=url&id=NPzvg&margin=%5Bobject%20Object%5D&originHeight=282&originWidth=582&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) |
| [SlotSetter](https://www.yuque.com/lce/doc/af5vba?view=doc_embed&from=kb&from=kb&outline=1&title=1) | Element &#124; Element[] | 节点型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395692198-ca0cb611-0b7b-43b2-9f3b-3f6983cc3b37.png#crop=0&crop=0&crop=1&crop=1&from=url&id=SLNSR&margin=%5Bobject%20Object%5D&originHeight=164&originWidth=644&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) |
| [StringSetter](https://www.yuque.com/lce/doc/qogni4?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 短文本型数据设置器,不可换行 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395613012-e7e5db32-9281-4f19-a18d-284765cd1184.png#crop=0&crop=0&crop=1&crop=1&from=url&id=OySEz&margin=%5Bobject%20Object%5D&originHeight=102&originWidth=414&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) |
| StyleSetter |
| 样式设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644416984306-00aca829-3611-4f4c-b6b6-a20d0da0bfe7.png#crop=0&crop=0&crop=1&crop=1&from=url&id=aWlAc&margin=%5Bobject%20Object%5D&originHeight=1214&originWidth=788&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) |
| [TextAreaSetter](https://www.yuque.com/lce/doc/gp36z6?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 长文本型数据设置器,可换行 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395843901-4d9c3e04-f6fc-4d50-93ed-44e6d8a99b9a.png#crop=0&crop=0&crop=1&crop=1&from=url&id=grvEZ&margin=%5Bobject%20Object%5D&originHeight=292&originWidth=1026&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) |
| TimePicker |
| 时间型数据设置器 |
|
| [VariableSetter](https://www.yuque.com/lce/doc/lkvb36?view=doc_embed&from=kb&from=kb&outline=1&title=1) | any | 变量型数据设置器, | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395524553-dba00e02-f44c-429f-a8f4-c0e5f6d8b35f.png#crop=0&crop=0&crop=1&crop=1&from=url&id=L5BHL&margin=%5Bobject%20Object%5D&originHeight=92&originWidth=578&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) |

View File

@ -1,5 +1,5 @@
{ {
"label": "创建低代码应用", "label": "创建低代码编辑器",
"position": 1, "position": 1,
"collapsed": false, "collapsed": false,
"collapsible": true "collapsible": true

View File

@ -8,39 +8,50 @@ sidebar_position: 0
1. clone 低代码项目的官方 demo直接启动项目。适合普通人。 1. clone 低代码项目的官方 demo直接启动项目。适合普通人。
2. 手工引入低代码 UMD 包,手工配置、打包和启动。适合 Webpack 配置工程师。 2. 手工引入低代码 UMD 包,手工配置、打包和启动。适合 Webpack 配置工程师。
# 方法 1: Clone 并启动 ## 方法 1: 以官方 Demo 为基础使用
可以通过两种方式之一获取低代码编辑器的示例代码: 可以通过两种方式之一获取低代码编辑器的示例代码:
1. 直接[在 github 仓库下](https://github.com/alibaba/lowcode-demo)进行下载 1. 直接[在 github 仓库下](https://github.com/alibaba/lowcode-demo)进行下载
![Rectangle 2.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645178084931-b81f6960-f0be-4695-ae38-e2632c859629.png#clientId=u6721b06e-9fb2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=259&id=ud829c08c&margin=%5Bobject%20Object%5D&name=Rectangle%202.png&originHeight=517&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=163331&status=done&style=none&taskId=ua56b6104-b23f-4dd6-a95c-4fa8ac8cb3c&title=&width=750) ![](https://img.alicdn.com/imgextra/i3/O1CN01PfGV3h1oJ1Wv3sakc_!!6000000005203-2-tps-1500-517.png)
2. 如果本地安装了 git可以通过 git clone 方式进行下载 2. 如果本地安装了 git可以通过 git clone 方式进行下载
(这个方法的好处是 demo 有了更新,可以通过 merge 方式跟上) (这个方法的好处是 demo 有了更新,可以通过 merge 方式跟上)
```typescript ```bash
git clone https://github.com/alibaba/lowcode-demo.git git clone https://github.com/alibaba/lowcode-demo.git
``` ```
拉取仓库代码后,需要进行如下配置或安装过程: 拉取仓库代码后,需要进行如下配置或安装过程:
1. 确保本地安装了 Node.js 和 npm如果没有[您可以通过 nvm 进行快捷的安装](https://github.com/nvm-sh/nvm) 1. 确保本地安装了 Node.js 和 npm如果没有[您可以通过 nvm 进行快捷的安装](https://github.com/nvm-sh/nvm)
2. 确保为 npm [设置了可以访问的 npm 源,保证安装过程无网络问题](https://npmmirror.com/) 2. 确保为 npm [设置了可以访问的 npm 源,保证安装过程无网络问题](https://npmmirror.com/)
3. 执行 `npm install` 3. 选择目录下其中一个 demo 工程进入,建议选择 `demo-general`
```bash
cd demo-general
```
4. 安装依赖
```bash
npm install
```
5. 安装依赖成功后,启动项目 (注意观察上一步的输出,如有 error 等失败信息,请先进行排查)
```bash
npm start
```
执行后如果看到这个界面,说明项目启动成功。您可以继续看后续章节了。本章节后续内容均为高级配置方式。
依赖完全安装完成后,执行 `npm start`,如果看到这个界面,说明项目启动成功。您可以继续看后续章节了。本章节后续内容均为高级配置方式。 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN013qJVoV1OAcFNKFrIQ_!!6000000001665-2-tps-3060-1634.png)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644982015764-35bb5f58-fbd6-4838-9792-3c5b2136162d.png#clientId=ub335956d-fdf2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=817&id=u01bca493&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1634&originWidth=3060&originalType=binary&ratio=1&rotation=0&showTitle=false&size=216709&status=done&style=stroke&taskId=u467c43dc-35c5-4c84-907d-d6db9a0b839&title=&width=1530) ## 方法 2: 使用 UMD 包方式配置
# 方法 2: 手工引入低代码 UMD 包,手工配置打包和启动
如果您不是从零开始的项目,您可能需要手工引入低代码引擎。 如果您不是从零开始的项目,您可能需要手工引入低代码引擎。
## 引入 UMD 包资源 ### 引入 UMD 包资源
我们需要在启动前,正确在项目中通过 UMD 包方式直接依赖如下内容: 我们需要在启动前,正确在项目中通过 UMD 包方式直接依赖如下内容:
(亦可使用异步加载工具,如果您按照正确的顺序进行加载) > 亦可使用异步加载工具,如果您按照正确的顺序进行加载
```html ```html
<!-- 低代码引擎的页面框架样式 --> <!-- 低代码引擎的页面框架样式 -->
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alilc/lowcode-engine@latest/dist/css/engine-core.css" /> <link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alilc/lowcode-engine@latest/dist/css/engine-core.css" />
@ -72,9 +83,9 @@ git clone https://github.com/alibaba/lowcode-demo.git
> 注:如果 unpkg 的服务比较缓慢,您可以使用 alicdn 来获得确定版本的低代码引擎,如对于引擎的 1.0.1 版本,可用 [https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.1/dist/js/engine-core.js](https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.1/dist/js/engine-core.js) > 注:如果 unpkg 的服务比较缓慢,您可以使用 alicdn 来获得确定版本的低代码引擎,如对于引擎的 1.0.1 版本,可用 [https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.1/dist/js/engine-core.js](https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.1/dist/js/engine-core.js)
## 配置打包 ### 配置打包
因为这些资源已经通过 UMD 方式引入,所以在 Webpack 等构建工具中需要配置它们为 external不再重复打包 因为这些资源已经通过 UMD 方式引入,所以在 webpack 等构建工具中需要配置它们为 external不再重复打包
```javascript ```javascript
{ {
@ -84,20 +95,16 @@ git clone https://github.com/alibaba/lowcode-demo.git
"prop-types": "var window.PropTypes", "prop-types": "var window.PropTypes",
"@alifd/next": "var window.Next", "@alifd/next": "var window.Next",
"@alilc/lowcode-engine": "var window.AliLowCodeEngine", "@alilc/lowcode-engine": "var window.AliLowCodeEngine",
"@alilc/lowcode-editor-core": "var window.AliLowCodeEngine.common.editorCabin",
"@alilc/lowcode-editor-skeleton": "var window.AliLowCodeEngine.common.skeletonCabin",
"@alilc/lowcode-designer": "var window.AliLowCodeEngine.common.designerCabin",
"@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
"@ali/lowcode-engine": "var window.AliLowCodeEngine",
"moment": "var window.moment", "moment": "var window.moment",
"lodash": "var window._" "lodash": "var window._"
} }
} }
``` ```
## 初始化低代码编辑器 ### 初始化低代码编辑器
### 方法 2.1 使用 init 进行初始化 #### 方法 2.1 使用 init 进行初始化
正确引入后,我们可以直接通过 window 上的变量进行引用,如 `window.AliLowCodeEngine.init`。您可以直接通过此方式初始化低代码引擎: 正确引入后,我们可以直接通过 window 上的变量进行引用,如 `window.AliLowCodeEngine.init`。您可以直接通过此方式初始化低代码引擎:
@ -114,11 +121,12 @@ window.AliLowCodeEngine.init(document.getElementById('lce-container'), {
// package.json // package.json
{ {
"devDependencies": { "devDependencies": {
"@alilc/lowcode-engine": "beta" "@alilc/lowcode-engine": "^1.0.0"
} }
} }
``` ```
```javascript ```javascript
// src/index.tsx
import { init } from '@alilc/lowcode-engine'; import { init } from '@alilc/lowcode-engine';
init(document.getElementById('lce-container'), { init(document.getElementById('lce-container'), {
@ -133,52 +141,61 @@ init 的功能包括但不限于:
2. 传递 preference 并设置 plugins 入参; 2. 传递 preference 并设置 plugins 入参;
3. 初始化 Workbench 3. 初始化 Workbench
> 本节中的低代码编辑器例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/index.ts#L21-L34](https://github.com/alibaba/lowcode-demo/blob/main/src/index.ts#L21-L34) > 本节中的低代码编辑器例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/index.ts](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/index.ts)
### 方法 2.2 使用 skeletonCabin.Workbench 方式初始化 #### 方法 2.2 使用 skeletonCabin.Workbench 方式初始化
`init()` 内部会调用 `ReactDOM.render()` 函数,因此这样初始化的内容没有办法与外部的 React 组件进行通信,也就没有办法在一些自定义的 plugin 中获取 redux 上的全局数据等内容。 `init()` 内部会调用 `ReactDOM.render()` 函数,因此这样初始化的内容没有办法与外部的 React 组件进行通信,也就没有办法在一些自定义的 plugin 中获取 redux 上的全局数据等内容。
因此,这种场景下您可以通过 `skeletonCabin.Workbench` 进行初始化。 因此,这种场景下您可以通过 `skeletonCabin.Workbench` 进行初始化。
> 注:您不需要同时使用 2.1 和 2.2 的方法。根据使用场景,只有需要低代码引擎插件和外界进行一定通信时2.2 提供的方法才是必要的 > 注:**不需要**同时使用 2.1 和 2.2 的方法。根据使用场景,当且有需要插件和外界进行一定通信时,才需要使用 2.2 提供的方法。
```javascript ```javascript
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react';
import { project, plugins, common, skeleton } from '@alilc/lowcode-engine' import { project, plugins, common, skeleton } from '@alilc/lowcode-engine';
// 此 schema 参考 demo 中的默认 schema 书写 // 此处略去若干依赖引用
import userSchema from './schema.json'
export default function EditorView() { async function registerPlugins() {
// 此处略去若干插件注册
}
function EditorView() {
/** 插件是否已初始化成功,因为必须要等插件初始化后才能渲染 Workbench */ /** 插件是否已初始化成功,因为必须要等插件初始化后才能渲染 Workbench */
const [hasPluginInited, setHasPluginInited] = useState(false); const [hasPluginInited, setHasPluginInited] = useState(false);
useEffect(() => { useEffect(() => {
plugins.init().then(() => { plugins.init().then(() => {
setHasPluginInited(true) setHasPluginInited(true);
}).catch(err => console.error(err)) }).catch(err => console.error(err));
}, []); }, []);
useEffect(() => {
project.importSchema(userSchema)
}, [userSchema]);
if (!hasPluginInited) { if (!hasPluginInited) {
return null; return null;
} }
const Workbench = common.skeletonCabin.Workbench;
return ( return <Workbench />;
<common.skeletonCabin.Workbench
skeleton={skeleton}
/>
);
} }
(async function main() {
await registerPlugins();
config.setConfig({
enableCondition: true,
enableCanvasLock: true,
supportVariableGlobally: true,
requestHandlersMap: {
fetch: createFetchHandler()
}
});
ReactDOM.render(<EditorView />, document.getElementById('lce-container')!);
})();
``` ```
> 本节中的低代码编辑器类似的例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/custom-initialization/index.tsx](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/custom-initialization/index.tsx) > 本节中的低代码编辑器类似的例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/demo-custom-initialization/src/index.tsx](https://github.com/alibaba/lowcode-demo/blob/main/demo-custom-initialization/src/index.tsx)
# 配置低代码编辑器 ## 配置低代码编辑器
详见“低代码扩展简述“章节。 详见[低代码扩展简述](/site/docs/guide/expand/editor/summary)章节。

View File

@ -5,18 +5,20 @@ sidebar_position: 1
低代码引擎的编辑器将产出两份数据: 低代码引擎的编辑器将产出两份数据:
- 资产包数据 assets包含物料名称、包名及其获取方式对应协议中的[《低代码引擎资产包协议规范》](https://lowcode-engine.cn/assets) - 资产包数据 assets包含物料名称、包名及其获取方式对应协议中的[《低代码引擎资产包协议规范》](/site/docs/specs/assets-spec)
- 页面数据 schema包含页面结构信息、生命周期和代码信息对应协议中的[《低代码引擎搭建协议规范》](https://lowcode-engine.cn/lowcode) - 页面数据 schema包含页面结构信息、生命周期和代码信息对应协议中的[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)
经过上述两份数据,可以直接交由渲染模块或者出码模块来运行,二者的区别在于: 经过上述两份数据,可以直接交由渲染模块或者出码模块来运行,二者的区别在于:
- 渲染模块:使用资产包数据、页面数据和低代码运行时,并且允许维护者在低代码编辑器中用 Low Code 的方式继续维护; - 渲染模块:使用资产包数据、页面数据和低代码运行时,并且允许维护者在低代码编辑器中用 `低代码LowCode`的方式继续维护;
- 出码模块:不依赖低代码运行时和页面数据,直接生成可直接运行的代码,并且允许维护者用 Pro Code 的方式继续维护,但无法再利用用低代码编辑器; - 出码模块:不依赖低代码运行时和页面数据,直接生成可直接运行的代码,并且允许维护者用 `源码ProCode` 的方式继续维护,但无法再利用低代码编辑器;
> 渲染和出码的详细阐述可参考此文:[低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ)
## 渲染模块 ## 渲染模块
[在 Demo 中](https://lowcode-engine.cn/demo),右上角有渲染模块的示例使用方式: [在 Demo 中](https://lowcode-engine.cn/demo/demo-general/index.html),右上角有渲染模块的示例使用方式:
![Mar-13-2022 16-52-49.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1647161579197-20c72ea4-6d9a-4692-9b23-005182f6387e.gif#clientId=u244806d0-100a-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u9b403d3d&margin=%5Bobject%20Object%5D&name=Mar-13-2022%2016-52-49.gif&originHeight=514&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=755539&status=done&style=stroke&taskId=u14f0f4c2-4d6c-4296-b2df-ccda870faff&title=) ![Mar-13-2022 16-52-49.gif](https://img.alicdn.com/imgextra/i2/O1CN01PRsEl61o7Zct5fJML_!!6000000005178-1-tps-1534-514.gif)
基于官方提供的渲染模块 [@alifd/lowcode-react-renderer](https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer),你可以在 React 上下文渲染低代码编辑器产出的页面。 基于官方提供的渲染模块 [@alifd/lowcode-react-renderer](https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer),你可以在 React 上下文渲染低代码编辑器产出的页面。
@ -28,6 +30,7 @@ sidebar_position: 1
- components需要根据编辑器产出的资产包 assets 中,根据页面 projectSchema 中声明依赖的 componentsMap来加载所有依赖的资产包最后获取资产包的实例并生成物料 - 资产包的键值对 components。 - components需要根据编辑器产出的资产包 assets 中,根据页面 projectSchema 中声明依赖的 componentsMap来加载所有依赖的资产包最后获取资产包的实例并生成物料 - 资产包的键值对 components。
这个过程可以参考 demo 项目中的 `src/preview.tsx` 这个过程可以参考 demo 项目中的 `src/preview.tsx`
```typescript ```typescript
async function getSchemaAndComponents() { async function getSchemaAndComponents() {
const packages = JSON.parse(window.localStorage.getItem('packages') || ''); const packages = JSON.parse(window.localStorage.getItem('packages') || '');
@ -76,25 +79,28 @@ const SamplePreview = () => {
schema={schema} schema={schema}
components={components} components={components}
/> />
) );
} }
``` ```
> 注:您可以注意到,此处是依赖了 React 进行渲染的,对于 Vue 形态的渲染或编辑器支持,详见[对应公告](https://github.com/alibaba/lowcode-engine/issues/236)。 > 注 1您可以注意到此处是依赖了 React 进行渲染的,对于 Vue 形态的渲染或编辑器支持,详见[对应公告](https://github.com/alibaba/lowcode-engine/issues/236)。
> 本节示例可在 Demo 代码里找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/preview.tsx](https://github.com/alibaba/lowcode-demo/blob/main/src/preview.tsx#L54-L58) >
> 注 2本节示例可在 Demo 代码里找到更完整的版本:[https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/preview.tsx](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/preview.tsx)
## 出码模块 ## 出码模块
[在 Demo 中](https://lowcode-engine.cn/demo),右上角有出码模块的示例使用方式: [在 Demo 中](https://lowcode-engine.cn/demo/demo-general/index.html),右上角有出码模块的示例使用方式:
![Mar-13-2022 16-55-56.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1647161777243-b16045c4-3cac-4920-8e68-ce064a90fe26.gif#clientId=u244806d0-100a-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=ud7bfd5a2&margin=%5Bobject%20Object%5D&name=Mar-13-2022%2016-55-56.gif&originHeight=514&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1727314&status=done&style=stroke&taskId=u4e079100-d6a0-4ad2-ac0c-938ab8e7759&title=)
![Mar-13-2022 16-55-56.gif](https://img.alicdn.com/imgextra/i3/O1CN017CVeka27p3vwrGI1D_!!6000000007845-1-tps-1536-514.gif)
> 本节示例可在出码插件里找到:[https://github.com/alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo) > 本节示例可在出码插件里找到:[https://github.com/alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo)
## 低代码的生产和消费 ## 低代码的生产和消费流程总览
经过“接入编辑器” - “接入运行时” 这两节的介绍,我们已经可以了解到低代码所构建的生产和消费流程了,梳理如下图: 经过“接入编辑器” - “接入运行时”这两节的介绍,我们已经可以了解到低代码所构建的生产和消费流程了,梳理如下图:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644405393410-1c54fa37-74de-4c48-a4a9-1cbce359feeb.png#clientId=ua752ee55-c225-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4ceefadb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1786&originWidth=3206&originalType=binary&ratio=1&rotation=0&showTitle=false&size=312489&status=done&style=none&taskId=uae8eacd1-4c05-4689-bb6a-24ceb76327d&title=&width=710)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01yiFiUc1rT32o9HpnW_!!6000000005631-2-tps-3206-1786.png)
如上述流程所示,您一般需要一个后端项目来保存页面数据信息,如果资产包信息是动态的,也需要保存资产包信息。 如上述流程所示,您一般需要一个后端项目来保存页面数据信息,如果资产包信息是动态的,也需要保存资产包信息。

View File

@ -6,19 +6,19 @@ sidebar_position: 7
考虑之后的扩展性和兼容性,核心分为了 2 类包,一个是 **datasource-engine** ,另一个是 **datasource-engine-x-handler** x 的意思其实是对应数据源的 type比如说 **datasource-engine-mtop-handler**,也就是说我们会将真正的请求工具放在 handler 里面去处理engine 在使用的时候由使用方自身来决定需要注册哪些 handler这样的目的有 2 个,一个是如果将所有的 handler 都放到一个包,对于端上来说这个包过大,有一些浪费资源和损耗性能的问题,另一个是如果有新的类型的数据源出现,只需要按照既定的格式去新增一个对应的 handler 处理器即可,达到了高扩展性的目的; 考虑之后的扩展性和兼容性,核心分为了 2 类包,一个是 **datasource-engine** ,另一个是 **datasource-engine-x-handler** x 的意思其实是对应数据源的 type比如说 **datasource-engine-mtop-handler**,也就是说我们会将真正的请求工具放在 handler 里面去处理engine 在使用的时候由使用方自身来决定需要注册哪些 handler这样的目的有 2 个,一个是如果将所有的 handler 都放到一个包,对于端上来说这个包过大,有一些浪费资源和损耗性能的问题,另一个是如果有新的类型的数据源出现,只需要按照既定的格式去新增一个对应的 handler 处理器即可,达到了高扩展性的目的;
![](https://intranetproxy.alipay.com/skylark/lark/0/2020/png/275191/1599545889374-73acbe09-3bb6-4df9-b6f9-80a86764afa2.png?x-oss-process=image%2Fresize%2Cw_720#crop=0&crop=0&crop=1&crop=1&id=zq0Rr&originHeight=370&originWidth=720&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) ![](https://img.alicdn.com/imgextra/i3/O1CN011ep9No2ACzrgzgtk0_!!6000000008168-2-tps-720-370.png)
### DataSourceEngine ### DataSourceEngine
- engine engine 主要分 2 类,一类是面向 render 引擎的,可以从 engine/interpret 引入,一类是面向出码或者说直接单纯使用数据源引擎的场景,可以从 engine/runtime 引入,代码如下 - engineengine 主要分 2 类,一类是面向 render 引擎的,可以从 engine/interpret 引入,一类是面向出码或者说直接单纯使用数据源引擎的场景,可以从 engine/runtime 引入,代码如下
```javascript ```typescript
import { createInterpret, createRuntime } from '@alilc/lowcode-datasource-engine'; import { createInterpret, createRuntime } from '@alilc/lowcode-datasource-engine';
``` ```
create 方法定义如下 create 方法定义如下
```javascript ```typescript
interface IDataSourceEngineFactory { interface IDataSourceEngineFactory {
create(dataSource: DataSource, context: Omit<IRuntimeContext, 'dataSourceMap' | 'reloadDataSource'>, extraConfig?: { create(dataSource: DataSource, context: Omit<IRuntimeContext, 'dataSourceMap' | 'reloadDataSource'>, extraConfig?: {
requestHandlersMap: RequestHandlersMap; requestHandlersMap: RequestHandlersMap;
@ -29,7 +29,7 @@ interface IDataSourceEngineFactory {
create 接收三个参数,第一个是 DataSource对于运行时渲染和出码来说DataSource 的定义分别如下: create 接收三个参数,第一个是 DataSource对于运行时渲染和出码来说DataSource 的定义分别如下:
```javascript ```typescript
/** /**
* 数据源对象--运行时渲染 * 数据源对象--运行时渲染
* @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5
@ -38,6 +38,7 @@ export interface DataSource {
list: DataSourceConfig[]; list: DataSourceConfig[];
dataHandler?: JSFunction; dataHandler?: JSFunction;
} }
/** /**
* 数据源对象 * 数据源对象
* @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5
@ -63,7 +64,7 @@ export interface DataSourceConfig {
但是对于出码来说create 和 DataSource 定义如下: 但是对于出码来说create 和 DataSource 定义如下:
```javascript ```typescript
export interface IRuntimeDataSourceEngineFactory { export interface IRuntimeDataSourceEngineFactory {
create(dataSource: RuntimeDataSource, context: Omit<IRuntimeContext, 'dataSourceMap' | 'reloadDataSource'>, extraConfig?: { create(dataSource: RuntimeDataSource, context: Omit<IRuntimeContext, 'dataSourceMap' | 'reloadDataSource'>, extraConfig?: {
requestHandlersMap: RequestHandlersMap; requestHandlersMap: RequestHandlersMap;
@ -92,6 +93,7 @@ export interface RuntimeDataSourceConfig {
options?: RuntimeOptions; options?: RuntimeOptions;
[otherKey: string]: unknown; [otherKey: string]: unknown;
} }
/** /**
* 数据源对象 * 数据源对象
* @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5
@ -106,18 +108,18 @@ export interface RuntimeDataSource {
- context数据源引擎内部有一些使用了 this 的表达式,这些表达式需要求值的时候依赖上下文,因此需要将当前的上下文丢给数据源引擎,另外在 handler 里面去赋值的时候,也会用到诸如 setState 这种上下文里面的 api当然这个是可选的我们后面再说。 - context数据源引擎内部有一些使用了 this 的表达式,这些表达式需要求值的时候依赖上下文,因此需要将当前的上下文丢给数据源引擎,另外在 handler 里面去赋值的时候,也会用到诸如 setState 这种上下文里面的 api当然这个是可选的我们后面再说。
```javascript ```typescript
/** /**
* 运行时上下文--暂时是参考 react当然可以自己构建完全没问题 * 运行时上下文--暂时是参考 react当然可以自己构建完全没问题
*/ */
export interface IRuntimeContext<TState extends object = Record<string, unknown>> { export interface IRuntimeContext<TState extends object = Record<string, unknown>> {
/** 当前容器的状态 */ /** 当前容器的状态 */
readonly state: TState; readonly state: TState;
/** 设置状态(浅合并) */ /** 设置状态 (浅合并) */
setState(state: Partial<TState>): void; setState(state: Partial<TState>): void;
/** 自定义的方法 */ /** 自定义的方法 */
[customMethod: string]: any; [customMethod: string]: any;
/** 数据源, key 是数据源的 ID */ /** 数据源key 是数据源的 ID */
dataSourceMap: Record<string, IRuntimeDataSource>; dataSourceMap: Record<string, IRuntimeDataSource>;
/** 重新加载所有的数据源 */ /** 重新加载所有的数据源 */
reloadDataSource(): Promise<void>; reloadDataSource(): Promise<void>;
@ -134,7 +136,7 @@ export interface IRuntimeContext<TState extends object = Record<string, unknown>
- extraConfig这个字段是为了留着扩展用的除了一个必填的字段 **requestHandlersMap** - extraConfig这个字段是为了留着扩展用的除了一个必填的字段 **requestHandlersMap**
```javascript ```typescript
export declare type RequestHandler<T = unknown> = (ds: RuntimeDataSourceConfig, context: IRuntimeContext) => Promise<RequestResult<T>>; export declare type RequestHandler<T = unknown> = (ds: RuntimeDataSourceConfig, context: IRuntimeContext) => Promise<RequestResult<T>>;
export declare type RequestHandlersMap = Record<string, RequestHandler>; export declare type RequestHandlersMap = Record<string, RequestHandler>;
``` ```
@ -143,9 +145,9 @@ RequestHandlersMap 是一个把数据源以及对应的数据源 handler 关联
create 调用结束后,可以获取到一个 DataSourceEngine 实例 create 调用结束后,可以获取到一个 DataSourceEngine 实例
```javascript ```typescript
export interface IDataSourceEngine { export interface IDataSourceEngine {
/** 数据源, key 是数据源的 ID */ /** 数据源key 是数据源的 ID */
dataSourceMap: Record<string, IRuntimeDataSource>; dataSourceMap: Record<string, IRuntimeDataSource>;
/** 重新加载所有的数据源 */ /** 重新加载所有的数据源 */
reloadDataSource(): Promise<void>; reloadDataSource(): Promise<void>;

View File

@ -4,18 +4,22 @@ sidebar_position: 3
--- ---
本篇重点介绍如何从零开始设计编排模块,设计思路是什么?思考编排的本质是什么?围绕着本质,如何设计并实现对应的功能模块。 本篇重点介绍如何从零开始设计编排模块,设计思路是什么?思考编排的本质是什么?围绕着本质,如何设计并实现对应的功能模块。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397577227-99a77c7d-6a6e-4d92-b222-eaac0ee7988e.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u4613aa03&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=911801&status=done&style=none&taskId=u449864e5-516f-41eb-b86a-7c026b797a8&title=&width=960) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01fGzyI41bqpl6AavNp_!!6000000003517-2-tps-1920-1080.png)
## 编排是什么
所谓编排即将设计器中的所有物料进行布局设置、组件设置、交互设置JS 编写/逻辑编排)后,形成符合业务诉求的 schema 描述。
## 编排的本质
# 编排是什么
所谓编排即将设计器中的所有物料进行布局设置、组件设置、交互设置JS编写/逻辑编排)后,形成符合业务诉求的 schema 描述。
# 编排的本质
首先,思考编排的本质是什么? 首先,思考编排的本质是什么?
编排的本质是生产符合《阿里巴巴中后台前端搭建协议规范》的数据****在这个场景里,协议是通过 JSON 来承载的。如: 编排的本质是生产符合《阿里巴巴中后台前端搭建协议规范》的数据****在这个场景里,协议是通过 JSON 来承载的。如:
```json ```json
{ {
"componentName": "Page", "componentName": "Page",
"props": { "props": {
"layout": "wide", "layout": "wide"
}, },
"children": [ "children": [
{ {
@ -29,35 +33,52 @@ sidebar_position: 3
``` ```
可是在真实场景节点数可能有成百上千每个节点都具有新增、删除、修改、移动、插入子节点等操作同时还有若干约束JSON 结构操作起来不是很便利,于是我们仿 DOM 设计了 **节点模型 & 属性模型,**用更具可编程性的方式来编排,这是**编排系统的基石** 可是在真实场景节点数可能有成百上千每个节点都具有新增、删除、修改、移动、插入子节点等操作同时还有若干约束JSON 结构操作起来不是很便利,于是我们仿 DOM 设计了 **节点模型 & 属性模型,**用更具可编程性的方式来编排,这是**编排系统的基石**
其次每次编排动作后CRUD都需要实时的渲染出视图。广义的视图应该包括各种平台上的展现浏览器、Rax、小程序、Flutter 等等,所以使用何种渲染器去渲染 JSON 结构应该可以由用户去扩展,我们定义一种机制去衔接设计态和渲染态。 其次每次编排动作后CRUD都需要实时的渲染出视图。广义的视图应该包括各种平台上的展现浏览器、Rax、小程序、Flutter 等等,所以使用何种渲染器去渲染 JSON 结构应该可以由用户去扩展,我们定义一种机制去衔接设计态和渲染态。
至此,我们已经完成了**编排模块最基础的功能**,接下来,就是完善细节,逐步丰满功能。比如: 至此,我们已经完成了**编排模块最基础的功能**,接下来,就是完善细节,逐步丰满功能。比如:
1编排面板的整体功能区划分设计 1. 编排面板的整体功能区划分设计;
2节点属性设计节点删除、移动等操作设计容器节点设计 2. 节点属性设计;节点删除、移动等操作设计;容器节点设计;
3节点拖拽功能、拖拽定位设计和实现 3. 节点拖拽功能、拖拽定位设计和实现;
4节点在画布上的辅助功能比如 hover、选中、选中时的操作项、resize、拖拽占位符等 4. 节点在画布上的辅助功能,比如 hover、选中、选中时的操作项、resize、拖拽占位符等
5设计态和渲染态的坐标系转换滚动监听等 5. 设计态和渲染态的坐标系转换,滚动监听等;
6快捷键机制 6. 快捷键机制;
7历史功能撤销和重做 7. 历史功能,撤销和重做;
8结构化的插件扩展机制 8. 结构化的插件扩展机制;
9原地编辑功能 9. 原地编辑功能;
有非常多模块,但只要记住一点,这些功能的目的都是辅助用户在画布上有更好的编排体验、扩展能力而逐个增加设计的。 有非常多模块,但只要记住一点,这些功能的目的都是辅助用户在画布上有更好的编排体验、扩展能力而逐个增加设计的。
# 编排功能模块
## 模型设计 ## 编排功能模块
### 模型设计
编排实际上操作 schema但是实际代码运行的过程中我们将 schema 分成了很多层,每一层有各自的职责,他们所负责的功能是明确清晰的。这就是低代码引擎中的模型设计。 编排实际上操作 schema但是实际代码运行的过程中我们将 schema 分成了很多层,每一层有各自的职责,他们所负责的功能是明确清晰的。这就是低代码引擎中的模型设计。
我们通过将 schema 和常用的操作等结合起来,最终将低代码引擎的模型分为节点模型、属性模型、文档模型和项目模型。 我们通过将 schema 和常用的操作等结合起来,最终将低代码引擎的模型分为节点模型、属性模型、文档模型和项目模型。
### 项目模型(`Project`
#### 项目模型(`Project`
项目模型提供项目管理能力。通常一个引擎启动会默认创建一个 `Project` 实例,有且只有一个。项目模型实例下可以持有多个文档模型的实例,而当前处于设计器设计状态的文档模型,我们将其添加 active 标识,也将其称为 `currentDocument`,可以通过 `project.currentDocument` 获得。 项目模型提供项目管理能力。通常一个引擎启动会默认创建一个 `Project` 实例,有且只有一个。项目模型实例下可以持有多个文档模型的实例,而当前处于设计器设计状态的文档模型,我们将其添加 active 标识,也将其称为 `currentDocument`,可以通过 `project.currentDocument` 获得。
一个 `Project` 包含若干个 `DocumentModel` 实例,即项目模型和文档模型的关系是 1 对 n如下图所示 一个 `Project` 包含若干个 `DocumentModel` 实例,即项目模型和文档模型的关系是 1 对 n如下图所示
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244733-2492a7bf-20bf-4610-a335-99cc047037b7.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=824&id=uadf98e25&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=1226&originalType=url&ratio=1&rotation=0&showTitle=false&size=1260603&status=done&style=none&taskId=u50b01e40-96f2-4629-a1b9-1b5a22967fc&title=&width=613) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01G28BKC1RvHRvhhiDf_!!6000000002173-2-tps-1226-1648.png)
### 文档模型(`DocumentModel`
#### 文档模型(`DocumentModel`
文档模型提供文档管理的能力,每一个页面即一个文档流,对应一个文档模型。文档模型包含了一组 Node 组成的一颗树,类似于 DOM。我们可以通过文档模型来操作 `Node` 树,来达到管理文档模型的能力。每一个文档模型对应多个 `Node`,但是根 `Node` 只有一个,即 `rootNode``nodes` 文档模型提供文档管理的能力,每一个页面即一个文档流,对应一个文档模型。文档模型包含了一组 Node 组成的一颗树,类似于 DOM。我们可以通过文档模型来操作 `Node` 树,来达到管理文档模型的能力。每一个文档模型对应多个 `Node`,但是根 `Node` 只有一个,即 `rootNode``nodes`
文档模型可以通过 `Node` 树,通过 `doc.schema` 来导出文档的 `schema`,并使用其进行渲染。 文档模型可以通过 `Node` 树,通过 `doc.schema` 来导出文档的 `schema`,并使用其进行渲染。
他们的关系如下图: 他们的关系如下图:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244327-d931aff8-40d4-47df-8b1c-b81c06c40c48.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=745&id=L5LAf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1490&originWidth=960&originalType=url&ratio=1&rotation=0&showTitle=false&size=1110316&status=done&style=none&taskId=u7d873681-f61a-40ea-baaa-8f7b76c769c&title=&width=480)
### 节点模型(`Node` ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01NYVhN61nab6hsw5ZK_!!6000000005106-2-tps-960-1490.png)
#### 节点模型(`Node`
我们先看一下一个 `Node``schema` 中对应的示例: 我们先看一下一个 `Node``schema` 中对应的示例:
```json
```javascript
{ {
componentName: 'Text', componentName: 'Text',
id: 'node_k1ow3cbf', id: 'node_k1ow3cbf',
@ -76,7 +97,9 @@ sidebar_position: 3
condition: true, condition: true,
} }
``` ```
上面的示例是一个 `Text``Node` 节点,而我们的 `Node` 节点模型就是负责这一层级的 `Schema` 管理。它的功能聚焦于单层级的 schema 相关操作。我们可以看一下节点模型的一些方法,了解其功能。 上面的示例是一个 `Text``Node` 节点,而我们的 `Node` 节点模型就是负责这一层级的 `Schema` 管理。它的功能聚焦于单层级的 schema 相关操作。我们可以看一下节点模型的一些方法,了解其功能。
```typescript ```typescript
declare class Node<Schema extends NodeSchema = NodeSchema> { declare class Node<Schema extends NodeSchema = NodeSchema> {
// Props // Props
@ -111,15 +134,22 @@ declare class Node<Schema extends NodeSchema = NodeSchema> {
replaceWith(schema: Schema, migrate?: boolean): any; replaceWith(schema: Schema, migrate?: boolean): any;
} }
``` ```
这里没有展示全部的方法,但是我们可以发现,`Node` 节点模型核心功能点有三个
1`Props` 管理:通过 `Props` 实例管理所有的 `Prop`,包括新增、设置、删除等 `Prop` 相关操作。 这里没有展示全部的方法,但是我们可以发现,`Node` 节点模型核心功能点有三个:
2`Node` 管理:管理 `Node` 树的关系,修改当前 `Node` 节点或者 `Node` 子节点等。
3`Schema` 管理:可以通过 `Node` 获取当前层级的 `Schema` 描述协议内容,并且也可以修改它。 1. `Props` 管理:通过 `Props` 实例管理所有的 `Prop`,包括新增、设置、删除等 `Prop` 相关操作。
2. `Node` 管理:管理 `Node` 树的关系,修改当前 `Node` 节点或者 `Node` 子节点等。
3. `Schema` 管理:可以通过 `Node` 获取当前层级的 `Schema` 描述协议内容,并且也可以修改它。
通过 `Node` 这一层级,对 `Props``Node` 树和 `Schema` 的管理粒度控制到最低,这样扩展性也就更强。 通过 `Node` 这一层级,对 `Props``Node` 树和 `Schema` 的管理粒度控制到最低,这样扩展性也就更强。
### 属性模型Prop
#### 属性模型Prop
一个 `Props` 对应多个 `Prop`,每一个 `Prop` 对应 schema 的 `props` 下的一个字段。 一个 `Props` 对应多个 `Prop`,每一个 `Prop` 对应 schema 的 `props` 下的一个字段。
`Props` 管理的是 `Node` 节点模型中的 `props` 字段下的内容。而 `Prop` 管理的是 `props` 下的每一个 `key` 的内容,例如下面的示例中,一个 `Props` 管理至少 6 个 `Prop`,而其中一个 `Prop` 管理的是 `showTitle` 的结果。 `Props` 管理的是 `Node` 节点模型中的 `props` 字段下的内容。而 `Prop` 管理的是 `props` 下的每一个 `key` 的内容,例如下面的示例中,一个 `Props` 管理至少 6 个 `Prop`,而其中一个 `Prop` 管理的是 `showTitle` 的结果。
```typescript
```javascript
{ {
props: { props: {
showTitle: false, showTitle: false,
@ -135,17 +165,27 @@ declare class Node<Schema extends NodeSchema = NodeSchema> {
}, },
} }
``` ```
### 组件描述模型ComponentMeta #### 组件描述模型ComponentMeta
编排已经等价于直接操作节点 & 属性了而一个节点和一组对应的属性相当于一个真实的组件而真实的组件一定是有约束的比如组件名、组件类型、支持哪些属性以及属性类型、组件能否拖动、支持哪些扩展操作、组件是否是容器型组件、A 组件中能否放入 B 组件等等。 编排已经等价于直接操作节点 & 属性了而一个节点和一组对应的属性相当于一个真实的组件而真实的组件一定是有约束的比如组件名、组件类型、支持哪些属性以及属性类型、组件能否拖动、支持哪些扩展操作、组件是否是容器型组件、A 组件中能否放入 B 组件等等。
于是,我们设计了一份协议专门负责组件描述,即《中后台搭建组件描述协议》,而编排模块中也有负责解析和使用符合描述协议规范的模块。 于是,我们设计了一份协议专门负责组件描述,即《中后台搭建组件描述协议》,而编排模块中也有负责解析和使用符合描述协议规范的模块。
每一个组件对应一个 `ComponentMeta` 的实例,其属性和方法就是描述协议中的所有字段,所有 `ComponentMeta` 都由设计器器的 `designer` 模块进行创建和管理,其他模块通过 `designer` 来获取指定的 `ComponentMeta` 实例,尤其是每个 `Node` 实例上都会挂载对应的 `ComponentMeta` 实例。 每一个组件对应一个 `ComponentMeta` 的实例,其属性和方法就是描述协议中的所有字段,所有 `ComponentMeta` 都由设计器器的 `designer` 模块进行创建和管理,其他模块通过 `designer` 来获取指定的 `ComponentMeta` 实例,尤其是每个 `Node` 实例上都会挂载对应的 `ComponentMeta` 实例。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244032-8aa176d5-a74e-49c9-a309-251dba81b37c.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u044bdacd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=756&originWidth=998&originalType=url&ratio=1&rotation=0&showTitle=false&size=294191&status=done&style=none&taskId=uee9dfeef-f646-41db-afd4-a0b1acf8019&title=)
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01NSh0LI1b150RUzOUc_!!6000000003404-2-tps-998-756.png)
组件描述模型是后续编排辅助的基础,包括设置面板、拖拽定位机制等。 组件描述模型是后续编排辅助的基础,包括设置面板、拖拽定位机制等。
### 项目、文档、节点和属性模型关系 #### 项目、文档、节点和属性模型关系
整体来看,一个 Project 包含若干个 DocumentModel 实例,每个 DocumentModel 包含一组 Node 构成一颗树(类似 DOM 树),每个 Node 通过 Props 实例管理所有 Prop。整体的关系图如下。 整体来看,一个 Project 包含若干个 DocumentModel 实例,每个 DocumentModel 包含一组 Node 构成一颗树(类似 DOM 树),每个 Node 通过 Props 实例管理所有 Prop。整体的关系图如下。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645066478805-57802de7-382e-4105-99cb-161b8c07f117.png#clientId=uf22d1b91-761d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=678&id=uc2db9afa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1356&originWidth=1694&originalType=binary&ratio=1&rotation=0&showTitle=false&size=285816&status=done&style=none&taskId=u6526eafb-f082-46dd-8584-9dd9b1bb395&title=&width=847)
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01mufxpY1qCGvDTSdw9_!!6000000005459-2-tps-1694-1356.png)
节点 & 属性模型是引擎基石,几乎贯穿所有模块,相信从上面的类图已经能看出几个基础类的职责以及依赖关系。 节点 & 属性模型是引擎基石,几乎贯穿所有模块,相信从上面的类图已经能看出几个基础类的职责以及依赖关系。
节点 & 属性模型等价于 JSON 数据结构,而编排的本质是产出 JSON 数据结构,现在可以重新表述为编排的本质是操作节点 & 属性模型了。 节点 & 属性模型等价于 JSON 数据结构,而编排的本质是产出 JSON 数据结构,现在可以重新表述为编排的本质是操作节点 & 属性模型了。
```typescript ```typescript
// 一段编排的示例代码 // 一段编排的示例代码
rootNode.insertAfter({ componentName: 'Button', props: { size: 'medium' } }); rootNode.insertAfter({ componentName: 'Button', props: { size: 'medium' } });
@ -156,33 +196,51 @@ rootNode.export();
// => 产出 schema // => 产出 schema
``` ```
## 画布渲染 ### 画布渲染
画布渲染使用了设计态与渲染态的双层架构。![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244328-61bb9ce7-a27c-4917-baee-c0a93bd0fd36.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u3c9164cd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=710&originWidth=1416&originalType=url&ratio=1&rotation=0&showTitle=false&size=287707&status=done&style=none&taskId=u6c993606-238b-478f-9317-397eb0708eb&title=)
画布渲染使用了设计态与渲染态的双层架构。
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01cZ6Q32260qtiDofwi_!!6000000007600-2-tps-1416-710.png)
如上图,设计器和渲染器其实处在不同的 Frame 下,渲染器以单独的 `iframe` 嵌入。这样做的好处,一是为了给渲染器一个更纯净的运行环境,更贴近生产环境,二是扩展性考虑,让用户基于接口约束自定义自己的渲染器。 如上图,设计器和渲染器其实处在不同的 Frame 下,渲染器以单独的 `iframe` 嵌入。这样做的好处,一是为了给渲染器一个更纯净的运行环境,更贴近生产环境,二是扩展性考虑,让用户基于接口约束自定义自己的渲染器。
### xxx-renderer #### xxx-renderer
xxx-renderer 是一个纯 renderer即一个渲染器通过给定输入 schema、依赖组件和配置参数之后完成渲染。 xxx-renderer 是一个纯 renderer即一个渲染器通过给定输入 schema、依赖组件和配置参数之后完成渲染。
### xxx-simulator-renderer #### xxx-simulator-renderer
xxx-simulator-renderer 通过和 host进行通信来和设计器打交道提供了 `DocumentModel` 获取 schema 和组件。将其传入 xxx-renderer 来完成渲染。
xxx-simulator-renderer 通过和 host 进行通信来和设计器打交道,提供了 `DocumentModel` 获取 schema 和组件。将其传入 xxx-renderer 来完成渲染。
另外其提供了一些必要的接口,来帮助设计器完成交互,比如点击渲染画布任意一个位置,需要能计算出点击的组件实例,继而找到设计器对应的 Node 实例,以及组件实例的位置/尺寸信息,让设计器完成辅助 UI 的绘制,如节点选中。 另外其提供了一些必要的接口,来帮助设计器完成交互,比如点击渲染画布任意一个位置,需要能计算出点击的组件实例,继而找到设计器对应的 Node 实例,以及组件实例的位置/尺寸信息,让设计器完成辅助 UI 的绘制,如节点选中。
### react-simulator-renderer #### react-simulator-renderer
以官方提供的 react-simulator-renderer 为例,我们看一下点击一个 DOM 节点后编排模块是如何处理的。 以官方提供的 react-simulator-renderer 为例,我们看一下点击一个 DOM 节点后编排模块是如何处理的。
首先在初始化的时候renderer 渲染的时候会给每一个元素添加 ref通过 ref 机制在组件创建时将其存储起来。在存储的时候我们给实例添加 `Symbol('_LCNodeId')` 的属性。 首先在初始化的时候renderer 渲染的时候会给每一个元素添加 ref通过 ref 机制在组件创建时将其存储起来。在存储的时候我们给实例添加 `Symbol('_LCNodeId')` 的属性。
当点击之后,会去根据 `__reactInternalInstance$` 查找相应的 fiberNode通过递归查找到对应的 React 组件实例。找到一个挂载着 `Symbol('_LCNodeId')` 的实例,也就是上面我们初始化添加的属性。 当点击之后,会去根据 `__reactInternalInstance$` 查找相应的 fiberNode通过递归查找到对应的 React 组件实例。找到一个挂载着 `Symbol('_LCNodeId')` 的实例,也就是上面我们初始化添加的属性。
通过 `Symbol('_LCNodeId')` 属性,我们可以获取 Node 的 id这样我们就可以找到 Node 实例。 通过 `Symbol('_LCNodeId')` 属性,我们可以获取 Node 的 id这样我们就可以找到 Node 实例。
通过 `getBoundingClientRect` 我们可以获取到 Node 渲染出来的 DOM 的相关信息,包括 `x``y``width``height` 等。 通过 `getBoundingClientRect` 我们可以获取到 Node 渲染出来的 DOM 的相关信息,包括 `x``y``width``height` 等。
通过 DOM 信息,我们将 focus 节点所需的标志渲染到对应的地方。hover、拖拽占位符、resize handler 等辅助 UI 都是类似逻辑。 通过 DOM 信息,我们将 focus 节点所需的标志渲染到对应的地方。hover、拖拽占位符、resize handler 等辅助 UI 都是类似逻辑。
### 通信机制 #### 通信机制
既然设计器和渲染器处于两个 Frame它们之间的事件通信、方法调用是通过各自的代理对象进行的不允许其他方式避免代码耦合。 既然设计器和渲染器处于两个 Frame它们之间的事件通信、方法调用是通过各自的代理对象进行的不允许其他方式避免代码耦合。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397245794-927fa812-ea1c-4bc1-967b-4c1dff924fd1.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u22088dc8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=648&originWidth=1290&originalType=url&ratio=1&rotation=0&showTitle=false&size=223251&status=done&style=none&taskId=uf720b921-07c2-4cda-a101-74e863ce10d&title=)
**host** ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01hxtg7X1M3AZsAdt83_!!6000000001378-2-tps-1290-648.png)
host 可以访问设计器的所有模块,由于 renderer 层不负责与设计器相关的交互。所以增加了一层 host作为通信的中间层。host 可以访问到设计器中所有模块,并提供相关方法供 simulator-renderer 层调用。例如schema 的获取、组件获取等。
##### host
host 可以访问设计器的所有模块,由于 renderer 层不负责与设计器相关的交互。所以增加了一层 host作为通信的中间层。host 可以访问到设计器中所有模块,并提供相关方法供 simulator-renderer 层调用。例如 schema 的获取、组件获取等。
simulator-renderer 通过调用 host 的方法,将 schema、components 等参数传给 renderer让 renderer 进行渲染。 simulator-renderer 通过调用 host 的方法,将 schema、components 等参数传给 renderer让 renderer 进行渲染。
**xxx-simulator-renderer** ##### xxx-simulator-renderer
为了完成双向交互simulator-renderer 也需要提供一些方法来供 host 层调用,之后当设计器和用户有交互,例如上述提到的节点选中。这里需要提供的方法有: 为了完成双向交互simulator-renderer 也需要提供一些方法来供 host 层调用,之后当设计器和用户有交互,例如上述提到的节点选中。这里需要提供的方法有:
- getClientRects - getClientRects
@ -196,12 +254,16 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参
这样host 和 simulator-renderer 之间便通过相关方法实现了双向通信,能在隔离设计器的基础上完成设计器到画布和画布到设计器的通信流程。 这样host 和 simulator-renderer 之间便通过相关方法实现了双向通信,能在隔离设计器的基础上完成设计器到画布和画布到设计器的通信流程。
## 编排辅助的核心 ### 编排辅助的核心
### 设置面板与设置器 #### 设置面板与设置器
当在渲染画布上点击一个 DOM 节点,我们可以通过 xxx-simulator-renderer 获取 `Node` 节点,我们在 `Node` 上挂载了 `ComponentMeta` 实例。通过 `ComponentMeta` 我们获取到当前组件的描述模型。通过描述模型,我们即可获得组件、即当前 Node 支持的所有属性配置。 当在渲染画布上点击一个 DOM 节点,我们可以通过 xxx-simulator-renderer 获取 `Node` 节点,我们在 `Node` 上挂载了 `ComponentMeta` 实例。通过 `ComponentMeta` 我们获取到当前组件的描述模型。通过描述模型,我们即可获得组件、即当前 Node 支持的所有属性配置。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397246381-ed265cc3-b6c1-4a38-985a-df1898862fe8.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u1422ee5e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=985&originWidth=1500&originalType=url&ratio=1&rotation=0&showTitle=false&size=332497&status=done&style=none&taskId=u2bbbb9ae-7834-48ba-b87f-fa5ccf8fa39&title=)
#### 设置面板 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01c7nkoo1OXyRhVAFlK_!!6000000001716-2-tps-1500-985.png)
##### 设置面板
设置面板对于配置项的呈现结构是通过 `ComponentMeta.configure` 来确定的。 设置面板对于配置项的呈现结构是通过 `ComponentMeta.configure` 来确定的。
```json ```json
{ {
"component": { "component": {
@ -231,14 +293,22 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参
} }
} }
``` ```
上述的 `component.isContainer` 描述了这个组件是否是一个容器组件。而 props 下的属性就是我们在设置面板中展示的属性,包含了这个属性的名称、使用的设置器、配置之后影响的是哪个属性等。 上述的 `component.isContainer` 描述了这个组件是否是一个容器组件。而 props 下的属性就是我们在设置面板中展示的属性,包含了这个属性的名称、使用的设置器、配置之后影响的是哪个属性等。
而这只是描述,编排模块的 `SettingTopEntry` 便是管理设置面板的实现模块。 而这只是描述,编排模块的 `SettingTopEntry` 便是管理设置面板的实现模块。
`SettingTopEntry` 包含了 n 个 `SettingField`,每一个 `SettingField` 就对应下面要将的设置器。即 `SettingTopEntry` 负责管理多个 `SettingField` `SettingTopEntry` 包含了 n 个 `SettingField`,每一个 `SettingField` 就对应下面要将的设置器。即 `SettingTopEntry` 负责管理多个 `SettingField`
#### 设置器
##### 设置器
选中节点可供配置的属性都有相应的设置器配置比如文本、数字、颜色、JSON、Choice、I18N、表达式 等等,或者混合多种。 选中节点可供配置的属性都有相应的设置器配置比如文本、数字、颜色、JSON、Choice、I18N、表达式 等等,或者混合多种。
设置器本质上是一个 React 组件,但是设置面板在渲染时会传入当前配置项对应的 `SettingField` 实例,`SettingField` 本质上就是包裹了 `Prop` 实例,设置器内部的行为以及 UI 变化都由设置器自己把控,但当属性值发生变化时需要通过 `SettingField` 下的 `Prop` 来修改值,因为修改 `Prop` 实例就相当于修改了 schema。一方面这样的设置器设置之后保存的 schema 才是正确的,另外一方面,只有 schema 变化了,才能触发渲染画布重新渲染。 设置器本质上是一个 React 组件,但是设置面板在渲染时会传入当前配置项对应的 `SettingField` 实例,`SettingField` 本质上就是包裹了 `Prop` 实例,设置器内部的行为以及 UI 变化都由设置器自己把控,但当属性值发生变化时需要通过 `SettingField` 下的 `Prop` 来修改值,因为修改 `Prop` 实例就相当于修改了 schema。一方面这样的设置器设置之后保存的 schema 才是正确的,另外一方面,只有 schema 变化了,才能触发渲染画布重新渲染。
### 拖拽引擎 & 拖拽定位机制
![](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644397245744-af8b951c-ee22-4fcb-9175-6f1b0eb2ba37.gif#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=uf8b286a2&margin=%5Bobject%20Object%5D&originHeight=917&originWidth=1425&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u9b4475cb-bb5c-4c86-9b03-b824bc46b12&title=) #### 拖拽引擎 & 拖拽定位机制
![](https://img.alicdn.com/imgextra/i4/O1CN01G8zyBw1OkL8m0FG4J_!!6000000001743-1-tps-1425-917.gif)
拖拽引擎(`Dragon`)核心完成的工作是将被拖拽对象拖拽到目标位置,涉及到几个概念: 拖拽引擎(`Dragon`)核心完成的工作是将被拖拽对象拖拽到目标位置,涉及到几个概念:
- 被拖拽对象 - `DragObject` - 被拖拽对象 - `DragObject`
@ -246,38 +316,53 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参
- 拖拽感应区 - `ISensor` - 拖拽感应区 - `ISensor`
- 定位事件 - `LocateEvent` - 定位事件 - `LocateEvent`
#### Sensor ##### Sensor
在引擎初始化的时候,我们监听 `document` 和 iframe `contentDocument``mouse``keyboard``drag` 事件来感知拖拽的发生。而这些监听的区域我们又称为拖拽感应区,也就是 `Sensor``Sensor` 会有多个,因为感应器有多个,默认设置器和设置面板是没有 `Sensor`,但是他们是可以注册 `Sensor` 来增加感应区域,例如大纲树就注册了自己的 `Sensor` 在引擎初始化的时候,我们监听 `document` 和 iframe `contentDocument``mouse``keyboard``drag` 事件来感知拖拽的发生。而这些监听的区域我们又称为拖拽感应区,也就是 `Sensor``Sensor` 会有多个,因为感应器有多个,默认设置器和设置面板是没有 `Sensor`,但是他们是可以注册 `Sensor` 来增加感应区域,例如大纲树就注册了自己的 `Sensor`
`Sensor` 有两个关键职责: `Sensor` 有两个关键职责:
1)用于事件对象转换,比如坐标系换算 1. 用于事件对象转换,比如坐标系换算。
2根据拖拽过程中提供的位置信息,结合每一层 `Node` 也就是组件包含的描述信息,知道其是否能作为容器等限制条件,来进行进一步的定位,最后计算出精准信息来进行视图渲染。 2. 根据拖拽过程中提供的位置信息,结合每一层 `Node` 也就是组件包含的描述信息,知道其是否能作为容器等限制条件,来进行进一步的定位,最后计算出精准信息来进行视图渲染。
**拖拽流程** **拖拽流程**
在引擎初始化的时候,初始化多个 `Sensor` 1. 在引擎初始化的时候,初始化多个 `Sensor`
当拖拽开始的时候,开启 `mousemove``mouseleave``mouseover` 等事件的监听。 2. 当拖拽开始的时候,开启 `mousemove``mouseleave``mouseover` 等事件的监听。
拖拽过程中根据 `mousemove``MouseEvent` 对象封装出 `LocateEvent` 对象,继而交给相应 `sensor` 做进一步定位处理。 3. 拖拽过程中根据 `mousemove``MouseEvent` 对象封装出 `LocateEvent` 对象,继而交给相应 `sensor` 做进一步定位处理。
拖拽结束时,根据拖拽的结果进行 schema 变更和视图渲染。 4. 拖拽结束时,根据拖拽的结果进行 schema 变更和视图渲染。
最后关闭拖拽开始时的事件监听。 5. 最后关闭拖拽开始时的事件监听。
#### 拖拽方式 ##### 拖拽方式
根据拖拽的对象不同,我们将拖拽分为几种方式: 根据拖拽的对象不同,我们将拖拽分为几种方式:
1**画布内拖拽:**此时 sensor 是 simulatorHost拖拽完成之后会根据拖拽的位置来完成节点的精确插入。 1. **画布内拖拽:**此时 sensor 是 simulatorHost拖拽完成之后会根据拖拽的位置来完成节点的精确插入。
2**从组件面板拖拽到画布**:此时的 sensor 还是 simulatorHost因为拖拽结束的目标还是画布。 2. **从组件面板拖拽到画布**:此时的 sensor 还是 simulatorHost因为拖拽结束的目标还是画布。
3**大纲树面板拖拽到画布中**:此时有两个 sensor一个是大纲树当我们拖拽到画布区域时画布区域内的 simulatorHost 开始接管。 3. **大纲树面板拖拽到画布中**:此时有两个 sensor一个是大纲树当我们拖拽到画布区域时画布区域内的 simulatorHost 开始接管。
4画布拖拽到画布中从画布中开始拖拽时最新生效的是 simulatorHost当离开画布到大纲树时大纲树 sensor 开始接管生效。当拖拽到大纲树的某一个节点下时,大纲树会将大纲树中的信息转化为 schema然后渲染到画布中。 4. **画布拖拽到画布中**:从画布中开始拖拽时,最新生效的是 simulatorHost当离开画布到大纲树时大纲树 sensor 开始接管生效。当拖拽到大纲树的某一个节点下时,大纲树会将大纲树中的信息转化为 schema然后渲染到画布中。
## 其他 ### 其他
引擎的编排能力远远不止上述所描述的功能,这里只描述了其核心和关键的功能。在整个引擎的迭代和设计过程中还有很多细节来使我们的引擎更好用、更容易扩展。 引擎的编排能力远远不止上述所描述的功能,这里只描述了其核心和关键的功能。在整个引擎的迭代和设计过程中还有很多细节来使我们的引擎更好用、更容易扩展。
**schema 处理的管道机制**
通过PropsReducer 的管道机制,用户可以定制自己需要的逻辑,来修改 Schema。 #### schema 处理的管道机制
**组件 metadata 处理的管道机制**
通过 PropsReducer 的管道机制,用户可以定制自己需要的逻辑,来修改 Schema。
#### 组件 metadata 处理的管道机制
组件的描述信息都收拢在各自的 ComponentMeta 实例内,涉及到的消费方几乎遍及整个编排过程,包括但不限于 组件拖拽、拖拽辅助 UI、设置区、原地编辑、大纲树 等等。 组件的描述信息都收拢在各自的 ComponentMeta 实例内,涉及到的消费方几乎遍及整个编排过程,包括但不限于 组件拖拽、拖拽辅助 UI、设置区、原地编辑、大纲树 等等。
在用户需要自定义的场景,开放 ComponentMeta 的修改能力至关重要,因此我们设计了 metadata 初始化/修改的管道机制。 在用户需要自定义的场景,开放 ComponentMeta 的修改能力至关重要,因此我们设计了 metadata 初始化/修改的管道机制。
**hotkey & builtin-hotkey**
#### hotkey & builtin-hotkey
快捷键的实现,以及引擎内核默认绑定的快捷键行为。 快捷键的实现,以及引擎内核默认绑定的快捷键行为。
**drag resize 引擎**
#### drag resize 引擎
对于布局等类型的组件支持拖拽改变大小。resize 拖拽引擎根据组件 ComponentMeta 声明来开启,拖拽后,触发组件的钩子函数(`onResizeStart` / `onResize` / `onResizeEnd`),完成 resize 过程。 对于布局等类型的组件支持拖拽改变大小。resize 拖拽引擎根据组件 ComponentMeta 声明来开启,拖拽后,触发组件的钩子函数(`onResizeStart` / `onResize` / `onResizeEnd`),完成 resize 过程。
**OffsetObserver**
#### OffsetObserver
设计态的辅助 UI 需要根据渲染态的视图变化而变化,比如渲染容器滚动了,此时通过 OffsetObserver 做一个动态的监听。 设计态的辅助 UI 需要根据渲染态的视图变化而变化,比如渲染容器滚动了,此时通过 OffsetObserver 做一个动态的监听。
**插件机制**
#### 插件机制
我们希望保持引擎内核足够小,但拥有足够强的扩展能力,所有扩展功能都通过插件机制来承载。 我们希望保持引擎内核足够小,但拥有足够强的扩展能力,所有扩展功能都通过插件机制来承载。

View File

@ -2,18 +2,20 @@
title: 出码模块设计 title: 出码模块设计
sidebar_position: 5 sidebar_position: 5
--- ---
本篇主要讲解了出码模块实现的基本思路与一些概念。如需接入出码和定制出码方案,可以参考《[使用出码功能](https://www.yuque.com/lce/doc/cplfv0)》一节。
# npm 包与仓库信息 本篇主要讲解了出码模块实现的基本思路与一些概念。如需接入出码和定制出码方案,可以参考《[使用出码功能](/site/docs/guide/expand/runtime/codeGeneration)》一节。
## npm 包与仓库信息
| **NPM 包** | **代码仓库** | **说明** | | **NPM 包** | **代码仓库** | **说明** |
| --- | --- | --- | | --- | --- | --- |
| [@alilc/lowcode-code-generator](https://www.npmjs.com/package/@alilc/lowcode-code-generator) | [alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | [@alilc/lowcode-code-generator](https://www.npmjs.com/package/@alilc/lowcode-code-generator) | [alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine)子目录modules/code-generator| 出码模块核心库,支持在 node 环境下运行,也提供了浏览器下运行的 standalone 模式 |
(子目录modules/code-generator) | 出码模块核心库,支持在 node 环境下运行,也提供了浏览器下运行的 standalone 模式 |
| [@alilc/lowcode-plugin-code-generator](https://www.npmjs.com/package/@alilc/lowcode-plugin-code-generator) | [alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo) | 出码示例 -- 浏览器端出码插件 | | [@alilc/lowcode-plugin-code-generator](https://www.npmjs.com/package/@alilc/lowcode-plugin-code-generator) | [alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo) | 出码示例 -- 浏览器端出码插件 |
# 出码模块原理 ## 出码模块原理
出码模块的输入和输出很简单: 出码模块的输入和输出很简单:
![](https://cdn.nlark.com/yuque/0/2022/jpeg/263300/1644825891969-1777dbe4-5ffc-4c94-a022-3aba0c116021.jpeg) ![](https://img.alicdn.com/imgextra/i3/O1CN01OkDmKq1xMX6Xxv6co_!!6000000006429-0-tps-1262-346.jpg)
这里有几个概念: 这里有几个概念:
@ -23,19 +25,23 @@ sidebar_position: 5
可以看出,这是一个与用户基本没有交互,通过既定的流程完成整个功能链路的模块。其核心暴露的是一个将搭建协议 schema 按既定的 solution 转换为代码的函数。对于使用者来说就是一个输入输出都确定的黑盒系统。 可以看出,这是一个与用户基本没有交互,通过既定的流程完成整个功能链路的模块。其核心暴露的是一个将搭建协议 schema 按既定的 solution 转换为代码的函数。对于使用者来说就是一个输入输出都确定的黑盒系统。
## 出码流程概述 ### 出码流程概述
出码模块和编译器很类似,都是将代码的一种表现形式转换成另一种表现形式,如: 出码模块和编译器很类似,都是将代码的一种表现形式转换成另一种表现形式,如:
**编译器流程** #### 编译器流程
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644403720547-e5021c3c-0c63-47ea-b8f0-1af79bbae3ef.png#clientId=u70bc6751-fff0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=246&id=u3b3e3126&margin=%5Bobject%20Object%5D&name=image.png&originHeight=492&originWidth=3228&originalType=binary&ratio=1&rotation=0&showTitle=false&size=110319&status=done&style=none&taskId=u32f55257-a18c-4caa-9334-0b3ca5b0bc0&title=&width=1614) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN019F21Lb1bsCwvNcWRq_!!6000000003520-2-tps-3228-492.png)
**出码模块流程** #### 出码模块流程
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644402753768-02d402da-dd1a-4783-9021-606e276d4c68.png#clientId=u70bc6751-fff0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=182&id=GlAz4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=182&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23743&status=done&style=none&taskId=ubbea9289-cb03-4fcf-9ce7-22da1ce077b&title=&width=1536) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01SEcVta1uLD72W0URZ_!!6000000006020-2-tps-1536-182.png)
### 出码流程详解
#### 协议解析
## 出码流程详解
### 协议解析
协议解析主要是将输入的 schema 解析成更适合出码模块内部使用的数据结构的过程。这样在后面的代码生成过程中就可以直接用这些数据,不必重复解析了。 协议解析主要是将输入的 schema 解析成更适合出码模块内部使用的数据结构的过程。这样在后面的代码生成过程中就可以直接用这些数据,不必重复解析了。
![](https://intranetproxy.alipay.com/skylark/lark/0/2021/jpeg/154771/1636960093808-624b5e50-18d6-476d-a951-556912832cdb.jpeg)
![](https://img.alicdn.com/imgextra/i3/O1CN016EeitG1giCNCNTLVF_!!6000000004175-0-tps-1282-515.jpg)
主要步骤如下: 主要步骤如下:
- 解析三方组件依赖 - 解析三方组件依赖
@ -46,21 +52,30 @@ sidebar_position: 5
- 分析 utils 和 NPM 包依赖关系 - 分析 utils 和 NPM 包依赖关系
- 其他兼容处理 - 其他兼容处理
### 前置优化 #### 前置优化
前置优化是计划基于策略对 schema 做一些优化。
主要逻辑分为分析、规则和优化三个部分,组合为一个支持通过配置进行一定程度定制化的策略包。每个策略包会先执行分析器,对输入进行特征提取,然后通过规则对特征进行判断,决定是否执行优化动作:
![](https://intranetproxy.alipay.com/skylark/lark/0/2021/jpeg/154771/1636960832211-0db6925b-c4b5-4be4-a883-fdd52a47e19a.jpeg)
### 代码生成 前置优化是计划基于策略对 schema 做一些优化。
主要逻辑分为分析、规则和优化三个部分,组合为一个支持通过配置进行一定程度定制化的策略包。每个策略包会先执行分析器,对输入进行特征提取,然后通过规则对特征进行判断,决定是否执行优化动作:
![](https://img.alicdn.com/imgextra/i4/O1CN01P0Lw7v1lfyWtfQTuR_!!6000000004847-2-tps-994-278.png)
#### 代码生成
代码生成的流程如下: 代码生成的流程如下:
![](https://intranetproxy.alipay.com/skylark/lark/0/2021/jpeg/154771/1636975834791-e3fe89f9-cd2d-446f-aa9f-fca0bb1d56c3.jpeg) ![](https://img.alicdn.com/imgextra/i1/O1CN01lhcWBg1RG3nsoSoY2_!!6000000002083-2-tps-1468-464.png)
如果简单粗暴地拼字符串生成源代码将难以扩展和维护,因此出码模块在代码生成过程中将代码进行了一些抽象化。 如果简单粗暴地拼字符串生成源代码将难以扩展和维护,因此出码模块在代码生成过程中将代码进行了一些抽象化。
日常开发中我们常常是基于某一个特定的项目框架将一些配置、UI 代码、逻辑代码放到他们应该在的地方,最终形成一套可以 run 起来的业务系统。那么其实对于出码这件事,我们也可以层层拆解,**项目 -> 插槽 -> 模块 -> 文件 -> 代码块**(代码片段)。这样就能将复杂的项目产出问题,拆分为一个个相对专注且单一的代码块产出问题,同时也支持组合复用。 日常开发中我们常常是基于某一个特定的项目框架将一些配置、UI 代码、逻辑代码放到他们应该在的地方,最终形成一套可以 run 起来的业务系统。那么其实对于出码这件事,我们也可以层层拆解,**项目 -> 插槽 -> 模块 -> 文件 -> 代码块**(代码片段)。这样就能将复杂的项目产出问题,拆分为一个个相对专注且单一的代码块产出问题,同时也支持组合复用。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644402753919-1f063db3-5ad9-406b-9b45-6eeef79ea38b.png#clientId=u70bc6751-fff0-4&crop=0&crop=0&crop=1&crop=1&height=305&id=LgGUo&margin=%5Bobject%20Object%5D&name=image.png&originHeight=454&originWidth=892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=230321&status=done&style=none&taskId=u50d38d84-3a3e-4c77-af05-8bc5f794643&title=&width=600)
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01vOGmBT1JaegccXDt8_!!6000000001045-2-tps-892-454.png)
注:中间表达结构即为对 Schema 解析后的结构化产物 注:中间表达结构即为对 Schema 解析后的结构化产物
**插槽** ##### 插槽
首先来看下插槽,插槽描述了对应模块在项目中相对路径,并且可以对模块做固定的命名。每个插槽都有一系列插件来完成代码产出工作。生成的一个或多个文件,最终会依照插槽的描述放入项目中。 首先来看下插槽,插槽描述了对应模块在项目中相对路径,并且可以对模块做固定的命名。每个插槽都有一系列插件来完成代码产出工作。生成的一个或多个文件,最终会依照插槽的描述放入项目中。
```typescript ```typescript
// 项目模版 // 项目模版
export interface IProjectTemplate { export interface IProjectTemplate {
@ -78,20 +93,23 @@ interface IProjectPlugins {
[slotName: string]: BuilderComponentPlugin[]; [slotName: string]: BuilderComponentPlugin[];
} }
``` ```
**代码块** ##### 代码块
代码块是出码产物的最小单元,由出码模块插件产出,多个代码块最后会被组装为代码文件。每个代码块通过 name 描述自己,再通过 linkAfter 描述应该跟在哪些 name 的代码块后面。 代码块是出码产物的最小单元,由出码模块插件产出,多个代码块最后会被组装为代码文件。每个代码块通过 name 描述自己,再通过 linkAfter 描述应该跟在哪些 name 的代码块后面。
```typescript ```typescript
interface ICodeChunk { interface ICodeChunk {
type: ChunkType; // 处理类型 ast | string | json type: ChunkType; // 处理类型 ast | string | json
fileType: string; // 文件类型 js | css | ts ... fileType: string; // 文件类型 js | css | ts ...
name: string; // 代码块名称,与 linkAfter 相关 name: string; // 代码块名称,与 linkAfter 相关
subModule?: string; // 模块内文件名,默认是 index subModule?: string; // 模块内文件名,默认是 index
content: ChunkContent; // 代码块内容,数据格式与 type 相关 content: ChunkContent; // 代码块内容,数据格式与 type 相关
linkAfter: string[]; // linkAfter: string[];
} }
``` ```
### 后置优化 #### 后置优化
后置优化分为文件级别和项目级别两种: 后置优化分为文件级别和项目级别两种:
- 文件级别:在生成完一个文件后进行处理 - 文件级别:在生成完一个文件后进行处理

View File

@ -3,7 +3,7 @@ title: 入料模块设计
sidebar_position: 2 sidebar_position: 2
--- ---
## 介绍 ## 介绍
入料模块负责物料接入,通过自动扫描、解析源码组件,产出一份符合《中后台低代码组件描述协议》的** **JSON Schema。这份 Schema 包含基础信息和属性描述信息部分低代码引擎会基于它们在运行时自动生成一份configure 配置,用作设置面板展示。 入料模块负责物料接入,通过自动扫描、解析源码组件,产出一份符合《中后台低代码组件描述协议》的** **JSON Schema。这份 Schema 包含基础信息和属性描述信息部分,低代码引擎会基于它们在运行时自动生成一份 configure 配置,用作设置面板展示。
## npm 包与仓库信息 ## npm 包与仓库信息
@ -15,7 +15,7 @@ sidebar_position: 2
### 整体流程 ### 整体流程
大体分为本地化、扫描、解析、转换、校验 5 部分,如下图所示。 大体分为本地化、扫描、解析、转换、校验 5 部分,如下图所示。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777217-58246e52-b5b9-4509-8bac-db2820535c39.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u8b5a70fd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=206&originWidth=2116&originalType=url&ratio=1&rotation=0&showTitle=false&size=51634&status=done&style=none&taskId=u76c5b45a-6fa8-404e-8d8b-f1d6f38438e&title=) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01sXf5fL1E5RcRxAlM1_!!6000000000300-2-tps-2116-206.png)
### 静态解析 ### 静态解析
在静态分析时,分为 JS 和 TS 两种情况。 在静态分析时,分为 JS 和 TS 两种情况。
@ -23,48 +23,58 @@ sidebar_position: 2
#### 静态解析 JS #### 静态解析 JS
在 JS 情况下,基于 react-docgen 进行扩展,自定义了 resolver 及 handler前者用于寻找组件定义后者用于解析 propTypes、defaultProps 等信息,整体流程图如下: 在 JS 情况下,基于 react-docgen 进行扩展,自定义了 resolver 及 handler前者用于寻找组件定义后者用于解析 propTypes、defaultProps 等信息,整体流程图如下:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777192-c9d3c3b3-c7d2-4780-b7dc-632349b00edb.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u3edfb33c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=478&originWidth=2176&originalType=url&ratio=1&rotation=0&showTitle=false&size=93513&status=done&style=none&taskId=ua23bd89a-3d0c-43cf-936b-13080cdc5ef&title=) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01VrhkEb1R6tsntvGhV_!!6000000002063-2-tps-2176-478.png)
react-docgen 使用 babel 生成语法树,再使用 ast-types 进行遍历去寻找组件节点及其属性类型定义。原本的 react-docgen 只能解析单文件,且不能解析 IIFE、逗号表达式等语法结构(一般出现在转码后的代码中)。笔者对其进行改造,使之可以递归解析多文件去查找组件定义,且能够解开 IIFE以及对逗号表达式进行转换以方便后续的组件解析。另外还增加了子组件解析的功能即类似 `Button.Group = Group` 这种定义。 react-docgen 使用 babel 生成语法树,再使用 ast-types 进行遍历去寻找组件节点及其属性类型定义。原本的 react-docgen 只能解析单文件,且不能解析 IIFE、逗号表达式等语法结构 (一般出现在转码后的代码中)。笔者对其进行改造,使之可以递归解析多文件去查找组件定义,且能够解开 IIFE以及对逗号表达式进行转换以方便后续的组件解析。另外还增加了子组件解析的功能即类似 `Button.Group = Group` 这种定义。
#### 静态解析 TS #### 静态解析 TS
在 TS 情况下,还要再细分为 TS 源码和 TS 编译后的代码。 在 TS 情况下,还要再细分为 TS 源码和 TS 编译后的代码。
TS 源码中React 组件具有类型签名TS 编译后的代码中dts 文件(如有)包含全部的 class / interface / type 类型信息。可以从这些类型信息中获取组件属性描述。整体流程图如下: TS 源码中React 组件具有类型签名TS 编译后的代码中dts 文件 (如有) 包含全部的 class / interface / type 类型信息。可以从这些类型信息中获取组件属性描述。整体流程图如下:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777193-14c74287-d0cb-4864-ba64-9259a88c8b99.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ud7fc6e1a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=240&originWidth=2280&originalType=url&ratio=1&rotation=0&showTitle=false&size=59331&status=done&style=none&taskId=u711959ae-241a-48c9-a446-59b9fcdc52e&title=) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN014lOIIy1FUvGW6wcYZ_!!6000000000491-2-tps-2280-240.png)
react-docgen 内置了 TypeScript 的 babel 插件,所以也具备解析 interface 的能力可惜能力有限babel 只能解析 TS 代码,但没法做类型检查,类型处理是由 react-docgen 实现的它对于extends/implements/utility 的情况处理不好,并且没有类型推断,虽然可以对其功能进行完善,不过这种情况下,应该借助 TypeScript Compiler 的能力,而非自己造轮子。通过调研,发现市面上有 typescript-react-docgen 这个项目。它在底层依赖了 TypeScript且产出的数据格式与 react-docgen 一致,所以我们选择基于它进行解析。 react-docgen 内置了 TypeScript 的 babel 插件,所以也具备解析 interface 的能力可惜能力有限babel 只能解析 TS 代码,但没法做类型检查,类型处理是由 react-docgen 实现的,它对于 extends/implements/utility 的情况处理不好,并且没有类型推断,虽然可以对其功能进行完善,不过这种情况下,应该借助 TypeScript Compiler 的能力,而非自己造轮子。通过调研,发现市面上有 typescript-react-docgen 这个项目。它在底层依赖了 TypeScript且产出的数据格式与 react-docgen 一致,所以我们选择基于它进行解析。
TypeScript Compiler 会递归解析某个文件中出现及引用的全部类型当然前提是已经定义或安装了相应的类型声明。typescript-react-docgen 会调用 TypeScript Compiler 的 API获取每个文件输出的类型判断其是否为 React 组件。满足下列条件之一的,会被判定为 React 组件: TypeScript Compiler 会递归解析某个文件中出现及引用的全部类型当然前提是已经定义或安装了相应的类型声明。typescript-react-docgen 会调用 TypeScript Compiler 的 API获取每个文件输出的类型判断其是否为 React 组件。满足下列条件之一的,会被判定为 React 组件:
1. 获取其函数签名,如果只有一个入参,或者第一个入参名称为 props ,会被判定为函数式组件; 1. 获取其函数签名,如果只有一个入参,或者第一个入参名称为 props会被判定为函数式组件
2. 获取其 `constructor` 方法,如果其返回值包含 props 属性,会被判定为有状态组件。 2. 获取其 `constructor` 方法,如果其返回值包含 props 属性,会被判定为有状态组件。
然后,遍历组件的 props 类型,获取每个属性的类型签名字符串,比如 `(a: string) => void`。typescript-react-docgen 可以克服 react-docgen 解析 TypeScirpt 类型的问题,但是每个类型都以字符串的形式来呈现,不利于后续的解析。所以,笔者对其进行了扩展,递归解析每一层的属性值。此外,在函数式组件的判定上,笔者做了完善,会看函数的返回值是否为 `ReactElement` ,若是,才为函数式组件。 然后,遍历组件的 props 类型,获取每个属性的类型签名字符串,比如 `(a: string) => void`。typescript-react-docgen 可以克服 react-docgen 解析 TypeScirpt 类型的问题,但是每个类型都以字符串的形式来呈现,不利于后续的解析。所以,笔者对其进行了扩展,递归解析每一层的属性值。此外,在函数式组件的判定上,笔者做了完善,会看函数的返回值是否为 `ReactElement` ,若是,才为函数式组件。
下面讲对于一些特殊情况的处理。 下面讲对于一些特殊情况的处理。
**循环定义** **循环定义**
TypeScript 类型可以循环定义,比如下面的 JSON 类型: TypeScript 类型可以循环定义,比如下面的 JSON 类型:
```typescript ```typescript
interface Json { interface Json {
[x: string]: string | number | boolean | Json | JsonArray; [x: string]: string | number | boolean | Json | JsonArray;
} }
type JsonArray = Array<string | number | boolean | Json | JsonArray>; type JsonArray = Array<string | number | boolean | Json | JsonArray>;
``` ```
因为低代码组件描述协议中没有引用功能,而且也不方便在界面上展示出来,所以这种循环定义无需完全解析,入料模块会在检测到循环定义的时候,把类型简化为 `object` 。对于特殊的类型,如 JSON可以用相应的 Setter 来编辑。 因为低代码组件描述协议中没有引用功能,而且也不方便在界面上展示出来,所以这种循环定义无需完全解析,入料模块会在检测到循环定义的时候,把类型简化为 `object` 。对于特殊的类型,如 JSON可以用相应的 Setter 来编辑。
**复杂类型** **复杂类型**
TypeScript Compiler 会将合成类型的所有属性展开,比如 `boolean | string`,会被展开为 `true | false | string`,这带来了不必要的精确,我们需要的只是 `boolean | string` 而已。当然,对于这个例子,我们很容易把它还原回 `boolean | string`,然而,对于诸如 `React.ButtonHTMLAttributes<any> & {'data-name': string}` 这种类型,它会把 `ButtonHTMLAttributes` 中众多的属性和 `data-name` 混杂在一起,完全无法分辨,只能以展开的形式提供。这 100 多个属性,如果都放在设置面板,绝对是使用者的噩梦,所以,其结果会被简化为 `object` 。当然,即使没有 `{'data-name': string}``ButtonHTMLAttributes` 也是没有单独的 Setter 的,同样会被简化为 `object` TypeScript Compiler 会将合成类型的所有属性展开,比如 `boolean | string`,会被展开为 `true | false | string`,这带来了不必要的精确,我们需要的只是 `boolean | string` 而已。当然,对于这个例子,我们很容易把它还原回 `boolean | string`,然而,对于诸如 `React.ButtonHTMLAttributes<any> & {'data-name': string}` 这种类型,它会把 `ButtonHTMLAttributes` 中众多的属性和 `data-name` 混杂在一起,完全无法分辨,只能以展开的形式提供。这 100 多个属性,如果都放在设置面板,绝对是使用者的噩梦,所以,其结果会被简化为 `object` 。当然,即使没有 `{'data-name': string}``ButtonHTMLAttributes` 也是没有单独的 Setter 的,同样会被简化为 `object`
### 动态解析 ### 动态解析
当一个组件,使用静态解析无法入料时,会使用动态解析。 当一个组件,使用静态解析无法入料时,会使用动态解析。
整体流程图如下: 整体流程图如下:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396776984-d390ec0c-33c6-4468-b68c-555a263b097e.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ube12dcbd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=449&originWidth=2516&originalType=url&ratio=1&rotation=0&showTitle=false&size=84334&status=done&style=none&taskId=ube349a5b-94c0-4a77-9bf3-ffe453226e1&title=)
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01dJ62Dm1u5de8GihG6_!!6000000005986-2-tps-2516-449.png)
基本思想很简单require 组件进来,然后读取其组件类上定义的 propTypes 和 defaultProps 属性。这里使用了 parse-prop-types 库,使用它的时候必须在组件之前引用,因为它会先对 prop-types 库进行修改,在每个 PropTypes 透出的函数上挂上类型,比如 string, number 等等,然后再去遍历。动态解析可以解析出全部的类型信息,因为 PropTypes 有可能引入依赖组件的一些类型定义,这在静态解析中很难做到,或者成本较高,而对于动态解析来说,都由运行时完成了。 基本思想很简单require 组件进来,然后读取其组件类上定义的 propTypes 和 defaultProps 属性。这里使用了 parse-prop-types 库,使用它的时候必须在组件之前引用,因为它会先对 prop-types 库进行修改,在每个 PropTypes 透出的函数上挂上类型,比如 string, number 等等,然后再去遍历。动态解析可以解析出全部的类型信息,因为 PropTypes 有可能引入依赖组件的一些类型定义,这在静态解析中很难做到,或者成本较高,而对于动态解析来说,都由运行时完成了。
##### 技术细节 ##### 技术细节
值得注意的是,有些 js 文件里还会引入 css 文件,而且从笔者了解的情况来看,这种情况在集团内部不在少数。这种组件不配合 webpack 使用,肯定会报错,但是使用 webpack 会明显拖慢速度所以笔者采用了sandbox 的方式,对 require 进来的类 css 文件进行 mock。这里笔者使用了 vm2 这个库,它对 node 自带的 vm 进行了封装,可以劫持文件中的 require 方法。因为 parse-prop-types 的修改在沙箱中会失效,所以笔者也 mock 了组件中的 prop-types 库。
值得注意的是,有些 js 文件里还会引入 css 文件,而且从笔者了解的情况来看,这种情况在集团内部不在少数。这种组件不配合 webpack 使用,肯定会报错,但是使用 webpack 会明显拖慢速度,所以笔者采用了 sandbox 的方式,对 require 进来的类 css 文件进行 mock。这里笔者使用了 vm2 这个库,它对 node 自带的 vm 进行了封装,可以劫持文件中的 require 方法。因为 parse-prop-types 的修改在沙箱中会失效,所以笔者也 mock 了组件中的 prop-types 库。
### 整体大图 ### 整体大图
把上述的静态解析和动态解析流程结合起来,可以得到以下大图。 把上述的静态解析和动态解析流程结合起来,可以得到以下大图。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777248-9e26dd26-51ac-473e-ae66-c08f8bed3aeb.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ue6806530&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1072&originWidth=2658&originalType=url&ratio=1&rotation=0&showTitle=false&size=184784&status=done&style=none&taskId=u0d982b36-25b8-442f-8d98-43b9e1629bb&title=)
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01TA9lQp27QmwVT7WUC_!!6000000007792-2-tps-2658-1072.png)

View File

@ -2,12 +2,13 @@
title: 渲染模块设计 title: 渲染模块设计
sidebar_position: 4 sidebar_position: 4
--- ---
# 低代码渲染介绍 ## 低代码渲染介绍
<img src="https://img.alicdn.com/imgextra/i1/O1CN01TXW6Ku1iQSGIPzncW_!!6000000004407-2-tps-1440-872.png" width="400"/>
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398134750-7b352564-a400-460e-a189-e72ef551624f.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=198&id=OSLhL&margin=%5Bobject%20Object%5D&name=image.png&originHeight=872&originWidth=1440&originalType=binary&ratio=1&rotation=0&showTitle=false&size=193396&status=done&style=none&taskId=ua5d2ae84-0117-4744-a49c-bd3dd1b8a5e&title=&width=327)
基于 Schema 和物料组件,如何渲染出我们的页面?这一节描述的就是这个。 基于 Schema 和物料组件,如何渲染出我们的页面?这一节描述的就是这个。
# npm 包与仓库信息 ## npm 包与仓库信息
- React 框架渲染 npm 包:@alilc/lowcode-react-renderer - React 框架渲染 npm 包:@alilc/lowcode-react-renderer
- Rax 框架渲染 npm 包:@alilc/lowcode-rax-renderer - Rax 框架渲染 npm 包:@alilc/lowcode-rax-renderer
@ -16,22 +17,25 @@ sidebar_position: 4
- packages/react-renderer - packages/react-renderer
- packages/react-simulator-renderer - packages/react-simulator-renderer
# 渲染框架原理 ## 渲染框架原理
## 整体架构 ### 整体架构
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398135242-d83a9d48-c244-4869-b61e-70e825006727.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=531&id=udb49df4c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1062&originWidth=1686&originalType=binary&ratio=1&rotation=0&showTitle=false&size=821823&status=done&style=none&taskId=u90381546-a7a8-4099-b24f-844b8489f4d&title=&width=843)
- 协议层:基于标准的《阿里巴巴中后台前端搭建协议规范》产出的 Schema 作为我们的规范协议。 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01i4IiSR1cMtUFXaWQq_!!6000000003587-2-tps-1686-1062.png)
- 协议层:基于《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec) 产出的 Schema 作为我们的规范协议。
- 能力层:提供组件、区块、页面等渲染所需的核心能力,包括 Props 解析、样式注入、条件渲染等。 - 能力层:提供组件、区块、页面等渲染所需的核心能力,包括 Props 解析、样式注入、条件渲染等。
- 适配层:由于我们使用的运行时框架不是统一的,所以统一使用适配层将不同运行框架的差异部分,通过接口对外,让渲染层注册/适配对应所需的方法。能保障渲染层和能力层直接通过适配层连接起来,能起到独立可扩展的作用。 - 适配层:由于我们使用的运行时框架不是统一的,所以统一使用适配层将不同运行框架的差异部分,通过接口对外,让渲染层注册/适配对应所需的方法。能保障渲染层和能力层直接通过适配层连接起来,能起到独立可扩展的作用。
- 渲染层:提供核心的渲染方法,由于不同运行时框架提供的渲染方法是不同的,所以其通过适配层进行注入,只需要提供适配层所需的接口,即可实现渲染。 - 渲染层:提供核心的渲染方法,由于不同运行时框架提供的渲染方法是不同的,所以其通过适配层进行注入,只需要提供适配层所需的接口,即可实现渲染。
- 应用层:根据渲染层所提供的方法,可以应用到项目中,根据使用的方法和规模即可实现应用、页面、区块的渲染。 - 应用层:根据渲染层所提供的方法,可以应用到项目中,根据使用的方法和规模即可实现应用、页面、区块的渲染。
## 核心解析 ### 核心解析
这里主要解析一下刚刚提到的架构中的适配层和渲染层。 这里主要解析一下刚刚提到的架构中的适配层和渲染层。
### 适配层
#### 适配层
适配层提供的是各个框架之间的差异项。比如 `React.createElement``Rax.createElement` 方法是不同的。所以需要在适配层对 API 进行抹平。 适配层提供的是各个框架之间的差异项。比如 `React.createElement``Rax.createElement` 方法是不同的。所以需要在适配层对 API 进行抹平。
#### React ##### React
```typescript ```typescript
import { createElement } from 'react'; import { createElement } from 'react';
import { import {
@ -42,7 +46,7 @@ adapter.setRuntime({
createElement, createElement,
}); });
``` ```
#### Rax ##### Rax
```typescript ```typescript
import { createElement } from 'rax'; import { createElement } from 'rax';
import { import {
@ -69,10 +73,12 @@ adapter.setRuntime({
- `ComponentRenderer`:组件渲染的方法。 - `ComponentRenderer`:组件渲染的方法。
- `BlockRenderer`:区块渲染的方法。 - `BlockRenderer`:区块渲染的方法。
### 渲染层 #### 渲染层
#### React Renderer ##### React Renderer
内部的技术栈统一都是 React大多数适配层的 API 都是按照 React 来设计的,所以对于 React Renderer 来说,需要做的不多。 内部的技术栈统一都是 React大多数适配层的 API 都是按照 React 来设计的,所以对于 React Renderer 来说,需要做的不多。
React Renderer 的代码量很少,主要是将 React API 注册到适配层中。 React Renderer 的代码量很少,主要是将 React API 注册到适配层中。
```typescript ```typescript
import React, { Component, PureComponent, createElement, createContext, forwardRef, ReactInstance, ContextType } from 'react'; import React, { Component, PureComponent, createElement, createContext, forwardRef, ReactInstance, ContextType } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
@ -112,7 +118,7 @@ adapter.setRenderers({
adapter.setConfigProvider(ConfigProvider); adapter.setConfigProvider(ConfigProvider);
``` ```
#### Rax Renderer ##### Rax Renderer
Rax 的大多数 API 和 React 基本也是一致的,差异点在于重写了一些方法。 Rax 的大多数 API 和 React 基本也是一致的,差异点在于重写了一些方法。
```typescript ```typescript
import { Component, PureComponent, createElement, createContext, forwardRef } from 'rax'; import { Component, PureComponent, createElement, createContext, forwardRef } from 'rax';
@ -146,8 +152,8 @@ adapter.setRenderers({
}); });
``` ```
## 多模式渲染 ### 多模式渲染
### 预览模式渲染 #### 预览模式渲染
预览模式的渲染,主要是通过 Schema、components 即可完成上述的页面渲染能力。 预览模式的渲染,主要是通过 Schema、components 即可完成上述的页面渲染能力。
```typescript ```typescript
import ReactRenderer from '@ali/lowcode-react-renderer'; import ReactRenderer from '@ali/lowcode-react-renderer';
@ -183,11 +189,11 @@ ReactDOM.render((
), document.getElementById('root')); ), document.getElementById('root'));
``` ```
### 设计模式渲染Simulator #### 设计模式渲染Simulator
设计模式渲染就是将编排生成的《搭建协议》渲染成视图的过程,视图是可以交互的,所以必须要处理好内部数据流、生命周期、事件绑定、国际化等等。也称为画布的渲染,画布是 UI 编排的核心,它一般融合了页面的渲染以及组件/区块的拖拽、选择、快捷配置。 设计模式渲染就是将编排生成的《搭建协议》渲染成视图的过程,视图是可以交互的,所以必须要处理好内部数据流、生命周期、事件绑定、国际化等等。也称为画布的渲染,画布是 UI 编排的核心,它一般融合了页面的渲染以及组件/区块的拖拽、选择、快捷配置。
画布的渲染和预览模式的渲染的区别在于,画布的渲染和设计器之间是有交互的。所以在这里我们新增了一层 `Simulator` 作为设计器和渲染的连接器。 画布的渲染和预览模式的渲染的区别在于,画布的渲染和设计器之间是有交互的。所以在这里我们新增了一层 `Simulator` 作为设计器和渲染的连接器。
`Simulator` 是将设计器传入的 `DocumentModel` 和组件/库描述转成相应的 Schema 和 组件类。再调用 Render 层完成渲染。我们这里介绍一下它提供的能力。 `Simulator` 是将设计器传入的 `DocumentModel` 和组件/库描述转成相应的 Schema 和 组件类。再调用 Render 层完成渲染。我们这里介绍一下它提供的能力。
#### 整体架构 ##### 整体架构
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398136330-0f48202b-b581-4b1f-af79-72a667a194d9.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=432&id=u734b5c16&margin=%5Bobject%20Object%5D&name=image.png&originHeight=864&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=572012&status=done&style=none&taskId=u7d7cf569-d5a9-4bea-9b2d-1121b85728f&title=&width=750) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398136330-0f48202b-b581-4b1f-af79-72a667a194d9.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=432&id=u734b5c16&margin=%5Bobject%20Object%5D&name=image.png&originHeight=864&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=572012&status=done&style=none&taskId=u7d7cf569-d5a9-4bea-9b2d-1121b85728f&title=&width=750)
- `Project`:位于顶层的 Project保留了对所有文档模型的引用用于管理应用级 Schema 的导入与导出。 - `Project`:位于顶层的 Project保留了对所有文档模型的引用用于管理应用级 Schema 的导入与导出。
@ -200,11 +206,11 @@ ReactDOM.render((
- `SettingField`:它连接属性设置器 `Setter` 与属性模型 `Prop`,它是实现多节点属性批处理的关键。 - `SettingField`:它连接属性设置器 `Setter` 与属性模型 `Prop`,它是实现多节点属性批处理的关键。
- 通用交互模型:内置了拖拽、活跃追踪、悬停探测、剪贴板、滚动、快捷键绑定。 - 通用交互模型:内置了拖拽、活跃追踪、悬停探测、剪贴板、滚动、快捷键绑定。
#### 模拟器介绍 ##### 模拟器介绍
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398137096-260646a0-f264-48af-9600-6f7141a6a1d8.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=370&id=ubfb08f11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=740&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=353179&status=done&style=none&taskId=u3cd764bb-52f6-47a6-8026-fee6a36d08d&title=&width=750) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398137096-260646a0-f264-48af-9600-6f7141a6a1d8.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=370&id=ubfb08f11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=740&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=353179&status=done&style=none&taskId=u3cd764bb-52f6-47a6-8026-fee6a36d08d&title=&width=750)
- 运行时环境:从运行时环境来看,目前我们有 React 生态、Rax 生态。而在对外的历程中,我们也会拥有 Vue 生态、Angular 生态等。 - 运行时环境:从运行时环境来看,目前我们有 React 生态、Rax 生态。而在对外的历程中,我们也会拥有 Vue 生态、Angular 生态等。
- 布局模式:不同于 C 端营销页的搭建,中后台场景大多是表单、表格,流式布局是主流的选择。对于设计师、产品来说,是需要绝对布局的方式来进行页面研发的。 - 布局模式:不同于 C 端营销页的搭建,中后台场景大多是表单、表格,流式布局是主流的选择。对于设计师、产品来说,是需要绝对布局的方式来进行页面研发的。
- 研发场景:从研发场景来看,低代码搭建不仅有页面编排,还有诸如逻辑编排、业务编排的场景。 - 研发场景:从研发场景来看,低代码搭建不仅有页面编排,还有诸如逻辑编排、业务编排的场景。
基于以上思考,我们通过基于沙箱隔离的模拟器技术来实现了多运行时环境(如 React、Rax、小程序、Vue、多模式如流式布局、自由布局、多场景如页面编排、关系图编排的 UI 编排。通过注册不同的运行时环境的渲染模块,能够实现编辑器从 React 页面搭建到 Rax 页面搭建的迁移。通过注册不同的模拟器画布,你可以基于 G6或者 mxgraph 来做关系图编排。你可以定制一个流式布局的画布,也可以定制一个自由布局的画布。 基于以上思考,我们通过基于沙箱隔离的模拟器技术来实现了多运行时环境(如 React、Rax、小程序、Vue、多模式如流式布局、自由布局、多场景如页面编排、关系图编排的 UI 编排。通过注册不同的运行时环境的渲染模块,能够实现编辑器从 React 页面搭建到 Rax 页面搭建的迁移。通过注册不同的模拟器画布,你可以基于 G6 或者 mxgraph 来做关系图编排。你可以定制一个流式布局的画布,也可以定制一个自由布局的画布。

View File

@ -2,22 +2,27 @@
title: 设置器设计 title: 设置器设计
sidebar_position: 6 sidebar_position: 6
--- ---
设置器,又称为 Setter是作为物料属性和用户交互的重要途径在编辑器日常使用中有着非常重要的作用本文重点介绍 Setter 的设计原理和使用方式,帮助用户更好的理解 Setter。 设置器,又称为 Setter是作为物料属性和用户交互的重要途径在编辑器日常使用中有着非常重要的作用本文重点介绍 Setter 的设计原理和使用方式,帮助用户更好的理解 Setter。
在编辑器的右边区域Setter 的区块就展现在这里,如下图: 在编辑器的右边区域Setter 的区块就展现在这里,如下图:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644404887956-8ffc8c8c-380c-4843-8bc9-512be77a9b18.png#clientId=u4cc5b992-0df5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=865&id=wNOuZ&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1730&originWidth=3836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=947162&status=done&style=none&taskId=ue623b488-8774-401a-b80c-c102e8aac8f&title=&width=1918)
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01qEjjoQ24QNkD42wzl_!!6000000007385-2-tps-3836-1730.png)
其中包含 属性、样式、事件、高级: 其中包含 属性、样式、事件、高级:
- 属性:展示该物料常规的属性; - 属性:展示该物料常规的属性;
- 样式:展示该物料样式的属性; - 样式:展示该物料样式的属性;
- 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件; - 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件;
- 高级:两个逻辑相关的属性,**条件渲染**和**循环。** - 高级:两个逻辑相关的属性,**条件渲染**和**循环。**
# npm 包与仓库信息 ## npm 包与仓库信息
- npm 包:@alilc/lowcode-engine-ext - npm 包:@alilc/lowcode-engine-ext
- 仓库:[https://github.com/alibaba/lowcode-engine-ext](https://github.com/alibaba/lowcode-engine-ext) - 仓库:[https://github.com/alibaba/lowcode-engine-ext](https://github.com/alibaba/lowcode-engine-ext)
# 设置器模块原理 ## 设置器模块原理
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644404909143-eede0a27-e990-4333-816a-d2d0cf2594b3.png#clientId=u4cc5b992-0df5-4&crop=0&crop=0&crop=1&crop=1&height=482&id=PyO6v&name=image.png&originHeight=964&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=273494&status=done&style=none&taskId=ufb317b56-de50-4693-8c39-8faa9b38307&title=&width=767)
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01EAmitQ1U5TUws63AV_!!6000000002466-2-tps-1534-964.png)
设置面板依赖于以下三块抽象 设置面板依赖于以下三块抽象
@ -25,7 +30,8 @@ sidebar_position: 6
- 设置对象 `settingTarget`,主要包含:选中的节点、是否同一值、值的储存等 - 设置对象 `settingTarget`,主要包含:选中的节点、是否同一值、值的储存等
- 设置列 `settingField`,主要和当前设置视图相关,包含视图的 `ref`、以及设置对象 `settingTarget` - 设置列 `settingField`,主要和当前设置视图相关,包含视图的 `ref`、以及设置对象 `settingTarget`
#### SettingTarget 抽象 ### SettingTarget 抽象
如果不是多选,可以直接暴露 `Node` 给到这,但涉及多选编辑的时候,大家的值时通常是不一样的,设置的时候需要批量设置进去,这里主要封装这些逻辑,把多选编辑的复杂性屏蔽掉。 如果不是多选,可以直接暴露 `Node` 给到这,但涉及多选编辑的时候,大家的值时通常是不一样的,设置的时候需要批量设置进去,这里主要封装这些逻辑,把多选编辑的复杂性屏蔽掉。
所选节点所构成的**设置对象**抽象如下: 所选节点所构成的**设置对象**抽象如下:
@ -49,7 +55,7 @@ interface SettingTarget {
} }
``` ```
基于设置对象所派生的**设置目标属性**抽象如下: 基于设置对象所派生的**设置目标属性**抽象如下
```typescript ```typescript
interface SettingTargetProp extends SettingTarget { interface SettingTargetProp extends SettingTarget {
@ -68,8 +74,8 @@ interface SettingTargetProp extends SettingTarget {
} }
``` ```
#### SettingField 抽象 ### SettingField 抽象
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396933393-779423e2-29a7-4e97-9ef9-e3c7964a5412.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=201&id=uc71z&margin=%5Bobject%20Object%5D&name=image.png&originHeight=402&originWidth=2022&originalType=binary&ratio=1&rotation=0&showTitle=false&size=218611&status=done&style=none&taskId=u534089f2-363d-464e-8c69-ac79f268f5a&title=&width=1011) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01D855j01j8sg9GdtJr_!!6000000004504-2-tps-2022-402.png)
```typescript ```typescript
interface SettingField extends SettingTarget { interface SettingField extends SettingTarget {

View File

@ -1,31 +1,51 @@
--- ---
title: 低代码引擎协议栈简介 title: 协议栈简介
sidebar_position: 1 sidebar_position: 1
--- ---
# 什么是低代码协议 ## 什么是低代码协议
这是两份中后台低代码领域的标准协议,即《低代码引擎物料协议规范》和《低代码引擎搭建协议规范》。它们保障了低代码领域的标准化,成为了生态建设和流通的基石。 低代码引擎体系基于三份协议来构建,分别是 [《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)、[《低代码引擎物料协议规范》](/site/docs/specs/material-spec)和[《低代码引擎资产包协议规范》](/site/docs/specs/assets-spec), 它们保障了低代码领域的标准化,成为了生态建设和流通的基石。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1648642508161-64dd3a2c-d2d2-43ed-92e4-ead40ab62498.png#clientId=ub4563dfd-c5b1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=532&id=u60966832&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1064&originWidth=1928&originalType=binary&ratio=1&rotation=0&showTitle=false&size=974317&status=done&style=none&taskId=u88a8512e-a57c-43f6-a01f-19f6878b7a0&title=&width=964)
# 为什么需要协议
首先,我们做一个不恰当的类比,我们将低代码引擎和 JavaScript 语言做一下类别。还记得之前,大家都被浏览器兼容性支配的恐惧,特别是 IE 和其他浏览器,对上层 API 实现的不一致,导致一份代码需要运行在两端需要做适配。当浏览器 / JavaScript 相关的标准出现之后,各个浏览器进行了 API 的统一使得我们终于可以从这部分工作中解放出来PSBabel 对于语言特性的转换是另一个方面的问题)。
而在《低代码引擎搭建协议规范》出现之前,低代码领域也有类似的问题。
## 概念不通
在交流的过程中,一些对于搭建产品的术语的不一致,导致了一些沟通成本,不管是在文章分享、技术分享、交流会上,都会有这个问题。
## 物料孤岛
由于低代码产品实现的方式不同,物料的消费方式也各不相同。这里分为两种物料,低代码物料和 ProCode 物料。
对于低代码物料来说A 平台创建的物料无法使用到 B 平台上,如果想在 B 平台实现同样的物料,需要按照 B 平台的标准搭建一份物料。
对于 ProCode 物料来说,需要在低代码平台进行消费,是需要进行转换的,包括搭建配置项的生成、物料搭建试图等,可能还需要特殊的描述文件进行描述。由于这一层没有统一,同一份 ProCode 物料每接入一个低代码,可能需要的描述文件格式不同,转换的代码不同,使用的工具也不同。
## 生态隔离
不同低代码平台的生态体系也不相同,有的低代码平台的物料生态不错,有的低代码平台的搭建体验生态不错。但是这些利好的生态,都是无法互通的,甚至就算知道了代码,也无法复用,因为底层是不一致的。对于集团来说,每一个平台都创建一份自己的生态,这并不是利好的。
## 技术深度不够
大家可能觉得,以上问题对于自己造轮子来说,其实也是有利的,因为自己得到了技术上的成长。
但是对于低代码的平台方,实际上更多的工作,在物料的转化、物料的生成、搭建体验的小优化、部分其他平台生态的实现。这些的技术深度其实并不高。
## 价值不高
如果每个业务都要从 0 开始做,做自己的平台,会花费大量的时间来构建底层基础设施,对业务本身而言并不是一件好事;而且前端领域的底层基础设施都大同小异,不同团队重复构建造成了极大的资源浪费。
这样的建设,会导致从 0 到 1 都需要花费大量的时间,往往在内部人力不足、投入有限时,产品很容易在未发展壮大的时候就面临了死亡相关的决策。
设想一下,如果可以开发一份全集团低代码平台都可以使用的物料,是否更有成就感呢?如果可以基于已有生态进行低代码平台的快速落地,而不是花费 1-2 年搭建一个可用的低代码平台,再验证市场。在快速的验证之后,再进行更深入的打磨,这其中的思考和技术含量是否更优于之前的模式呢?
比如不同平台的低代码物料
1. vc-deep — vc 协议 + Deep 组件库(企业智能基于 Fusion Next 定制) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01axsOyW1s01YgXnT8z_!!6000000005703-2-tps-1888-1000.png)
## 为什么需要协议
首先,我们做一个不恰当的类比,我们将低代码引擎和 JavaScript 语言做一下类别。还记得之前,大家都被浏览器兼容性支配的恐惧,特别是 IE 和其他浏览器,对上层 API 实现的不一致,导致一份代码需要运行在两端需要做适配。当浏览器 / JavaScript 相关的标准出现之后,各个浏览器进行了 API 的统一使得我们终于可以从这部分工作中解放出来PSBabel 对于语言特性的转换是另一个方面的问题)。
而在《低代码引擎搭建协议规范》出现之前,低代码领域也有类似的问题。
### 概念不通
在交流的过程中,一些对于搭建产品的术语的不一致,导致了一些沟通成本,不管是在文章分享、技术分享、交流会上,都会有这个问题。
### 物料孤岛
由于低代码产品实现的方式不同,物料的消费方式也各不相同。这里分为两种物料,低代码物料和 ProCode 物料。
对于低代码物料来说A 平台创建的物料无法使用到 B 平台上,如果想在 B 平台实现同样的物料,需要按照 B 平台的标准搭建一份物料。
对于 ProCode 物料来说,需要在低代码平台进行消费,是需要进行转换的,包括搭建配置项的生成、物料搭建试图等,可能还需要特殊的描述文件进行描述。由于这一层没有统一,同一份 ProCode 物料每接入一个低代码,可能需要的描述文件格式不同,转换的代码不同,使用的工具也不同。
### 生态隔离
不同低代码平台的生态体系也不相同,有的低代码平台的物料生态不错,有的低代码平台的搭建体验生态不错。但是这些利好的生态,都是无法互通的,甚至就算知道了代码也无法复用,因为底层是不一致的。对于阿里巴巴集团来说,每一个平台都创建一份自己的生态,这并不是利好的。
### 低水平重复建设
大家可能觉得,以上问题对于自己造轮子来说,其实也是有利的,因为自己得到了技术上的成长。
但是对于低代码的平台方,实际上更多的工作,在物料的转化、物料的生成、搭建体验的小优化、部分其他平台生态的实现。这些的技术深度其实并不高,属于低水平重复建设部分。
### 价值不高
如果每个业务都要从 0 开始做,做自己的平台,会花费大量的时间来构建底层基础设施,对业务本身而言并不是一件好事;而且前端领域的底层基础设施都大同小异,不同团队重复构建造成了极大的资源浪费。
这样的建设,会导致从 0 到 1 都需要花费大量的时间,往往在内部人力不足、投入有限时,产品很容易在未发展壮大的时候就面临了死亡相关的决策。
设想一下,如果可以开发一份全集团低代码平台都可以使用的物料,是否更有成就感呢?如果可以基于已有生态进行低代码平台的快速落地,而不是花费 1-2 年搭建一个可用的低代码平台,再验证市场。在快速的验证之后,再进行更深入的打磨,这其中的思考和技术含量是否更优于之前的模式呢?
以 2019 年的阿里巴巴的情况举例,不同平台的低代码物料但不限于:
1. vc-deep — vc 协议 + Deep 组件库 (阿里巴巴企业智能团队基于 Fusion Next 定制)
2. Iceluna 协议 + Fusion Next 2. Iceluna 协议 + Fusion Next
3. AIMake 物料; 3. AIMake 物料;
4. vc-fusion-basic + 业务改造 — vc 协议 + Fusion Next(各业务 Fork 定制) 4. vc-fusion-basic + 业务改造 — vc 协议 + Fusion Next(各业务 Fork 定制)
@ -33,28 +53,37 @@ sidebar_position: 1
6. vc 协议 + antd 6. vc 协议 + antd
可以看到,各个搭建平台都需要维护一套自己的基础组件库,这是非常不合理的,对基础组件库的维护会分散开发同学完成业务目标的精力。 可以看到,各个搭建平台都需要维护一套自己的基础组件库,这是非常不合理的,对基础组件库的维护会分散开发同学完成业务目标的精力。
建立统一的低代码领域标准化是百利而无一害的。于是在阿里巴巴集团2020财年进行了讨论建立了搭建治理&物料流通战役,此战役便产出了《低代码引擎物料协议规范》、《低代码引擎搭建协议规范》两份规范,成为了低代码引擎和其生态的基础。
# 协议的作用
基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,集团各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升阿里巴巴中后台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。
## 打破物料孤岛 建立统一的低代码领域标准化,是百利而无一害的。于是,在阿里巴巴集团 2020 年进行了讨论,建立了搭建治理&物料流通战役,此战役便产出了上文中的协议规范,成为了低代码引擎和其生态的基础。
### 物料中心
在《低代码引擎物料协议规范》成立了之后,规范先行建立了阿里巴巴各个中后台研发平台沟通、对话的基础,物料流通的先决条件已经成熟,这个时候我们还需要一个统一的物料源,用于管理物料的上传、存储、检索、分发,一个典型的中心化架构,类似 npm 的管理,这便是我们物料中心。 ## 协议的作用
基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。
### 打破物料孤岛
#### 物料中心
这里以阿里集团的前端物料中间建设为例,在《低代码引擎物料协议规范》落地之后,建立了阿里巴巴各个中后台研发平台沟通、对话的基础,物料流通的先决条件已经成熟,这个时候我们还需要一个统一的物料源,用于管理物料的上传、存储、检索、分发,一个典型的中心化架构,类似 npm 的管理,这便是我们物料中心。
Fusion Market 是物料中心的前身,它提供了业务组件的存储、文档展示和全局透出的功能,由于 fusion 体系在集团内的广泛使用Fusion Market 沉淀了不少的业务组件,但是这个项目却一直不温不火,只看到业务组件数量的增加,却未看到物料流通起来。其中一个原因是,没有阿里巴巴前端委员会的背书,规范很难统一,规范如果不统一,物料就很难流通; Fusion Market 是物料中心的前身,它提供了业务组件的存储、文档展示和全局透出的功能,由于 fusion 体系在集团内的广泛使用Fusion Market 沉淀了不少的业务组件,但是这个项目却一直不温不火,只看到业务组件数量的增加,却未看到物料流通起来。其中一个原因是,没有阿里巴巴前端委员会的背书,规范很难统一,规范如果不统一,物料就很难流通;
在规范成立之后,物料中心也将有了建设的基础,最终于 2019 年建立了物料中心,提供了物料流通的平台能力。 在规范成立之后,物料中心也将有了建设的基础,最终于 2019 年建立了物料中心,提供了物料流通的平台能力。
### 低代码基础物料
#### 低代码基础物料
就像 AntD、Element 之于源码研发模式在低代码研发模式下各个搭建平台也需要一套统一的、开箱即用的低代码基础组件库。基于低代码描述协议完成了两份低代码基础物料的建设即“Fusion 低代码基础组件库”和“AntD 低代码基础组件库”。 就像 AntD、Element 之于源码研发模式在低代码研发模式下各个搭建平台也需要一套统一的、开箱即用的低代码基础组件库。基于低代码描述协议完成了两份低代码基础物料的建设即“Fusion 低代码基础组件库”和“AntD 低代码基础组件库”。
### 源码组件低代码化
#### 源码组件低代码化
将源码组件一键转化为低代码物料,符合低代码物料规范,可以在低代码平台进行流通。 将源码组件一键转化为低代码物料,符合低代码物料规范,可以在低代码平台进行流通。
### 低代码物料中心 ### 低代码物料中心
当低代码物料积累到一定的量级之后,所有的搭建平台的业务物料越来越多。这些物料通过低代码物料中心进行统一的管理和消费。 当低代码物料积累到一定的量级之后,所有的搭建平台的业务物料越来越多。这些物料通过低代码物料中心进行统一的管理和消费。
## Setter 生态的基础 ### 设置器生态的基础
Snippet(组件默认搭建 schema ) 由《低代码引擎搭建协议规范》定义低代码引擎会按照规范对组件进行渲染Configure 由《低代码引擎物料协议规范》定义,它描述了组件的 props 以及每个 prop 对应的设置器 (Prop 配置面板),低代码引擎提供了 20+ 个内置设置器,但如果我们组件的 props 超出了引擎内置设置器的范围,就需要我们自己来开发对应设置器。
设置器最终也慢慢形成了自己的生态,这使得开发物料更加容易,可以使用已有的生态中的设置器,进行物料配置描述。
### 低代码引擎实现标准
Snippet(组件默认搭建 schema )由《低代码引擎搭建协议规范》定义低代码引擎会按照规范对组件进行渲染Configure 由《低代码引擎物料协议规范》定义,它描述了组件的 props 以及每个 prop 对应的 setter (Prop 配置面板),低代码引擎提供了 14 个内置 Setter但如果我们组件的 props 超出了引擎内置 setter 的范围,就需要我们自己来开发对应 Setter。
setter 最终也慢慢形成了自己的生态,这使得开发物料更加容易,可以使用已有的 setter 生态,进行物料配置描述。
## 低代码引擎实现标准
低代码引擎是以上生态的消费端,它是实现了标准协议的低代码引擎。这是不可或缺的部分,低代码引擎这里就相当于一个标准浏览器,一方面给其他的低代码平台提供了一个 Demo其他平台可以参考低代码引擎进行实现满足官方协议便也可以消费相关的物料生态和其他生态。 低代码引擎是以上生态的消费端,它是实现了标准协议的低代码引擎。这是不可或缺的部分,低代码引擎这里就相当于一个标准浏览器,一方面给其他的低代码平台提供了一个 Demo其他平台可以参考低代码引擎进行实现满足官方协议便也可以消费相关的物料生态和其他生态。
通过物料中心实现集团各业务域物料跨系统流通是第一步,通过低代码引擎快速搭建出来的各业务域低代码平台平滑高效地使用各业务域物料,提升集团中后台研发系统的效率是关键的第二步。
其中入料模块,使得任意符合物料协议的物料都可以被消费,也就打破了物料孤岛,实现物料之间的流通。

View File

@ -1,46 +1,55 @@
--- ---
title: 低代码引擎架构综述 title: 架构综述
sidebar_position: 0 sidebar_position: 0
--- ---
## 分层架构描述 ## 分层架构描述
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644392855407-44040c3e-f98e-4e93-a7ba-7efc0a7927fb.png#clientId=ue3f00c22-d0cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u0d1fdc91&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=177518&status=done&style=none&taskId=u0ac7d0a3-e838-4982-ad41-e830af33545&title=&width=960) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN016l8gDo1z7zlRlW1P0_!!6000000006668-2-tps-1920-1080.png)
我们设计了这样一套分层架构,自下而上分别是协议 - 引擎 - 生态 - 平台。 我们设计了这样一套分层架构,自下而上分别是协议 - 引擎 - 生态 - 平台。
底层协议栈定义的是标准,**标准的统一让上层产物的互通成为可能**
**引擎是对协议的实现,同时通过能力的输出,向上支撑生态开放体系,提供各种生态扩展能力,** - 底层协议栈定义的是标准,**标准的统一让上层产物的互通成为可能**。
那么生态就好理解了,是基于引擎核心能力上扩展出来的,比如物料、设置器、插件等,还有工具链支撑开发体系, - 引擎是**对协议的实现**,同时通过能力的输出,向上**支撑生态开放体系**,提供各种生态扩展能力。
最后,各个平台基于引擎内核以及生态中的产品组合、衔接形成满足其需求的低代码平台。 - 生态就好理解了,是基于引擎核心能力上扩展出来的,比如物料、设置器、插件等,还有工具链支撑开发体系。
- 最后,各个平台基于引擎内核以及生态中的产品组合、衔接形成满足其需求的低代码平台。
**每一层都明确自身的定位,各司其职,协议不会去思考引擎如何实现,引擎也不会实现具体上层平台功能,上层平台的定制化均通过插件来实现,这些理念将会贯穿我们体系设计、实现的过程。** **每一层都明确自身的定位,各司其职,协议不会去思考引擎如何实现,引擎也不会实现具体上层平台功能,上层平台的定制化均通过插件来实现,这些理念将会贯穿我们体系设计、实现的过程。**
## 引擎内核简述 ## 引擎内核简述
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644393521380-2b5dda70-cd35-4cc2-aeae-6d0ba98deccd.png#clientId=ue3f00c22-d0cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u6b0dd5f3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=330340&status=done&style=none&taskId=u39127ebd-dbac-4636-9cb5-5c4833146a1&title=&width=960) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01QUUVu21LjTXqY6H8I_!!6000000001335-2-tps-1920-1080.png)
低代码引擎分为 4 大模块,入料 - 编排 - 渲染 - 出码 低代码引擎分为 4 大模块,入料 - 编排 - 渲染 - 出码
入料模块就是将外部的物料,比如海量的 npm 组件,按照《物料描述协议》进行描述。
**注意这里仅是增加描述而非重写一套这样我们能最大程度复用ProCode体系已沉淀的组件。** - 入料模块就是将外部的物料,比如海量的 npm 组件,按照《物料描述协议》进行描述。将描述后的数据通过引擎 API 注册后,在编辑器中使用。
将描述后的数据通过引擎 API 注册后,在编辑器中使用。 > **注意,这里仅是增加描述,而非重写一套,这样我们能最大程度复用 ProCode 体系已沉淀的组件。**
编排,本质上来讲,就是**不断在生成符合《搭建协议》的页面描述,将编辑器中的所有物料,进行布局设置、组件 CRUD 操作、以及 JS/CSS编写/逻辑编排**等,最终转换成页面描述,技术细节待会儿我们再展开讲讲 - 编排,本质上来讲,就是**不断在生成符合[低代码引擎搭建协议规范](/site/docs/specs/lowcode-spec)的页面描述,将编辑器中的所有物料,进行布局设置、组件 CRUD 操作、以及 JS / CSS 编写/ 逻辑编排 **等,最终转换成页面描述,技术细节后文会展开
渲染,顾名思义,就是**将编排生成的页面描述结构渲染成视图的过程**,视图是面向用户的,所以必须处理好内部数据流、生命周期、事件绑定、国际化等。 - 渲染,顾名思义,就是**将编排生成的页面描述结构渲染成视图的过程**,视图是面向用户的,所以必须处理好内部数据流、生命周期、事件绑定、国际化等。
出码,就是**将页面描述结构解析和转换成应用代码的机制**。 - 出码,就是**将编排过程产生的符合[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)的页面描述转换成另一种 DSL 或 编程语言代码的过程**。
## 引擎生态简述 ## 引擎生态简述
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644393489755-b9a6a471-c099-480b-b40b-3094b793394d.png#clientId=ue3f00c22-d0cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u81ccc9e2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=504671&status=done&style=none&taskId=u52008ac0-e9c6-407b-a59e-7dbf4c02c0c&title=&width=960) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01LkRseZ23W31l8DPzS_!!6000000007262-2-tps-1920-1080.png)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397483218-2b58bfca-94b1-474e-8983-afc757f20e59.png#clientId=uafdaa655-f89e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u3aeacdac&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=394834&status=done&style=none&taskId=udcd28484-1df2-484c-9f98-87175972d65&title=&width=960) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01PYBVfZ1hL82XPrXzX_!!6000000004260-2-tps-1920-1080.png)
引擎生态主要分为 3 部分,物料、设置器和插件。 引擎生态主要分为 3 部分,物料、设置器和插件。
### 物料生态 ### 物料生态
物料是低代码平台的生产资料,没有物料低代码平台则变成了无源之水无本之木。低代码平台的物料即低代码组件。因此低代码物料生态指的是: 物料是低代码平台的生产资料,没有物料低代码平台则变成了无源之水无本之木。低代码平台的物料即低代码组件。因此低代码物料生态指的是:
1低代码物料生产能力和规范。 1. 低代码物料生产能力和规范。
2对低代码物料进行统一管理的物料中心。 2. 对低代码物料进行统一管理的物料中心。
3基于 Fusion Next 的低代码基础组件库。 3. 基于 Fusion Next 的低代码基础组件库。
### 设置器生态 ### 设置器生态
对于已接入物料的属性配置,需要不同的设置器。 对于已接入物料的属性配置,需要不同的设置器。
比如配置数值类型的 age需要一个数值设置器配置对象类型的 hobby需要一个对象设置器依次类推。 比如配置数值类型的 age需要一个数值设置器配置对象类型的 hobby需要一个对象设置器依次类推。
每个设置器本质上都是一个 React 组件,接受由引擎传入的参数,比如 value 和 onChangevalue 是初始传入的值onChange 是在设置器的值变化时的回传函数,将值写回到引擎中。 每个设置器本质上都是一个 React 组件,接受由引擎传入的参数,比如 value 和 onChangevalue 是初始传入的值onChange 是在设置器的值变化时的回传函数,将值写回到引擎中。
```json
```typescript
// 一个最简单的文本设置器示例 // 一个最简单的文本设置器示例
class TextSetter extends Component { class TextSetter extends Component {
render() { render() {
@ -49,9 +58,12 @@ class TextSetter extends Component {
} }
} }
``` ```
大多数组件所使用的设置器都是一致或相似的。如同建设低代码基础组件库一样,设置器生态是一组基础的设置器,供大多数组件配置场景使用。 大多数组件所使用的设置器都是一致或相似的。如同建设低代码基础组件库一样,设置器生态是一组基础的设置器,供大多数组件配置场景使用。
同时提供了设置器的定制功能。 同时提供了设置器的定制功能。
### 插件生态 ### 插件生态
低代码引擎本身只包含了最小的内核,而我们所能看到的设计器上的按钮、面板等都是插件提供的。插件是组成设计器的必要部分。 低代码引擎本身只包含了最小的内核,而我们所能看到的设计器上的按钮、面板等都是插件提供的。插件是组成设计器的必要部分。
因此我们提供了一套官方的插件生态,提供最基础的设计器功能。帮助用户通过使用插件,快速完成自己的设计器。 因此我们提供了一套官方的插件生态,提供最基础的设计器功能。帮助用户通过使用插件,快速完成自己的设计器。

View File

@ -1,5 +1,5 @@
{ {
"label": "扩展低代码应用", "label": "扩展低代码编辑器",
"position": 2, "position": 2,
"collapsed": false, "collapsed": false,
"collapsible": true "collapsible": true

View File

@ -7,15 +7,19 @@ sidebar_position: 7
在 fork 低代码编辑器 demo 项目后,您可以直接在项目中任意扩展低代码编辑器。如果您想要将自己的组件/插件/设置器封装成一个独立的 npm 包并提供给社区,您可以使用我们的低代码脚手架建立低代码扩展。 在 fork 低代码编辑器 demo 项目后,您可以直接在项目中任意扩展低代码编辑器。如果您想要将自己的组件/插件/设置器封装成一个独立的 npm 包并提供给社区,您可以使用我们的低代码脚手架建立低代码扩展。
> Windows 开发者请在 WSL 环境下使用开发工具 > Windows 开发者请在 WSL 环境下使用开发工具
>
> WSL 中文 doc[https://docs.microsoft.com/zh-cn/windows/wsl/install](https://docs.microsoft.com/zh-cn/windows/wsl/install) > WSL 中文 doc[https://docs.microsoft.com/zh-cn/windows/wsl/install](https://docs.microsoft.com/zh-cn/windows/wsl/install)
中文教程:[https://blog.csdn.net/weixin_45027467/article/details/106862520](https://blog.csdn.net/weixin_45027467/article/details/106862520) >
> 中文教程:[https://blog.csdn.net/weixin_45027467/article/details/106862520](https://blog.csdn.net/weixin_45027467/article/details/106862520)
## 脚手架功能 ## 脚手架功能
### 脚手架初始化 ### 脚手架初始化
```shell ```shell
$ npm init @alilc/element your-element-name $ npm init @alilc/element your-element-name
``` ```
不写 your-element-name 的情况下,则在当前目录创建。 不写 your-element-name 的情况下,则在当前目录创建。
> 觉得安装速度比较慢的同学,可以设置 npm 国内镜像,如 > 觉得安装速度比较慢的同学,可以设置 npm 国内镜像,如
@ -25,157 +29,166 @@ $ npm init @alilc/element your-element-name --registry=https://registry.npmmirro
``` ```
选择对应的元素类型,并填写对应的问题,即可完成创建。 选择对应的元素类型,并填写对应的问题,即可完成创建。
![截屏2022-02-09 下午8.15.07.png](https://cdn.nlark.com/yuque/0/2022/png/134449/1644408912640-ae7a9a9b-54a4-49c3-a5d8-ccac1db7da0b.png#averageHue=%23f0f0ef&clientId=ue2be1de5-5d30-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=drop&height=82&id=uaff32f98&margin=%5Bobject%20Object%5D&name=%E6%88%AA%E5%B1%8F2022-02-09%20%E4%B8%8B%E5%8D%888.15.07.png&originHeight=148&originWidth=688&originalType=binary&ratio=1&rotation=0&showTitle=false&size=72918&status=error&style=none&taskId=uf08c7e98-b502-416d-be39-0029f765203&title=&width=382)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01SNaXUg1g4LurKuBHs_!!6000000004088-2-tps-688-148.png)
### 脚手架本地环境调试 ### 脚手架本地环境调试
```shell
```bash
cd your-element-name cd your-element-name
npm install npm install
npm start npm start
``` ```
### 脚手架构建 ### 脚手架构建
```shell
```bash
$ npm run build $ npm run build
``` ```
### 脚手架发布 ### 脚手架发布
修改版本号后,执行如下指令即可: 修改版本号后,执行如下指令即可:
```shell
```bash
$ npm publish $ npm publish
``` ```
# 🔥🔥🔥 调试物料/插件/设置器 # 🔥🔥🔥 调试物料/插件/设置器
> 📢📢 📢 低代码生态脚手架提供的调试利器,在启动 setter/插件/物料 项目后,直接在已有的低代码平台就可以调试,不需要 npm link / 手改 npm main 入口等传统方式,轻松上手,强烈推荐使用!! > 📢📢📢 低代码生态脚手架提供的调试利器,在启动 setter/插件/物料 项目后,直接在已有的低代码平台就可以调试,不需要 npm link / 手改 npm main 入口等传统方式,轻松上手,强烈推荐使用!!
注:若控制台出现如下错误,直接访问一次该 url 即可~ 注:若控制台出现如下错误,直接访问一次该 url 即可~
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652408638502-0509191d-1cd6-435c-9196-5c7abac7cc4d.png#averageHue=%23c8e1be&clientId=u0b1196f0-7f06-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=113&id=tjF5F&margin=%5Bobject%20Object%5D&name=image.png&originHeight=226&originWidth=1418&originalType=binary&ratio=1&rotation=0&showTitle=false&size=180782&status=error&style=none&taskId=u57eb2bdc-6dfd-4332-b176-c453947be2d&title=&width=709)
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01cvKmeK1saCqpIxbLW_!!6000000005782-2-tps-1418-226.png)
## 组件/插件/Setter 侧 ## 组件/插件/Setter 侧
1. 插件/setter 在原有 alt 的配置中添加相关的调试配置 1. 插件/setter 在原有 alt 的配置中添加相关的调试配置
```json ```json
// build.json 中 // build.json 中
{ {
"plugins": [ "plugins": [
[ [
"@alilc/build-plugin-alt", "@alilc/build-plugin-alt",
{ {
"type": "plugin", "type": "plugin",
"inject": true, // 开启注入调试 "inject": true, // 开启注入调试
// 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器 // 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器
// 支持直接使用官方 demo 项目https://lowcode-engine.cn/demo/index.html // 支持直接使用官方 demo 项目https://lowcode-engine.cn/demo/index.html
"openUrl": "https://lowcode-engine.cn/demo/index.html?debug" "openUrl": "https://lowcode-engine.cn/demo/index.html?debug"
} }
], ],
] ]
} }
``` ```
2. 组件需先安装 @alilc/build-plugin-alt再将组件内的 `build.lowcode.js`文件修改如下 2. 组件需先安装 @alilc/build-plugin-alt再将组件内的 `build.lowcode.js`文件修改如下
```javascript ```javascript
const { library } = require('./build.json'); const { library } = require('./build.json');
module.exports = { module.exports = {
alias: { alias: {
'@': './src', '@': './src',
}, },
plugins: [ plugins: [
[ [
// lowcode 的配置保持不变,这里仅为示意。 // lowcode 的配置保持不变,这里仅为示意。
'@alifd/build-plugin-lowcode', '@alifd/build-plugin-lowcode',
{ {
library, library,
engineScope: "@alilc" engineScope: "@alilc"
}, },
], ],
[ [
'@alilc/build-plugin-alt', '@alilc/build-plugin-alt',
{ {
type: 'component', type: 'component',
inject: true, inject: true,
library, library,
// 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器 // 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器
// 支持直接使用官方 demo 项目https://lowcode-engine.cn/demo/index.html // 支持直接使用官方 demo 项目https://lowcode-engine.cn/demo/index.html
openUrl: "https://lowcode-engine.cn/demo/index.html?debug" openUrl: "https://lowcode-engine.cn/demo/index.html?debug"
} }
]], ]],
}; };
``` ```
3. 本地组件/插件/Setter正常启动调试在项目的访问地址增加 debug即可开启注入调试。 3. 本地组件/插件/Setter正常启动调试在项目的访问地址增加 debug即可开启注入调试。
```typescript ```url
https://lowcode-engine.cn/demo/index.html?debug https://lowcode-engine.cn/demo/demo-general/index.html?debug
``` ```
## 项目侧的准备 ## 项目侧的准备
> 如果你的低代码项目 fork 自官方 demo那么项目侧的准备已经就绪不用再看以下内容~ > 如果你的低代码项目 fork 自官方 demo那么项目侧的准备已经就绪不用再看以下内容~
1. 安装 @alilc/lowcode-plugin-inject 1. 安装 @alilc/lowcode-plugin-inject
```shell ```bash
npm i @alilc/lowcode-plugin-inject --save-dev npm i @alilc/lowcode-plugin-inject --save-dev
``` ```
2. 在引擎初始化侧引入插件 2. 在引擎初始化侧引入插件
```json ```typescript
import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject';
export default async () => { export default async () => {
// 注意 Inject 插件必须在其他插件前注册,且所有插件的注册必须 await // 注意 Inject 插件必须在其他插件前注册,且所有插件的注册必须 await
await plugins.register(Inject); await plugins.register(Inject);
await plugins.register(OtherPlugin); await plugins.register(OtherPlugin);
await plugins.register((ctx: ILowCodePluginContext) => { await plugins.register((ctx: ILowCodePluginContext) => {
return { return {
name: "editor-init", name: "editor-init",
async init() { async init() {
// 设置物料描述前,使用插件提供的 injectAssets 进行处理 // 设置物料描述前,使用插件提供的 injectAssets 进行处理
const { material, project } = ctx; const { material, project } = ctx;
material.setAssets(await injectAssets(assets)); material.setAssets(await injectAssets(assets));
}, },
}; };
}); });
} }
``` ```
3. 在 saveSchema 时过滤掉插入的url避免影响渲染态 3. 在 saveSchema 时过滤掉插入的 url避免影响渲染态
```javascript ```typescript
import { filterPackages } from '@alilc/lowcode-plugin-inject'; import { filterPackages } from '@alilc/lowcode-plugin-inject';
export const saveSchema = async () => { export const saveSchema = async () => {
// ... // ...
const packages = await filterPackages(editor.get('assets').packages); const packages = await filterPackages(editor.get('assets').packages);
window.localStorage.setItem( window.localStorage.setItem(
'packages', 'packages',
JSON.stringify(packages), JSON.stringify(packages),
); );
// ... // ...
}; };
```
```
4. 如果希望预览态也可以注入调试组件,则需要在 preview 逻辑里插入组件 4. 如果希望预览态也可以注入调试组件,则需要在 preview 逻辑里插入组件
```javascript ```javascript
import { injectComponents } from '@alilc/lowcode-plugin-inject'; import { injectComponents } from '@alilc/lowcode-plugin-inject';
async function init() { async function init() {
// 在传递给 ReactRenderer 前,先通过 injectComponents 进行处理 // 在传递给 ReactRenderer 前,先通过 injectComponents 进行处理
const components = await injectComponents(buildComponents(libraryMap, componentsMap)); const components = await injectComponents(buildComponents(libraryMap, componentsMap));
// ... // ...
} }
``` ```
# Meta 信息 # Meta 信息
meta 信息是放在生态元素 package.json 中的一小段 json用户可以通过 meta 了解到这个元素的一些基本信息,如元素类型,一些入口信息等。 meta 信息是放在生态元素 package.json 中的一小段 json用户可以通过 meta 了解到这个元素的一些基本信息,如元素类型,一些入口信息等。
```typescript ```typescript
interface LcMeta { interface LcMeta {
type: 'plugin' | 'setter' | 'component'; // 元素类型,尚未实现 type: 'plugin' | 'setter' | 'component'; // 元素类型,尚未实现
pluginName: string; // 插件名,仅插件包含 pluginName: string; // 插件名,仅插件包含
meta: { meta: {
dependencies: string[]; // 插件依赖的其他插件列表,仅插件包含 dependencies: string[]; // 插件依赖的其他插件列表,仅插件包含
engines: { engines: {
lowcodeEngine: string; // 适配的引擎版本 lowcodeEngine: string; // 适配的引擎版本
} }
prototype: string; // 物料描述入口,仅组件包含,尚未实现 prototype: string; // 物料描述入口,仅组件包含,尚未实现
prototypeView: string; // 物料设计态入口,仅组件包含,尚未实现 prototypeView: string; // 物料设计态入口,仅组件包含,尚未实现
} }
} }
``` ```

View File

@ -12,14 +12,14 @@ sidebar_position: 1
低代码编辑器中的物料需要进行一定的配置和处理,才能让用户在低代码平台使用起来。这个过程中,需要一份一份配置文件,也就是资产包。资产包文件中,针对每个物料定义了它们在低代码编辑器中的使用描述。 低代码编辑器中的物料需要进行一定的配置和处理,才能让用户在低代码平台使用起来。这个过程中,需要一份一份配置文件,也就是资产包。资产包文件中,针对每个物料定义了它们在低代码编辑器中的使用描述。
## 资产包配置 ## 资产包配置
### 什么是低代码资产包 ### 什么是低代码资产包
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647671718994-e013a162-37be-4fa7-bd3b-3af06878c3c2.png#clientId=uf20508c2-6786-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=579&id=u7a0c3dae&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1646&originWidth=3068&originalType=binary&ratio=1&rotation=0&showTitle=false&size=635660&status=done&style=stroke&taskId=uc304cc2b-24bf-449d-8e2e-fd25c88b189&title=&width=1080) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01SQJfxh1Y8uwDXksaK_!!6000000003015-2-tps-3068-1646.png)
在低代码 Demo 中,我们可以看到,组件面板不只提供一个组件,组件是以集合的形式提供给低代码平台的,而低代码资产包正是这些组件构成集合的形式。 在低代码 Demo 中,我们可以看到,组件面板不只提供一个组件,组件是以集合的形式提供给低代码平台的,而低代码资产包正是这些组件构成集合的形式。
**_它背后的 Interface_**[**_在引擎中的定义摘抄如下_**](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/assets.ts)**__** **_它背后的 Interface_**[**_在引擎中的定义摘抄如下_**](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/assets.ts)**__**
```typescript ```typescript
export interface Assets { export interface Assets {
version: string; // 资产包协议版本号 version: string; // 资产包协议版本号
packages?: Array<Package>; // 大包列表external与package的概念相似融合在一起 packages?: Array<Package>; // 大包列表external package 的概念相似,融合在一起
components: Array<ComponentDescription> | Array<RemoteComponentDescription>; // 所有组件的描述协议列表 components: Array<ComponentDescription> | Array<RemoteComponentDescription>; // 所有组件的描述协议列表
sort: ComponentSort; // 新增字段,用于描述组件面板中的 tab 和 category sort: ComponentSort; // 新增字段,用于描述组件面板中的 tab 和 category
} }
@ -32,7 +32,7 @@ export interface ComponentSort {
export interface RemoteComponentDescription { export interface RemoteComponentDescription {
exportName: string; // 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; exportName: string; // 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容;
url: string; // 组件描述的资源链接; url: string; // 组件描述的资源链接;
package: { // 组件(库)的 npm 信息; package: { // 组件 (库) 的 npm 信息;
npm: string; npm: string;
} }
} }
@ -40,14 +40,14 @@ export interface RemoteComponentDescription {
资产包协议 TS 描述 资产包协议 TS 描述
### Demo 中的资产包 ### Demo 中的资产包
在 Demo 项目中,自带了一份默认的资产包: 在 Demo 项目中,自带了一份默认的资产包:
> [https://github.com/alibaba/lowcode-demo/blob/main/src/universal/assets.json](https://github.com/alibaba/lowcode-demo/blob/main/src/universal/assets.json) > [https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/services/assets.json](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/services/assets.json)
这份资产包里的物料是我们内部沉淀出的,用户可以通过这套资产包体验引擎提供的搭建、配置能力。 这份资产包里的物料是我们内部沉淀出的,用户可以通过这套资产包体验引擎提供的搭建、配置能力。
**_在项目中正常注册资产包_** **_在项目中正常注册资产包_**
```json ```typescript
import { material } from '@alilc/lowcode-engine' import { material } from '@alilc/lowcode-engine';
// 以任何方式引入 assets // 以任何方式引入 assets
material.setAssets(assets) material.setAssets(assets);
``` ```
**_以支持调试的方式注册资产包_** **_以支持调试的方式注册资产包_**
> 这样启动并部署出来的项目,可以通过在预览地址加上 ?debug 来调试本地物料。 > 这样启动并部署出来的项目,可以通过在预览地址加上 ?debug 来调试本地物料。
@ -55,18 +55,18 @@ material.setAssets(assets)
> - 通过插件初始化一个物料 > - 通过插件初始化一个物料
> - 按照参考文章配置物料支持调试 > - 按照参考文章配置物料支持调试
> - 启动物料 > - 启动物料
> - 访问:[https://lowcode-engine.cn/demo?debug](https://lowcode-engine.cn/demo?debug) > - 访问:[https://lowcode-engine.cn/demo/demo-general/index.html?debug](https://lowcode-engine.cn/demo/demo-general/index.html)
> >
详细参考:[https://www.yuque.com/lce/doc/ulvlkz](https://www.yuque.com/lce/doc/ulvlkz) 详细参考:[低代码生态脚手架 & 调试机制](https://lowcode-engine.cn/site/docs/guide/expand/editor/cli)
```javascript ```typescript
import { material } from '@alilc/lowcode-engine' import { material } from '@alilc/lowcode-engine';
import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject';
await material.setAssets(await injectAssets(assets)); await material.setAssets(await injectAssets(assets));
``` ```
### 手工配置资产包 ### 手工配置资产包
参考 Demo 中的[基础 Fusion Assets 定义](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/basic-fusion/assets.json),如果我们修改 assets.json我们就能做到配置资产包 参考 Demo 中的[基础 Fusion Assets 定义](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json),如果我们修改 assets.json我们就能做到配置资产包
- packages 对象:我们需要在其中定义这个包的获取方式,如果不定义,就不会被低代码引擎动态加载并对应上组件实例。定义方式是 UMD 的包,低代码引擎会尝试在 window 上寻找对应 library 的实例; - packages 对象:我们需要在其中定义这个包的获取方式,如果不定义,就不会被低代码引擎动态加载并对应上组件实例。定义方式是 UMD 的包,低代码引擎会尝试在 window 上寻找对应 library 的实例;
- components 对象:我们需要在其中定义物料描述,物料描述我们将在下一节继续讲解。 - components 对象:我们需要在其中定义物料描述,物料描述我们将在下一节继续讲解。
@ -80,14 +80,14 @@ await material.setAssets(await injectAssets(assets));
4. 画布更新生效。 4. 画布更新生效。
**_当我们选中一个组件我们可以看到面板右侧会显示组件的配置项。_** **_当我们选中一个组件我们可以看到面板右侧会显示组件的配置项。_**
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644312295732-5e0df2b5-065a-4d80-a66c-b5b20c8c32af.png#clientId=ue1d4eb8d-3b5c-4&crop=0&crop=0&crop=1&crop=1&from=url&height=535&id=ML9vP&margin=%5Bobject%20Object%5D&name=image.png&originHeight=743&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=212807&status=done&style=stroke&taskId=u2458e0f7-6bea-40d8-bb9b-9811562c6fe&title=&width=1080) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01T5hGcl25ABLpLIWKh_!!6000000007485-2-tps-1500-743.png)
**_它包含以下内容_** **_它包含以下内容_**
1. 基础信息:描述组件的基础信息,通常包含包信息、组件名称、标题、描述等。 1. 基础信息:描述组件的基础信息,通常包含包信息、组件名称、标题、描述等。
2. 组件属性信息:描述组件属性信息,通常包含参数、说明、类型、默认值 4 项内容。 2. 组件属性信息:描述组件属性信息,通常包含参数、说明、类型、默认值 4 项内容。
3. 能力配置/体验增强:推荐用于优化搭建产品编辑体验,定制编辑能力的配置信息。 3. 能力配置/体验增强:推荐用于优化搭建产品编辑体验,定制编辑能力的配置信息。
因此,我们设计了[**《中后台低代码组件描述协议》**](http://lowcode-engine.cn/material)来描述一个低代码编辑器中可被配置的内容。 因此,我们设计了[**《中后台低代码组件描述协议》**](/site/docs/specs/material-spec)来描述一个低代码编辑器中可被配置的内容。
### Demo 中的物料描述 ### Demo 中的物料描述
我们可以从 Demo 中的 assets.json 找到如下三个物料描述: 我们可以从 Demo 中的 assets.json 找到如下三个物料描述:
@ -97,13 +97,13 @@ await material.setAssets(await injectAssets(assets));
**_引擎中会尝试调用对应 meta 文件并注入到全局_** **_引擎中会尝试调用对应 meta 文件并注入到全局_**
```tsx ```tsx
const src = 'https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/meta.js' const src = 'https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/meta.js';
const script = document.createElement('script') const script = document.createElement('script');
script.src = src script.src = src;
document.head.appendChild(script) document.head.appendChild(script);
``` ```
然后在 window 上就能拿到对应的物料描述内容了: 然后在 window 上就能拿到对应的物料描述内容了:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647672326187-ec19ed1e-645a-4086-8384-ccca19b9f36c.png#clientId=uf20508c2-6786-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=648&id=ue7a84d56&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1138&originWidth=1896&originalType=binary&ratio=1&rotation=0&showTitle=false&size=582492&status=done&style=stroke&taskId=u11707d78-e1c5-4368-9de0-e98b7597815&title=&width=1080) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01DHSEOH1RwCEq19Ro9_!!6000000002175-2-tps-1896-1138.png)
手工配置物料描述时,可以用这样的方式参考一下 Demo 中的物料描述是如何实现的。 手工配置物料描述时,可以用这样的方式参考一下 Demo 中的物料描述是如何实现的。
### 手工配置物料描述 ### 手工配置物料描述
详见:“物料描述详解”章节。 详见:“物料描述详解”章节。
@ -113,18 +113,18 @@ document.head.appendChild(script)
您可以通过本节内容,完成一个组件在低代码编辑器中的配置和调试。 您可以通过本节内容,完成一个组件在低代码编辑器中的配置和调试。
### 前言(必读) ### 前言(必读)
引擎提供的物料开发脚手架内置了**_入料模块_**初始化的时候会自动根据源码解析出一份_**低代码描述**_但是从源码解析出来的低代码描述让用户直接使用是不够精细的因为源码包含的信息不够它没办法完全包含配置项的交互 引擎提供的物料开发脚手架内置了**_入料模块_**初始化的时候会自动根据源码解析出一份_**低代码描述**_但是从源码解析出来的低代码描述让用户直接使用是不够精细的因为源码包含的信息不够它没办法完全包含配置项的交互
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1650539267595-c15e6200-9747-46bf-a61d-2a635d295406.png?x-oss-process=image/format,png#clientId=u97daa023-2ae2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=856&id=u5b22ab2d&name=image.png&originHeight=1830&originWidth=802&originalType=binary&ratio=1&rotation=0&showTitle=false&size=4406602&status=done&style=stroke&taskId=ued90eb0c-b714-401a-bbfe-9f0b04794f6&title=&width=375) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN010t0YzC1znDPQB1LUA_!!6000000006758-2-tps-802-1830.png)
比如设计师出了上面的设计稿,这里面除了有哪些 props 可被配置,通过哪个设置器配置,还包含了 props 之间的聚合、排序,甚至有自定义 setter ,这些信息源码里是不具备的,需要在低代码描述里进行开发; 比如设计师出了上面的设计稿,这里面除了有哪些 props 可被配置,通过哪个设置器配置,还包含了 props 之间的聚合、排序,甚至有自定义 setter这些信息源码里是不具备的需要在低代码描述里进行开发
**_因此我们建议只把 cli 初始化的低代码描述作为启动要根据用户习惯对配置项进行设计然后人工地去开发调试直接的低代码描述。_** **_因此我们建议只把 cli 初始化的低代码描述作为启动要根据用户习惯对配置项进行设计然后人工地去开发调试直接的低代码描述。_**
### 新开发组件 ### 新开发组件
#### 组件项目初始化 #### 组件项目初始化
```json ```bash
npm init @alilc/element your-material-name npm init @alilc/element your-material-name
``` ```
#### 选择组件类型 #### 选择组件类型
> 组件 -> <组件组织方式> > 组件 -> <组件组织方式>
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647569723981-d0cb5f94-c137-4abf-8165-947b49595c8c.png#clientId=u6b9f3678-e2a3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=174&id=ud7ad63de&margin=%5Bobject%20Object%5D&name=image.png&originHeight=464&originWidth=1596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=298505&status=done&style=stroke&taskId=ud5e35ff9-c823-41bf-b441-db9e06a1f29&title=&width=600) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01BTiMt51iLPtzDbuh8_!!6000000004396-2-tps-1596-464.png)
这里我们选择 react-组件库,之后便生出我们的组件库项目,目录结构如下: 这里我们选择 react-组件库,之后便生出我们的组件库项目,目录结构如下:
``` ```
my-materials my-materials
@ -147,7 +147,7 @@ my-materials
└── └── ExampleComponent2 // 业务组件2 └── └── ExampleComponent2 // 业务组件2
``` ```
#### 组件开发与调试 #### 组件开发与调试
``` ```bash
# 安装依赖 # 安装依赖
npm install npm install
@ -157,15 +157,15 @@ npm run lowcode:dev
# 构建低代码产物 # 构建低代码产物
npm run lowcode:build npm run lowcode:build
``` ```
执行上述命令后会在组件(库)根目录生成一个 `lowcode` 文件夹,里面会包含每个组件的低代码描述: 执行上述命令后会在组件 (库) 根目录生成一个 `lowcode` 文件夹,里面会包含每个组件的低代码描述:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644314663918-b2464be7-a65b-447c-af2a-12ea326a7558.png#clientId=ue1d4eb8d-3b5c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=376&id=AYq7T&margin=%5Bobject%20Object%5D&name=image.png&originHeight=906&originWidth=1446&originalType=binary&ratio=1&rotation=0&showTitle=false&size=347634&status=done&style=stroke&taskId=u25ffbb86-6681-427f-b199-69a22560a9c&title=&width=600) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN016m7gOK1DvpIcnlTvY_!!6000000000279-2-tps-1446-906.png)
在 src/components 目录新增一个组件并在 src/index.tsx 中导出,然后再执行 npm run lowcode:dev 时,低代码插件会在 lowcode/<component-name\> 目录自动生成新增组件的低代码描述meta.ts)。 在 src/components 目录新增一个组件并在 src/index.tsx 中导出,然后再执行 npm run lowcode:dev 时,低代码插件会在 lowcode/<component-name\> 目录自动生成新增组件的低代码描述meta.ts)。
用户可以直接修改低代码描述来修改组件的配置: 用户可以直接修改低代码描述来修改组件的配置:
- 设置组件的 setter(上一个章节介绍的设置器,也可以定制设置器用到物料中) - 设置组件的 setter上一个章节介绍的设置器也可以定制设置器用到物料中
- 新增组件配置项 - 新增组件配置项;
- 更改当前配置项; - 更改当前配置项;
#### 配置示例 #### 配置示例
隐藏一个 prop 隐藏一个 prop
@ -179,24 +179,27 @@ npm run lowcode:build
```typescript ```typescript
{ {
name: 'dataSource', name: 'dataSource',
display: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry' // 常用的是 inline(默认), block、entry display: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry', // 常用的是 inline(默认), block、entry
} }
``` ```
发布组件 发布组件
``` ```bash
# 在组件根目录下,执行 # 在组件根目录下,执行
$ npm publish $ npm publish
``` ```
### 现存组件低代码化 ### 现存组件低代码化
组件低代码化是指,在引入低代码平台之前,我们大多数都是使用源码开发的组件,也就是 ProCode 组件。 组件低代码化是指,在引入低代码平台之前,我们大多数都是使用源码开发的组件,也就是 ProCode 组件。
在引入低代码平台之后,原来的源码组件是需要转化为低代码物料,这样才能在低代码平台进行消费。 在引入低代码平台之后,原来的源码组件是需要转化为低代码物料,这样才能在低代码平台进行消费。
所以接下来会说明,对于已有的源码组件,我们如何把它低代码化。 所以接下来会说明,对于已有的源码组件,我们如何把它低代码化。
#### 配置低代码开发环境 #### 配置低代码开发环境
在您的组件开发环境中,安装 [build-scripts](https://github.com/ice-lab/build-scripts) 和它的低代码开发插件: 在您的组件开发环境中,安装 [build-scripts](https://github.com/ice-lab/build-scripts) 和它的低代码开发插件:
```shell ```bash
npm install -D @alifd/build-plugin-lowcode @alib/build-scripts --save-dev npm install -D @alifd/build-plugin-lowcode @alib/build-scripts --save-dev
``` ```
新增 build-scripts 配置文件build.lowcode.js 新增 build-scripts 配置文件build.lowcode.js
```javascript ```javascript
module.exports = { module.exports = {
alias: { alias: {
@ -218,39 +221,49 @@ module.exports = {
"lowcode:dev": "build-scripts start --config ./build.lowcode.js", "lowcode:dev": "build-scripts start --config ./build.lowcode.js",
"lowcode:build": "build-scripts build --config ./build.lowcode.js", "lowcode:build": "build-scripts build --config ./build.lowcode.js",
``` ```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644314665584-018b6675-ca7c-4bf5-b755-15a9b629f78f.png#clientId=ue1d4eb8d-3b5c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=270&id=brUY9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=822&originWidth=1830&originalType=binary&ratio=1&rotation=0&showTitle=false&size=972113&status=done&style=stroke&taskId=u09d05c9e-cf05-417e-bf32-8268d004134&title=&width=600) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN014iSa1P1dNdkUUtoMm_!!6000000003724-2-tps-1830-822.png)
#### 开发调试 #### 开发调试
```bash ```bash
# 启动低代码开发调试环境 # 启动低代码开发调试环境
npm run lowcode:dev npm run lowcode:dev
``` ```
组件开发形式还和原来的保持一致,但是新增了一份组件的配置文件,其中配置方式和低代码物料的配置是一样的。 组件开发形式还和原来的保持一致,但是新增了一份组件的配置文件,其中配置方式和低代码物料的配置是一样的。
#### 构建 #### 构建
```bash ```bash
# 构建低代码产物 # 构建低代码产物
npm run lowcode:build npm run lowcode:build
``` ```
#### 发布组件 #### 发布组件
```bash ```bash
# 在组件根目录下,执行 # 在组件根目录下,执行
npm publish npm publish
``` ```
## 在项目中引入组件(库)
> 以下内容可观看[《阿里巴巴低代码引擎项目实战(3)-自定义组件接入》](https://www.bilibili.com/video/BV1dZ4y1m76S/)直播回放 ## 在项目中引入组件 (库)
> 以下内容可观看[《阿里巴巴低代码引擎项目实战 (3)-自定义组件接入》](https://www.bilibili.com/video/BV1dZ4y1m76S/)直播回放
对于平台或者用户来说,可能所需要的组件集合是不同的。如果需要自定义组件集合,就需要定制资产包,定制的资产包是配置了一系列组件的,将这份资产包用于引擎即可在引擎中使用自定义的组件集合。 对于平台或者用户来说,可能所需要的组件集合是不同的。如果需要自定义组件集合,就需要定制资产包,定制的资产包是配置了一系列组件的,将这份资产包用于引擎即可在引擎中使用自定义的组件集合。
### 管理一份资产包 ### 管理一份资产包
项目中使用的组件相关资源都需要在资产包中定义,那么我们自己开发的组件库如果要在项目中使用,只需要把组件构建好的相关资源 merge 到 assets.json 中就可以; 项目中使用的组件相关资源都需要在资产包中定义,那么我们自己开发的组件库如果要在项目中使用,只需要把组件构建好的相关资源 merge 到 assets.json 中就可以;
#### 自定义组件加入到资产包 #### 自定义组件加入到资产包
通过官方脚手架自定义组件构建发布之后npm 包里会出现一个 `build/lowcode/assets-prod.json`文件,我们只需要把该文件的内容 merge 到项目的 assets.json 中就可以; 通过官方脚手架自定义组件构建发布之后npm 包里会出现一个 `build/lowcode/assets-prod.json`文件,我们只需要把该文件的内容 merge 到项目的 assets.json 中就可以;
#### 资产包托管 #### 资产包托管
- 最简单的方式就是类似[引擎 demo 项目](https://github.com/alibaba/lowcode-demo/blob/main/src/universal/assets.json)的做法,在项目中维护一份 assets.json新增组件或者组件版本更新都需要修改这份资产包 - 最简单的方式就是类似[引擎 demo 项目](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/services/assets.json)的做法,在项目中维护一份 assets.json新增组件或者组件版本更新都需要修改这份资产包
- 灵活一点的做法是通过 oss 等服务维护一份远程可配置的 assets.json ,新增组件或者组件更新只需要修改这份远程的资产包,项目无需更新; - 灵活一点的做法是通过 oss 等服务维护一份远程可配置的 assets.json新增组件或者组件更新只需要修改这份远程的资产包项目无需更新
- 再高级一点的做法是实现一个资产包管理的服务,能够通过用户界面去更新资产包的内容; - 再高级一点的做法是实现一个资产包管理的服务,能够通过用户界面去更新资产包的内容;
### 在项目中引入资产包 ### 在项目中引入资产包
```javascript ```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine' import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine';
// 动态加载 assets // 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => { plugins.register((ctx: ILowCodePluginContext) => {
@ -259,13 +272,13 @@ plugins.register((ctx: ILowCodePluginContext) => {
async init() { async init() {
try { try {
// 将下述链接替换为您的物料即可。无论是通过 utils 从物料中心引入,还是通过其他途径如直接引入物料描述 // 将下述链接替换为您的物料即可。无论是通过 utils 从物料中心引入,还是通过其他途径如直接引入物料描述
const res = await window.fetch('https://fusion.alicdn.com/assets/default@0.1.95/assets.json') const res = await window.fetch('https://fusion.alicdn.com/assets/default@0.1.95/assets.json');
const assets = await res.text() const assets = await res.text();
material.setAssets(assets) material.setAssets(assets);
} catch (err) { } catch (err) {
console.error(err) console.error(err);
} }
}, },
} }
}).catch(err => console.error(err)) }).catch(err => console.error(err));
``` ```

View File

@ -4,13 +4,13 @@ sidebar_position: 2
--- ---
## 物料描述概述 ## 物料描述概述
中后台前端体系中,存在大量的组件,程序员可以通过阅读文档,知悉组件的用法。可是搭建平台无法理解 README而且很多时候README 里并没有属性列表。这时,我们需要一份额外的描述,来告诉低代码搭建平台,组件接受哪些属性,又是该用怎样的方式来配置这些属性,于是,[**《中后台低代码组件描述协议》**](http://lowcode-engine.cn/material)应运而生。协议主要包含三部分:基础信息、属性信息 props、能力配置/体验增强 configure。 中后台前端体系中,存在大量的组件,程序员可以通过阅读文档,知悉组件的用法。可是搭建平台无法理解 README而且很多时候README 里并没有属性列表。这时,我们需要一份额外的描述,来告诉低代码搭建平台,组件接受哪些属性,又是该用怎样的方式来配置这些属性,于是,[**《中后台低代码组件描述协议》**](/site/docs/specs/material-spec)应运而生。协议主要包含三部分:基础信息、属性信息 props、能力配置/体验增强 configure。
物料配置,就是产出一份符合[**《中后台低代码组件描述协议》**](http://lowcode-engine.cn/material)的 JSON Schema。如果需要补充属性描述信息或需要定制体验增强部分如修改 Setter、调整展示顺序等就可以通过修改这份 Schema 来实现。目前有自动生成、手工配置这两种方式生成物料描述配置。 物料配置,就是产出一份符合[**《中后台低代码组件描述协议》**](/site/docs/specs/material-spec)的 JSON Schema。如果需要补充属性描述信息或需要定制体验增强部分如修改 Setter、调整展示顺序等就可以通过修改这份 Schema 来实现。目前有自动生成、手工配置这两种方式生成物料描述配置。
## 可视化生成物料描述 ## 可视化生成物料描述
使用Parts造物平台[https://www.yuque.com/lce/xhk5hf/qa9pbx](https://www.yuque.com/lce/xhk5hf/qa9pbx) 使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/partsIntro)
## 自动生成物料描述 ## 自动生成物料描述
@ -28,7 +28,7 @@ export default class FusionForm extends PureComponent {
static defaultProps = { static defaultProps = {
name: '张三', name: '张三',
age: 18, age: 18,
friends: ['李四','王五','赵六'] friends: ['李四','王五','赵六'],
} }
static propTypes = { static propTypes = {
@ -47,11 +47,13 @@ export default class FusionForm extends PureComponent {
}; };
render() { render() {
return <div>dumb</div> return <div>dumb</div>;
} }
} }
``` ```
引入 parse 工具自动解析 引入 parse 工具自动解析
```typescript ```typescript
import parse from '@alilc/lowcode-material-parser'; import parse from '@alilc/lowcode-material-parser';
(async () => { (async () => {
@ -59,7 +61,9 @@ import parse from '@alilc/lowcode-material-parser';
console.log(JSON.stringify(result, null, 2)); console.log(JSON.stringify(result, null, 2));
})(); })();
``` ```
因为一个组件可能输出多个子组件,所以解析结果是个数组。 因为一个组件可能输出多个子组件,所以解析结果是个数组。
```json ```json
[ [
{ {
@ -103,6 +107,7 @@ import parse from '@alilc/lowcode-material-parser';
} }
] ]
``` ```
## 手工配置物料描述 ## 手工配置物料描述
如果自动生成的物料无法满足需求,我们就需要手动配置物料描述。本节将分场景描述物料配置的内容。 如果自动生成的物料无法满足需求,我们就需要手动配置物料描述。本节将分场景描述物料配置的内容。
@ -113,7 +118,8 @@ import parse from '@alilc/lowcode-material-parser';
增加一个 size 属性,只能从 'large'、'normal'、'small' 这个候选值中选择。 增加一个 size 属性,只能从 'large'、'normal'、'small' 这个候选值中选择。
以上面自动解析的物料为例,在此基础上手工加上 size 属性: 以上面自动解析的物料为例,在此基础上手工加上 size 属性:
```json ```json
[ [
{ {
@ -168,7 +174,7 @@ import parse from '@alilc/lowcode-material-parser';
"options": [ "options": [
{ "title": "大", "value": "large" }, { "title": "大", "value": "large" },
{ "title": "中", "value": "normal" }, { "title": "中", "value": "normal" },
{ "title": "小", "value": "small" }, { "title": "小", "value": "small" }
] ]
}, },
} }
@ -180,18 +186,20 @@ import parse from '@alilc/lowcode-material-parser';
``` ```
#### 组件的属性既可以设置固定值,也可以绑定到变量 #### 组件的属性既可以设置固定值,也可以绑定到变量
我们知道一种属性形式就需要一种 setter 来设置,如果想要将 value 属性允许输入字符串,那就需要设置为 `StringSetter`,如果允许绑定变量,就需要设置为 `VariableSetter`,具体设置器请参考[预置 Setter 列表](https://www.yuque.com/lce/doc/oc220p)
那如果都想要呢?可以使用 `MixedSetter` 来实现 我们知道一种属性形式就需要一种 setter 来设置,如果想要将 value 属性允许输入字符串,那就需要设置为 `StringSetter`,如果允许绑定变量,就需要设置为 `VariableSetter`,具体设置器请参考[预置设置器列表](/site/docs/guide/appendix/setters)。
```json
那如果都想要呢?可以使用 `MixedSetter` 来实现。
```javascript
{ {
..., // ...
configure: { configure: {
isExtend: true, isExtend: true,
props: [ props: [
{ {
title: "输入框的值", title: '输入框的值',
name: "activeValue", name: 'activeValue',
setter: { setter: {
componentName: 'MixedSetter', componentName: 'MixedSetter',
isRequired: true, isRequired: true,
@ -208,14 +216,18 @@ import parse from '@alilc/lowcode-material-parser';
} }
} }
``` ```
设置后,就会出现 “切换设置器” 的操作项了
![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647590065530-b50ed66a-8d24-40fc-91a9-13561663537b.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=126&id=ub0e036f6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=252&originWidth=598&originalType=binary&ratio=1&rotation=0&showTitle=false&size=62314&status=done&style=none&taskId=u6545c47c-0fed-44eb-bfab-03694941981&title=&width=299) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647590197192-cd0071cf-a90c-4882-9b65-4b46bff13ce9.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=154&id=u67de127d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=308&originWidth=244&originalType=binary&ratio=1&rotation=0&showTitle=false&size=24027&status=done&style=none&taskId=u1a44a2d7-3680-4018-8709-9832cd03ad0&title=&width=122) 设置后,就会出现“切换设置器”的操作项了
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01jBqcuK1xYRP00WyVx_!!6000000006455-2-tps-598-252.png)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01944xqq1PYihvYQb4v_!!6000000001853-2-tps-244-308.png)
#### 开启组件样式设置 #### 开启组件样式设置
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003600-48ef05cd-dbac-4aad-b7a5-012727fe1c6f.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u467d584c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=772&originWidth=820&originalType=url&ratio=1&rotation=0&showTitle=false&size=128316&status=done&style=none&taskId=ub01cb8bb-e784-485b-b2a6-aead3302c4f&title=) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01EBStyl24EvqJkAdh1_!!6000000007360-2-tps-820-772.png)
```tsx ```javascript
{ {
configure: { configure: {
// ..., // ...,
@ -229,12 +241,12 @@ import parse from '@alilc/lowcode-material-parser';
#### 设置组件的默认事件 #### 设置组件的默认事件
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003649-c0da562f-220c-415e-83ea-e07b71c07552.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u7b452a11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=800&originWidth=776&originalType=url&ratio=1&rotation=0&showTitle=false&size=120022&status=done&style=none&taskId=u6805e481-897b-4929-86c8-9321791a21a&title=) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN012gijqt1NERwqF5f6Y_!!6000000001538-2-tps-776-800.png)
```tsx ```javascript
{ {
configure: { configure: {
// ..., // ...
supports: { supports: {
events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'],
}, },
@ -245,9 +257,9 @@ import parse from '@alilc/lowcode-material-parser';
#### 设置 prop 标题的 tip #### 设置 prop 标题的 tip
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003618-4a1bb1c4-da39-437b-8510-a121329aa91d.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u7fe57bc7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=176&originWidth=908&originalType=url&ratio=1&rotation=0&showTitle=false&size=39688&status=done&style=none&taskId=u7e9e26eb-a4c3-423c-b7f1-f096d654d4e&title=) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01d8TdsY1jhENsKvwAv_!!6000000004579-2-tps-908-176.png)
```tsx ```javascript
{ {
name: 'label', name: 'label',
setter: 'StringSetter', setter: 'StringSetter',
@ -259,7 +271,7 @@ import parse from '@alilc/lowcode-material-parser';
}, },
tip: { tip: {
type: 'i18n', type: 'i18n',
zh_CN: '属性: label | 说明: 标签文本内容', zh_CN: '属性label | 说明:标签文本内容',
en_US: 'prop: label | description: label content', en_US: 'prop: label | description: label content',
}, },
}, },
@ -268,72 +280,79 @@ import parse from '@alilc/lowcode-material-parser';
#### 配置 prop 对应 setter 在配置面板的展示方式 #### 配置 prop 对应 setter 在配置面板的展示方式
inline:![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571004529-c879ec4c-18af-46fd-8231-4ab80c937399.png#clientId=uad16fa90-b520-4&crop=0.0174&crop=0.0597&crop=0.9933&crop=0.3909&from=paste&height=260&id=u8cdcc718&margin=%5Bobject%20Object%5D&name=image.png&originHeight=266&originWidth=790&originalType=url&ratio=1&rotation=0&showTitle=false&size=40667&status=done&style=none&taskId=u9390a3bb-0290-46c7-b487-7380f162fd0&title=&width=771) ##### inline
```tsx ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01z1sXj420vkP7vbeHj_!!6000000006912-2-tps-790-266.png)
```javascript
{ {
configure: { configure: {
props: [{ props: [{
description: '标签文本', description: '标签文本',
display: 'inline' display: 'inline',
}] }]
} }
} }
``` ```
block: ##### block
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571004690-22e7dc4f-db0d-43fe-b837-48ed1145bde7.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=0.996&crop=1&from=paste&height=273&id=ua1717366&margin=%5Bobject%20Object%5D&name=image.png&originHeight=274&originWidth=792&originalType=url&ratio=1&rotation=0&showTitle=false&size=31246&status=done&style=none&taskId=u9e678772-1217-4c64-ac75-c5928b48834&title=&width=789)
```tsx ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01i3MVKF299xchs6kMX_!!6000000008026-2-tps-792-274.png)
```javascript
{ {
configure: { configure: {
props: [{ props: [{
description: '高级', description: '高级',
display: 'block' display: 'block',
}] }]
} }
} }
``` ```
accordion ##### accordion
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005189-552ef14d-6043-48fa-a526-4565d42fa581.png#clientId=uad16fa90-b520-4&crop=0&crop=0.0159&crop=1&crop=1&from=paste&height=740&id=u53a75049&margin=%5Bobject%20Object%5D&name=image.png&originHeight=740&originWidth=798&originalType=url&ratio=1&rotation=0&showTitle=false&size=163685&status=done&style=none&taskId=ub42fca77-545e-435f-bafe-88e2b2ddfd1&title=&width=798) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01RePeyy1nhvRiBMm2w_!!6000000005122-2-tps-798-740.png)
```tsx
```javascript
{ {
configure: { configure: {
props: [{ props: [{
description: '表单项配置', description: '表单项配置',
display: 'accordion' display: 'accordion',
}] }]
} }
} }
``` ```
entry ##### entry
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005244-fb508efb-a2d8-4064-8ff3-d6140e4c20a1.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u16645b5c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=424&originWidth=796&originalType=url&ratio=1&rotation=0&showTitle=false&size=91418&status=done&style=none&taskId=u38c7b284-f480-4440-baac-9f7c985104f&title=) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01zkjBak1YY6igYUO1n_!!6000000003070-2-tps-796-424.png)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005468-1c7f4b24-4330-45e2-b6c9-5bf5362874b4.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u2fad6ab5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=632&originWidth=794&originalType=url&ratio=1&rotation=0&showTitle=false&size=158094&status=done&style=none&taskId=u7c356adc-4286-46b8-9a2c-d33b4268ddc&title=)
```tsx
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01lmuRTl1LOPKMnsfLJ_!!6000000001289-2-tps-794-632.png)
```javascript
{ {
configure: { configure: {
props: [{ props: [{
description: '风格与样式', description: '风格与样式',
display: 'entry' display: 'entry',
}] }]
} }
} }
``` ```
plain ##### plain
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005702-ad979f93-cc47-4c6f-8de7-454cc6305614.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u6aa6d230&margin=%5Bobject%20Object%5D&name=image.png&originHeight=438&originWidth=776&originalType=url&ratio=1&rotation=0&showTitle=false&size=133070&status=done&style=none&taskId=u1db8205a-79ed-4d60-91b4-6e7f5bfaff3&title=) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01G0DOfV1jGD0v049gk_!!6000000004520-2-tps-776-438.png)
```tsx ```javascript
{ {
configure: { configure: {
props: [{ props: [{
description: '返回上级', description: '返回上级',
display: 'plain' display: 'plain',
}] }]
} }
} }
@ -343,14 +362,18 @@ plain
### 进阶配置 ### 进阶配置
#### 组件的 children 属性允许传入 ReactNode #### 组件的 children 属性允许传入 ReactNode
例如有一个如下的 Tab 选项卡组件,每个 TabPane 的 children 都是一个组件 例如有一个如下的 Tab 选项卡组件,每个 TabPane 的 children 都是一个组件
![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647588145478-fb8b7296-a8ee-4698-9851-846c78de301e.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=167&id=bi43p&margin=%5Bobject%20Object%5D&name=image.png&originHeight=334&originWidth=2332&originalType=binary&ratio=1&rotation=0&showTitle=false&size=55470&status=done&style=none&taskId=ub8c8b04a-e2e9-4b5d-9be7-c7ad7154864&title=&width=1166)
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01Cu09HV1m8pTucSc7Q_!!6000000004910-2-tps-2332-334.png)
只需要增加 `isContainer` 配置即可 只需要增加 `isContainer` 配置即可
```json
```javascript
{ {
..., // ...
configure: { configure: {
..., // ...
component: { component: {
// 新增,设置组件为容器组件,可拖入组件 // 新增,设置组件为容器组件,可拖入组件
isContainer: true, isContainer: true,
@ -358,12 +381,14 @@ plain
} }
} }
``` ```
假设我们希望只允许拖拽 Table、Button 等内容放在 TabPane 里。配置白名单 `childWhitelist` 即可 假设我们希望只允许拖拽 Table、Button 等内容放在 TabPane 里。配置白名单 `childWhitelist` 即可
```json
```javascript
{ {
..., // ...
configure: { configure: {
..., // ...
component: { component: {
isContainer: true, isContainer: true,
nestingRule: { nestingRule: {
@ -377,17 +402,20 @@ plain
} }
``` ```
#### 组件的非 children 属性允许传入 ReactNode #### 组件的非 children 属性允许传入 ReactNode
这就需要使用 `SlotSetter` 开启插槽了,如下面示例,给 Tab 的 title 开启插槽,允许拖拽组件 这就需要使用 `SlotSetter` 开启插槽了,如下面示例,给 Tab 的 title 开启插槽,允许拖拽组件
![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647590398244-479c820e-3b2f-4d7e-8742-37cf896bcafb.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=290&id=Utp8Y&margin=%5Bobject%20Object%5D&name=image.png&originHeight=580&originWidth=3016&originalType=binary&ratio=1&rotation=0&showTitle=false&size=254405&status=done&style=none&taskId=u0c8f777c-3559-455a-b136-c884312bb67&title=&width=1508)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01P77m5m1pKEBXTk9Yt_!!6000000005341-2-tps-3016-580.png)
```json ```json
{ {
// ..., // ...
configure: { configure: {
isExtend: true, isExtend: true,
props: [ props: [
{ {
title: "选项卡标题", title: '选项卡标题',
name: "title", name: 'title',
setter: { setter: {
componentName: 'MixedSetter', componentName: 'MixedSetter',
props: { props: {
@ -397,35 +425,38 @@ plain
'VariableSetter', 'VariableSetter',
], ],
}, },
} },
} },
] ],
} },
} }
``` ```
#### 屏蔽组件在设计器中的操作按钮 #### 屏蔽组件在设计器中的操作按钮
正常情况下,组件允许复制: 正常情况下,组件允许复制:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003626-06d80381-4d97-4d5b-8621-331674832c82.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=Sp6IN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=226&originWidth=1158&originalType=url&ratio=1&rotation=0&showTitle=false&size=54949&status=done&style=none&taskId=u7e4b2cbe-5acf-467f-950b-ee48deb9502&title=)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01925Nyl1a2AKNQ1XCP_!!6000000003271-2-tps-1158-226.png)
如果希望禁止组件的复制行为,我们可以这样做: 如果希望禁止组件的复制行为,我们可以这样做:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647673808399-2708ff56-70d1-4c58-b93b-aa65269fb179.png#clientId=ufbfe731c-4217-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=150&id=A304J&margin=%5Bobject%20Object%5D&name=image.png&originHeight=300&originWidth=1176&originalType=binary&ratio=1&rotation=0&showTitle=false&size=90147&status=done&style=none&taskId=uf8da0392-c584-4d27-b664-95b3e908103&title=&width=588) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01IoLKUu1CXGRb0ileB_!!6000000000090-2-tps-1176-300.png)
```tsx
```javascript
{ {
configure: { configure: {
component: { component: {
disableBehaviors: ['copy'], disableBehaviors: ['copy'],
} },
} },
} }
``` ```
#### 实现一个 BackwardSetter #### 实现一个 BackwardSetter
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647674621328-6b0a5afc-eafc-43cc-95ce-bbe00981ac20.png#clientId=ufbfe731c-4217-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=219&id=u9c11597c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=438&originWidth=776&originalType=binary&ratio=1&rotation=0&showTitle=false&size=125336&status=done&style=none&taskId=u01853245-46a8-42dd-9c62-6cdbb909afa&title=&width=388) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01GI4VfT23ga8TUCjIh_!!6000000007285-2-tps-776-438.png)
```tsx ```javascript
{ {
name: 'back', name: 'back',
title: ' ', title: ' ',
@ -457,16 +488,16 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => {
- 始终隐藏当前 prop - 始终隐藏当前 prop
```tsx ```javascript
{ {
// 始终隐藏当前 prop 配置 // 始终隐藏当前 prop 配置
condition: () => false condition: () => false,
} }
``` ```
- 根据其它 prop 的值展示/隐藏当前 prop - 根据其它 prop 的值展示/隐藏当前 prop
```tsx ```javascript
{ {
// direction 为 hoz 则展示当前 prop 配置 // direction 为 hoz 则展示当前 prop 配置
condition: (target) => { condition: (target) => {
@ -477,7 +508,7 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => {
#### props 联动 #### props 联动
```tsx ```javascript
// 根据当前 prop 的值动态设置其它 prop 的值 // 根据当前 prop 的值动态设置其它 prop 的值
{ {
name: 'labelAlign', name: 'labelAlign',
@ -510,9 +541,9 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => {
#### 动态 setter 配置 #### 动态 setter 配置
可以通过 DynamicSetter 传入的 target 获取一些引擎暴露的数据,例如当前有哪些组件被加载到引擎中,将这个数据作为 SelectSetter 的选项,让用户选择: 可以通过 DynamicSetter 传入的 target 获取一些引擎暴露的数据,例如当前有哪些组件被加载到引擎中,将这个数据作为 SelectSetter 的选项,让用户选择
```tsx ```javascript
{ {
setter: (target) => { setter: (target) => {
return { return {
@ -528,7 +559,7 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => {
} }
), ),
), ),
} },
}; };
} }
} }

View File

@ -1,75 +1,99 @@
--- ---
title: 利用Parts造物快速使用react组件 title: 利用 Parts 造物快速使用 react 组件
sidebar_position: 3 sidebar_position: 3
--- ---
## 介绍 ## 介绍
大家在使用[低代码引擎](https://lowcode-engine.cn/)构建低代码应用平台时,遇到的一个主要问题是如何让已有的 React 组件能够快速低成本地接入进来。这个问题拆解下来主要包括两个子问题1. 如何给已有组件[配置物料描述](https://lowcode-engine.cn/material)2. 如何构建出一个低代码引擎能够识别的资产包(Assets)。 大家在使用[低代码引擎](https://lowcode-engine.cn/)构建低代码应用平台时,遇到的一个主要问题是如何让已有的 React 组件能够快速低成本地接入进来。这个问题拆解下来主要包括两个子问题:
我们的产品 「[Parts·造物](https://parts.lowcode-engine.cn/)」 可以帮助大家解决这个问题。我们通过在线可视化的方式完成物料描述配置,并且提供一键打包的功能生成引擎可以识别的资产包。 1. 如何给已有组件[配置物料描述](/site/docs/specs/material-spec)
2. 如何构建出一个低代码引擎能够识别的资产包 (Assets)。
我们的产品「[Parts·造物](https://parts.lowcode-engine.cn/)」可以帮助大家解决这个问题。我们通过在线可视化的方式完成物料描述配置,并且提供一键打包的功能生成引擎可以识别的资产包。
## 导入物料 ## 导入物料
首先,我们需要在 [物料管理](https://parts.lowcode-engine.cn/material#/) 页面导入我们需要进行在线物料描述配置的物料。 首先,我们需要在 [物料管理](/site/docs/specs/material-spec) 页面导入我们需要进行在线物料描述配置的物料。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434800993-0fbf5ed5-63e5-492b-85ab-feafd663ad2d.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=196&id=u918deb34&margin=%5Bobject%20Object%5D&name=image.png&originHeight=342&originWidth=1399&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33102&status=done&style=stroke&taskId=u95c39b84-836c-45f8-aee6-0effc1ccfd1&title=&width=800) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01IyZdZf1L1VWWU3dnp_!!6000000001239-2-tps-1399-342.png)
- 点击列表左上方的 导入已有物料 按钮 - 点击列表左上方的 导入已有物料 按钮
- 在弹框中输入 npm包名 - 在弹框中输入 npm 包名
- 点击 获取包信息 按钮获取npm包基本信息 - 点击 获取包信息 按钮,获取 npm 包基本信息
- 点击确定,导入成功 - 点击确定,导入成功
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801003-7bd783f0-8804-445e-b508-8601501dfa60.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u825d698a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=315&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=21969&status=done&style=stroke&taskId=ued992c2e-822b-4c32-81b5-9c9add84954&title=) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN019FwWgs1kqgAXq5UNJ_!!6000000004735-2-tps-640-315.png)
## 配置管理 ## 配置管理
第二步:物料导入以后,我们就可以为导入的物料新增[物料描述配置](https://lowcode-engine.cn/material),点击右侧的组件配置开始配置。 第二步:物料导入以后,我们就可以为导入的物料新增[物料描述配置](/site/docs/specs/material-spec),点击右侧的组件配置开始配置。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801125-979e6348-b78a-47b4-bb2e-fa8f1bb4ff90.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=216&id=u7fb954eb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=261&originWidth=965&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15305&status=done&style=stroke&taskId=uc1e18ffd-fe76-4fe4-83a4-c907f308b14&title=&width=800) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01kqymdB1nkDQclPk7F_!!6000000005127-2-tps-965-261.png)
### 新增配置 ### 新增配置
- 点击配置管理右上角的 新增配置 - 点击配置管理右上角的 新增配置
- 选择组件的版本号 - 选择组件的版本号
- 填写组件路径,一般和 npm 包的 package.json 里的 main 字段相同 (如果填写错误,后面会渲染不出来) - 填写组件路径,一般和 npm 包的 package.json 里的 main 字段相同(如果填写错误,后面会渲染不出来)
- 描述字段用于给这份配置增加一些备注信息。 - 描述字段用于给这份配置增加一些备注信息。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801095-1957da7f-5d9d-4c17-a762-c576bf0f763f.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=380&id=u9ad0ec47&margin=%5Bobject%20Object%5D&name=image.png&originHeight=418&originWidth=596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=26130&status=done&style=stroke&taskId=u2b592498-195a-4fec-9853-ec5c3b95ef7&title=&width=541.8181700745893) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01i78OhT1cKbVWnXRNu_!!6000000003582-2-tps-596-418.png)
为了降低配置成本,第一次新增配置的时候会自动解析组件代码,生成一份初始化组件物料描述。所以需要等待片刻,用于代码解析。解析完成后,点击配置按钮即可进入在线配置界面。 为了降低配置成本,第一次新增配置的时候会自动解析组件代码,生成一份初始化组件物料描述。所以需要等待片刻,用于代码解析。解析完成后,点击配置按钮即可进入在线配置界面。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801053-1a48b598-e987-4cd5-b657-030d345e0a99.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=193&id=ud384a13d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=232&originWidth=963&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23541&status=done&style=stroke&taskId=ud2efc4d3-6d52-4b77-adbd-14dd5ee4b11&title=&width=800)
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01R24mTl1tJY3oJ5DCi_!!6000000005881-2-tps-963-232.png)
### 组件描述配置 ### 组件描述配置
操作界面如下,接下来讲具体的配置流程 操作界面如下,接下来讲具体的配置流程
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802081-6546d0f5-19da-475e-8dec-93ea324cc4e3.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=522&id=uf73c4753&margin=%5Bobject%20Object%5D&name=image.png&originHeight=938&originWidth=1438&originalType=binary&ratio=1&rotation=0&showTitle=false&size=111984&status=done&style=stroke&taskId=u0ce37d2b-8ca3-48b5-ac67-8fb461d17b5&title=&width=800)
#### 新增组件
如果新增配置的过程中,代码自动解析失败或者解析出来的组件列表不满足开发要求,我们可以点击左侧组件列表插件 新增 按钮,添加新的组件,具体的字段描述可以参考提示内容,以 [react-color](https://github.com/casesandberg/react-color) 为例:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802087-eaf4e2f1-2028-4415-b696-9788a6b2d0ed.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=560&id=u4341eb1b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1005&originWidth=1436&originalType=binary&ratio=1&rotation=0&showTitle=false&size=147918&status=done&style=stroke&taskId=ud921b52d-1961-4be9-b4ec-77d6364b213&title=&width=800)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802555-bbd14a55-89a6-42cd-a4b3-76c98febf00c.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=472&id=u06e0b78f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=704&originWidth=1193&originalType=binary&ratio=1&rotation=0&showTitle=false&size=240470&status=done&style=stroke&taskId=u77603c5d-9d14-4379-86d2-deb4deaba50&title=&width=800)
#### 给组件增加物料描述
选中刚刚新增的BlockPicker组件然后给它增加描述
- 打开左侧 Sette r面板 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XjSW9I1u662raRg8E_!!6000000005987-2-tps-1438-938.png)
- 按照组件的属性拖入需要 Setter 类型 如图中组件的width属性拖入数字Setter
- 各种 Setter 的介绍可以参看这篇文档:[https://www.yuque.com/lce/doc/grfylu](https://www.yuque.com/lce/doc/grfylu) #### 新增组件
如果新增配置的过程中,代码自动解析失败或者解析出来的组件列表不满足开发要求,我们可以点击左侧组件列表插件 新增 按钮,添加新的组件,具体的字段描述可以参考提示内容,以 [react-color](https://github.com/casesandberg/react-color) 为例:
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01A9VFfQ1m9kH2Qliz4_!!6000000004912-2-tps-1436-1005.png)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01klci7y1IUPflKpeVB_!!6000000000896-2-tps-1193-704.png)
#### 给组件增加物料描述
选中刚刚新增的 BlockPicker 组件,然后给它增加描述:
- 打开左侧 Setter 面板
- 按照组件的属性拖入需要 Setter 类型(如图中组件的 width 属性,拖入数字 Setter
- 各种 Setter 的介绍可以参看这篇文档:[预置设置器列表](/site/docs/guide/appendix/setters)
- 配置属性的基本信息(如图所示) - 配置属性的基本信息(如图所示)
- 配置完成后点击右上角的保存 - 配置完成后点击右上角的保存
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802458-b0fb8a0e-307e-458c-a9f9-af3d2697024c.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=539&id=udeb647da&margin=%5Bobject%20Object%5D&name=image.png&originHeight=967&originWidth=1434&originalType=binary&ratio=1&rotation=0&showTitle=false&size=158958&status=done&style=stroke&taskId=u2950484f-659b-4643-af5e-75d04f14346&title=&width=800) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01gxLKBp1RaDEMPS54O_!!6000000002127-2-tps-1434-967.png)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802443-cdc533bf-1b08-4c11-b3d2-7cfd7fe0a5dd.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=311&id=uaaaa88fb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=360&originWidth=925&originalType=binary&ratio=1&rotation=0&showTitle=false&size=64587&status=done&style=stroke&taskId=u7139e8ef-eee3-468b-833c-a42d8f3cb56&title=&width=800)
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01uReCQ825yYuwIfj2J_!!6000000007595-2-tps-925-360.png)
#### 高级配置(属性联动) #### 高级配置(属性联动)
举个栗子:如图所示,如果期望 “设置器” 这个配置项的值 “被修改”的时候,下面的 “默认值” 跟着变化。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434803379-009a9783-ec24-4a08-8a46-55ae775ce7ba.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=520&id=u005ad05e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=572&originWidth=371&originalType=binary&ratio=1&rotation=0&showTitle=false&size=96588&status=done&style=stroke&taskId=u97330f9d-6728-4a05-a842-55df114ccee&title=&width=337.27271996253796) 举个栗子:如图所示,如果期望“设置器”这个配置项的值“被修改”的时候,下面的“默认值”跟着变化。
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01bg7X571bpSZdnXTBW_!!6000000003514-2-tps-371-572.png)
如何使用 如何使用
组件的属性配置目前支持3个基本的联动函数
- 显示状态返回true | false如果返回true表示组件配置显示否则配置时不显示 组件的属性配置目前支持 3 个基本的联动函数:
- 获取值当调用该配置节点的getValue方法时触发的方法
- 值变化当调用该配置节点的setValue方法时触发的方法 - 显示状态:返回 true | false如果返回 true表示组件配置显示否则配置时不显示
- 获取值:当调用该配置节点的 getValue 方法时触发的方法
- 值变化:当调用该配置节点的 setValue 方法时触发的方法
![image.png](https://img.alicdn.com/imgextra/i3/O1CN018ZJAJO21q57TdWfjM_!!6000000007035-2-tps-316-142.png)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434803522-85aed489-4e00-4787-a496-54cc73e25bc5.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=129&id=u0a782260&margin=%5Bobject%20Object%5D&name=image.png&originHeight=142&originWidth=316&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29086&status=done&style=stroke&taskId=u95864da5-4ccf-4e4b-b903-1ce26af4f66&title=&width=287.2727210462587)
方法的第一个参数都是当前配置节点的对象,常用到的有以下几个: 方法的第一个参数都是当前配置节点的对象,常用到的有以下几个:
- getValue(): 获取当前节点的值如果当前节点是子节点的话否则为undefined - getValue(): 获取当前节点的值,如果当前节点是子节点的话,否则为 undefined
- setValue(): 设置当前节点的值,如果当前节点是子节点的话 - setValue(): 设置当前节点的值,如果当前节点是子节点的话
- parent: 当前节点的父节点 - parent: 当前节点的父节点
- getPropValue(propName): 父节点获取子节点的属性值propName为子节点的属性名称 - getPropValue(propName): 父节点获取子节点的属性值propName 为子节点的属性名称
- setPropValue(propName, value): 父节点设置子节点的属性值propName为子节点的属性名称, value 为设置的值 - setPropValue(propName, value): 父节点设置子节点的属性值propName 为子节点的属性名称value 为设置的值
- getConfig: 获取当前节点的配置如title、setter等 - getConfig: 获取当前节点的配置,如 title、setter 等
#### 调试物料描述 #### 调试物料描述
点击右上角的预览按钮开始调试我们刚刚配置的属性如果是组件的首次预览会有一段组件构建的过程构建出umd包的过程构建完成后就可以调试我们的配置了。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804408-717e49bd-26b3-4a28-b3e5-bd1d67cdab00.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=209&id=ucf92cc3e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=373&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46363&status=done&style=stroke&taskId=u501edca5-bbef-4fde-b341-b42c28b125a&title=&width=800) 点击右上角的预览按钮,开始调试我们刚刚配置的属性,如果是组件的首次预览,会有一段组件构建的过程(构建出 umd 包的过程),构建完成后就可以调试我们的配置了。
![image.png](https://img.alicdn.com/imgextra/i2/O1CN012biqEn1uGAl650nb2_!!6000000006009-2-tps-1431-373.png)
#### 发布物料描述 #### 发布物料描述
物料描述调试没问题后,就可以到项目中去使用了,使用前需要先发布物料描述 物料描述调试没问题后,就可以到项目中去使用了,使用前需要先发布物料描述
@ -77,24 +101,32 @@ sidebar_position: 3
- 选择需要发布的组件 - 选择需要发布的组件
- 点击确定发布完成 - 点击确定发布完成
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804305-276f03e2-4dd2-41e9-9375-1c3bd0c7092a.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=410&id=uf879e7fd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=734&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=103858&status=done&style=stroke&taskId=udc267585-ffb7-4247-b1f5-b7aca386e10&title=&width=800) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01uwa8RH1QDwM7FN31k_!!6000000001943-2-tps-1431-734.png)
## 资产包构建 ## 资产包构建
第三步:物料描述发布完成后,接下来我们就需要构建出可用的资产包用于低代码应用中。 第三步:物料描述发布完成后,接下来我们就需要构建出可用的资产包用于低代码应用中。
#### 资产包构建 #### 资产包构建
- 选择需要构建的组件 - 选择需要构建的组件
- 点击构建资产包按钮 - 点击构建资产包按钮
- 选择刚刚的物料描述配置 - 选择刚刚的物料描述配置
- 开始构建构建完成后你将得到一份json文件里面包含了物料描述和umd包就可以到项目中使用了 - 开始构建,构建完成后你将得到一份 json 文件(里面包含了物料描述和 umd 包),就可以到项目中使用了
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Oc73aw1TH5vlJx9oj_!!6000000002356-2-tps-1431-770.png)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804769-6f6f60f1-9ee3-4561-972d-610f0616576e.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=430&id=ue119fa2b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=770&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=93492&status=done&style=stroke&taskId=ubfd97421-964b-4823-adc8-b056a588924&title=&width=800)
#### 资产包使用 #### 资产包使用
**方式一、在 **[**lowcode-demo**](https://github.com/alibaba/lowcode-demo)**中直接引用可直接替换demo中原来的资产包文件**
例如在basic-fusion demo中直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/basic-fusion/assets.json),即可快速使用自己的物料了。 **方式一、在 **[**lowcode-demo**](https://github.com/alibaba/lowcode-demo)**中直接引用,可直接替换 demo 中原来的资产包文件:**
例如,在 basic-fusion demo 中,直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json),即可快速使用自己的物料了。
**方式二、将新的资产包内容和现有的资产包内容融合:** **方式二、将新的资产包内容和现有的资产包内容融合:**
将上面构建完成的资产包与你项目中的[assets.json文件](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/basic-fusion/assets.json)合并主要合并packages 和 components
- packages中是构建好的umd包 将上面构建完成的资产包与你项目中的[assets.json 文件](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json)合并,主要合并 packages 和 components。
- components中是上面配置好的[物料描述](https://lowcode-engine.cn/material),你也可以在基础上二次加工
![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804944-860abc0c-057c-46d5-a6e5-8d33fde8a762.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=676&id=u5499b1c9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=744&originWidth=1140&originalType=binary&ratio=1&rotation=0&showTitle=false&size=116233&status=done&style=stroke&taskId=u7be27934-77ce-4dd7-a406-1d402acef2c&title=&width=1036.36361390106) - packages 中是构建好的 umd 包;
- components 中是上面配置好的[物料描述](https://lowcode-engine.cn/material),你也可以在基础上二次加工;
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01m7QkDN1P7hL86mjyH_!!6000000001794-2-tps-1140-744.png)

View File

@ -1,11 +1,13 @@
--- ---
title: 插件扩展-编排扩展 title: 插件扩展 - 编排扩展
sidebar_position: 6 sidebar_position: 6
--- ---
## 场景一:扩展选中节点操作项 ## 场景一:扩展选中节点操作项
### 增加节点操作项 ### 增加节点操作项
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647693318212-173890bc-b0b5-437b-9802-4b1fd9f74c5a.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=254&id=u55228975&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=1240&originalType=binary&ratio=1&rotation=0&showTitle=false&size=38144&status=done&style=none&taskId=u426cac9f-24ad-4d06-adbe-faca1896eaa&title=&width=1080) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01J7PrJc1S86XNDBIFQ_!!6000000002201-2-tps-1240-292.png)
选中节点后,在选中框的右上角有操作按钮,编排模块默认实现了查看组件直系父节点、复制节点和删除节点按钮外,还可以通过相关 API 来扩展更多操作,如下代码: 选中节点后,在选中框的右上角有操作按钮,编排模块默认实现了查看组件直系父节点、复制节点和删除节点按钮外,还可以通过相关 API 来扩展更多操作,如下代码:
```typescript ```typescript
import { plugins } from '@alilc/lowcode-engine'; import { plugins } from '@alilc/lowcode-engine';
import { Icon, Message } from '@alifd/next'; import { Icon, Message } from '@alifd/next';
@ -30,14 +32,18 @@ const addHelloAction = (ctx: ILowCodePluginContext) => {
}); });
} }
}; };
} };
addHelloAction.pluginName = 'addHelloAction'; addHelloAction.pluginName = 'addHelloAction';
await plugins.register(addHelloAction); await plugins.register(addHelloAction);
``` ```
**_效果如下_** **_效果如下_**
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647694920149-b8d9a534-b943-45d2-b67e-cc42b906f827.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=282&id=ua20a09c8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=343&originWidth=1315&originalType=binary&ratio=1&rotation=0&showTitle=false&size=35131&status=done&style=none&taskId=u3f47b55d-15ff-495c-8615-31e3ccb0222&title=&width=1080)
具体 API 参考:[https://www.yuque.com/lce/doc/mu7lml#ieJzi](https://www.yuque.com/lce/doc/mu7lml#ieJzi) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01O8W2H61ybw2b7K5nV_!!6000000006598-2-tps-1315-343.png)
具体 API 参考:[API 文档](/site/docs/api/material#addbuiltincomponentaction)
### 删除节点操作项 ### 删除节点操作项
```typescript ```typescript
import { plugins } from '@alilc/lowcode-engine'; import { plugins } from '@alilc/lowcode-engine';
@ -48,22 +54,26 @@ const removeCopyAction = (ctx: ILowCodePluginContext) => {
removeBuiltinComponentAction('copy'); removeBuiltinComponentAction('copy');
} }
} }
} };
removeCopyAction.pluginName = 'removeCopyAction'; removeCopyAction.pluginName = 'removeCopyAction';
await plugins.register(removeCopyAction); await plugins.register(removeCopyAction);
``` ```
**_效果如下_** **_效果如下_**
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647695353667-e22bef51-3c6a-4b6a-87d2-c144ddb68115.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=237&id=ufa1f9434&margin=%5Bobject%20Object%5D&name=image.png&originHeight=290&originWidth=1319&originalType=binary&ratio=1&rotation=0&showTitle=false&size=22495&status=done&style=none&taskId=u73e01acc-96e8-45e7-9d42-a31edca193e&title=&width=1080)
具体 API 参考:[https://www.yuque.com/lce/doc/mu7lml#va9mb](https://www.yuque.com/lce/doc/mu7lml#va9mb) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Gfnu8J1O7PTRdoFQZ_!!6000000001658-2-tps-1319-290.png)
具体 API 参考:[API 文档](/site/docs/api/material#removebuiltincomponentaction)
## 实际案例 ## 实际案例
### 区块管理 ### 区块管理
- 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) - 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins)
- 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block) - 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block)
- 直播回放: - 直播回放:
- [低代码引擎项目实战(9)-区块管理(1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) - [低代码引擎项目实战 (9)-区块管理 (1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/)
- [低代码引擎项目实战(10)-区块管理-区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) - [低代码引擎项目实战 (10)-区块管理 - 区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/)
- [阿里巴巴低代码引擎项目实战(11)-区块管理- ICON优化](https://www.bilibili.com/video/BV1zr4y1H7Km/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - ICON 优化](https://www.bilibili.com/video/BV1zr4y1H7Km/)
- [阿里巴巴低代码引擎项目实战(11)-区块管理-自动截图](https://www.bilibili.com/video/BV1GZ4y117VH/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 自动截图](https://www.bilibili.com/video/BV1GZ4y117VH/)
- [阿里巴巴低代码引擎项目实战(11)-区块管理-样式优化](https://www.bilibili.com/video/BV1Pi4y1S7ZT/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 样式优化](https://www.bilibili.com/video/BV1Pi4y1S7ZT/)
- [阿里低代码引擎项目实战(12)-区块管理(完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/) - [阿里低代码引擎项目实战 (12)-区块管理 (完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/)

View File

@ -1,16 +1,21 @@
--- ---
title: 插件扩展-面板扩展 title: 插件扩展 - 面板扩展
sidebar_position: 5 sidebar_position: 5
--- ---
## 插件简述 ## 插件简述
插件功能赋予低代码引擎更高的灵活性,低代码引擎的生态提供了一些官方的插件,但是无法满足所有人的需求,所以提供了强大的插件定制功能。 插件功能赋予低代码引擎更高的灵活性,低代码引擎的生态提供了一些官方的插件,但是无法满足所有人的需求,所以提供了强大的插件定制功能。
通过定制插件,在和低代码引擎解耦的基础上,我们可以和引擎核心模块进行交互,从而满足多样化的功能。不仅可以自定义插件的 UI还可以实现一些非 UI 的逻辑: 通过定制插件,在和低代码引擎解耦的基础上,我们可以和引擎核心模块进行交互,从而满足多样化的功能。不仅可以自定义插件的 UI还可以实现一些非 UI 的逻辑:
1调用编辑器框架提供的 API 进行编辑器操作或者 schema 操作;
2通过插件类的生命周期函数实现一些插件初始化的逻辑 1. 调用编辑器框架提供的 API 进行编辑器操作或者 schema 操作;
3通过实现监听编辑器内的消息实现特定的切片逻辑例如面板打开、面板关闭等 2. 通过插件类的生命周期函数实现一些插件初始化的逻辑;
> 本文仅介绍面板层面的扩展,编辑器插件层面的扩展可以参考 "插件扩展 - 编排扩展" 章节。 3. 通过实现监听编辑器内的消息实现特定的切片逻辑(例如面板打开、面板关闭等);
> 本文仅介绍面板层面的扩展,编辑器插件层面的扩展可以参考 ["插件扩展 - 编排扩展"](./pluginContextMenu.md) 章节。
## 注册插件 API ## 注册插件 API
```typescript ```typescript
import { plugins, ILowCodePluginContext } from '@alilc/lowcode-engine'; import { plugins, ILowCodePluginContext } from '@alilc/lowcode-engine';
@ -38,42 +43,67 @@ pluginA.pluginName = 'pluginA';
plugins.register(pluginA, { key: 'test' }); plugins.register(pluginA, { key: 'test' });
``` ```
> 如果您想了解抽取出来的插件如何封装成为一个 npm 包并提供给社区,可以参考“扩展低代码应用 - 扩展低代码编辑器 - 低代码插件脚手架”章节。
插件系统的详细设计,可参考“参与低代码引擎开发 - 低代码引擎设计文档 - 插件”章节。 > 如果您想了解抽取出来的插件如何封装成为一个 npm 包并提供给社区,可以参考[“低代码生态脚手架 & 调试机制”](./cli)章节。
## 面板插件配置说明 ## 面板插件配置说明
面板插件是作用于设计器的,主要是通过按钮、图标等展示在设计器的骨架中。设计器的骨架我们分为下面的几个区域,而我们的插件大多数都是作用于这几个区域的。 面板插件是作用于设计器的,主要是通过按钮、图标等展示在设计器的骨架中。设计器的骨架我们分为下面的几个区域,而我们的插件大多数都是作用于这几个区域的。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644393006009-165e36cd-fa7b-4ee0-b3e3-dc7ba9d80d55.png#averageHue=%237cac76&clientId=u45843f36-7f71-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=608&id=u9e018f89&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=149463&status=done&style=stroke&taskId=u74f952e4-c783-47ae-b11c-be48d3c52be&title=&width=1080)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320581783-b8fcd29c-45c2-48df-be2c-7101b12474e3.png#averageHue=%23edf6d4&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=580&id=ixlrN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=3068&originalType=binary&ratio=1&rotation=0&showTitle=false&size=165621&status=done&style=stroke&taskId=u030d9faf-015f-4475-b34a-ba1fbf8868b&title=&width=1080) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Bkfm9E1MQWmBWeIOh_!!6000000001429-2-tps-1920-1080.png)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01y05ZHC1Gix0p4nXxH_!!6000000000657-2-tps-3068-1648.png)
### 展示区域 area ### 展示区域 area
#### topArea #### topArea
展示在设计器的顶部区域,常见的相关区域的插件主要是:
1注册设计器 Logo 展示在设计器的顶部区域,常见的相关区域的插件主要是:、
2设计器操作回退和撤销按钮
3全局操作按钮例如保存、预览等 1. 注册设计器 Logo
2. 设计器操作回退和撤销按钮;
3. 全局操作按钮,例如:保存、预览等;
#### leftArea #### leftArea
左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。 左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。
该区域相关插件的主要有: 该区域相关插件的主要有:
1大纲树展示展示该设计器设计页面的大纲。
2组件库展示注册到设计器中的组件点击之后可以从组件库面板中拖拽到设计器的画布中。 1. 大纲树展示,展示该设计器设计页面的大纲。
3数据源面板 2. 组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。
4JS 等代码面板。 3. 数据源面板
4. JS 等代码面板。
可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。 可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。
#### centerArea #### centerArea
画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有: 画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有:
1画布大小修改
2物料选中扩展区域修改 1. 画布大小修改
2. 物料选中扩展区域修改
#### rightArea #### rightArea
右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。
#### toolbar #### toolbar
跟 topArea 类似,按需放置面板插件~ 跟 topArea 类似,按需放置面板插件~
### 展示形式 type ### 展示形式 type
#### PanelDock #### PanelDock
PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。 PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。
下图是组件库插件的展示效果。 下图是组件库插件的展示效果。
![Feb-08-2022 19-44-15.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644320663827-ee9c54a1-f684-40e2-8a6b-875103d04b31.gif#averageHue=%23eaf6d2&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=555&id=u5292d9cc&margin=%5Bobject%20Object%5D&name=Feb-08-2022%2019-44-15.gif&originHeight=790&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1381641&status=done&style=stroke&taskId=ub28a13a4-3d80-4a02-bcaa-cc9d6127243&title=&width=1080)
![Feb-08-2022 19-44-15.gif](https://img.alicdn.com/imgextra/i3/O1CN01XCrv5Q1hR5BgsyAiq_!!6000000004273-1-tps-1536-790.gif)
其中右上角可以进行固定,可以对弹出的宽度做设定 其中右上角可以进行固定,可以对弹出的宽度做设定
接入可以参考代码 接入可以参考代码
```javascript ```javascript
import { skeleton } from "@alilc/lowcode-engine"; import { skeleton } from "@alilc/lowcode-engine";
@ -85,7 +115,7 @@ skeleton.add({
props: { props: {
align: "left", align: "left",
icon: "wenjian", icon: "wenjian",
description: "JS面板", description: "JS 面板",
}, },
panelProps: { panelProps: {
floatable: true, // 是否可浮动 floatable: true, // 是否可浮动
@ -93,15 +123,20 @@ skeleton.add({
hideTitleBar: false, hideTitleBar: false,
maxHeight: 800, maxHeight: 800,
maxWidth: 1200, maxWidth: 1200,
title: "JS面板", title: "JS 面板",
width: 600, width: 600,
}, },
}); });
``` ```
#### Widget #### Widget
Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。 Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320068765-47efc836-30c2-452f-8104-b98b1ea3533d.png#averageHue=%23fefefb&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=51&id=u68c58cad&margin=%5Bobject%20Object%5D&name=image.png&originHeight=94&originWidth=1988&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58410&status=done&style=stroke&taskId=u4eadd643-2e63-4be7-8736-b27b9c82b81&title=&width=1080)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01h89p5W1pfknnzwMqS_!!6000000005388-2-tps-1988-94.png)
接入可以参考代码: 接入可以参考代码:
```javascript ```javascript
import {skeleton} from "@alilc/lowcode-engine"; import {skeleton} from "@alilc/lowcode-engine";
// 注册 logo 面板 // 注册 logo 面板
@ -110,7 +145,7 @@ skeleton.add({
type: "Widget", type: "Widget",
name: "logo", name: "logo",
content: Logo, // Widget 组件实例 content: Logo, // Widget 组件实例
contentProps: { // Widget 插件props contentProps: { // Widget 插件 props
logo: logo:
"https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png", "https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png",
href: "/", href: "/",
@ -121,21 +156,24 @@ skeleton.add({
}, },
}); });
``` ```
#### Dock #### Dock
一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景
一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景。
```javascript ```javascript
import { skeleton } from "@alilc/lowcode-engine"; import { skeleton } from "@alilc/lowcode-engine";
skeleton.add({ skeleton.add({
area: "leftArea", area: 'leftArea',
type: "Dock", type: 'Dock',
name: "opener", name: 'opener',
content: Opener, // Widget 组件实例 content: Opener, // Widget 组件实例
contentProps: { // Widget 插件props contentProps: { // Widget 插件 props
xxx: "1", xxx: '1',
}, },
props: { props: {
align: "bottom", align: 'bottom',
}, },
onClick: function() { onClick: function() {
// 打开外部链接 // 打开外部链接
@ -145,26 +183,31 @@ skeleton.add({
} }
}); });
``` ```
#### Panel #### Panel
一般不建议单独使用,通过 PanelDock 使用~ 一般不建议单独使用,通过 PanelDock 使用~
## 实际案例 ## 实际案例
### 页面管理面板 ### 页面管理面板
- 仓库地址:[https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) - 仓库地址:[https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal)
- 具体代码:[https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx](https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx) - 具体代码:[https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx](https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx)
- 直播回放: - 直播回放:
- [低代码引擎项目实战(4)-自定义插件-页面管理](https://www.bilibili.com/video/BV17a411i73f/) - [低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/)
- [低代码引擎项目实战(4)-自定义插件-页面管理-后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) - [低代码引擎项目实战 (4)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/)
- [低代码引擎项目实战(4)-自定义插件-页面管理-前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) - [低代码引擎项目实战 (4)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/)
- [低代码引擎项目实战(4)-自定义插件-页面管理-完结](https://www.bilibili.com/video/BV13Y4y1e7EV/) - [低代码引擎项目实战 (4)-自定义插件 - 页面管理 - 完结](https://www.bilibili.com/video/BV13Y4y1e7EV/)
### 区块面板 ### 区块面板
- 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) - 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins)
- 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block) - 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block)
- 直播回放: - 直播回放:
- [低代码引擎项目实战(9)-区块管理(1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) - [低代码引擎项目实战 (9)-区块管理 (1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/)
- [低代码引擎项目实战(10)-区块管理-区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) - [低代码引擎项目实战 (10)-区块管理 - 区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/)
- [阿里巴巴低代码引擎项目实战(11)-区块管理- ICON优化](https://www.bilibili.com/video/BV1zr4y1H7Km/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - ICON 优化](https://www.bilibili.com/video/BV1zr4y1H7Km/)
- [阿里巴巴低代码引擎项目实战(11)-区块管理-自动截图](https://www.bilibili.com/video/BV1GZ4y117VH/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 自动截图](https://www.bilibili.com/video/BV1GZ4y117VH/)
- [阿里巴巴低代码引擎项目实战(11)-区块管理-样式优化](https://www.bilibili.com/video/BV1Pi4y1S7ZT/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 样式优化](https://www.bilibili.com/video/BV1Pi4y1S7ZT/)
- [阿里低代码引擎项目实战(12)-区块管理(完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/) - [阿里低代码引擎项目实战 (12)-区块管理 (完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/)

View File

@ -3,24 +3,37 @@ title: 设置器扩展
sidebar_position: 4 sidebar_position: 4
--- ---
## 设置器简述 ## 设置器简述
设置器主要用于低代码组件属性值的设置,顾名思义叫"设置器",又称为 Setter。由于组件的属性有各种类型需要有与之对应的设置器支持每一个设置器对应一个值的类型。 设置器主要用于低代码组件属性值的设置,顾名思义叫"设置器",又称为 Setter。由于组件的属性有各种类型需要有与之对应的设置器支持每一个设置器对应一个值的类型。
### 设计器展示位置 ### 设计器展示位置
设置器展示在编辑器的右边区域,如下图: 设置器展示在编辑器的右边区域,如下图:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644387351052-0be9546e-9e46-41ff-bbb4-a1effe650d7f.png#clientId=u39aebc41-90a1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=pi5XH&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1730&originWidth=3836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=947162&status=done&style=stroke&taskId=u4d4deed8-40f5-40a6-b20d-d092c90775c&title=&width=1080)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01F0yBV91jNzkZKLzvJ_!!6000000004537-2-tps-3836-1730.png)
其中包含四类设置器: 其中包含四类设置器:
- 属性:展示该物料常规的属性 - 属性:展示该物料常规的属性
- 样式:展示该物料样式的属性 - 样式:展示该物料样式的属性
- 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件。 - 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件。
- 高级:两个逻辑相关的属性,**条件渲染**和**循环** - 高级:两个逻辑相关的属性,**条件渲染**和**循环**
### 设置器类型 ### 设置器类型
上述区域中是有多项设置器的,对于一个组件来说,每一项配置都对应一个设置器,比如我们的配置是一个文本,我们需要的是文本设置器,我们需要配置的是数字,我们需要的就是数字设置器。 上述区域中是有多项设置器的,对于一个组件来说,每一项配置都对应一个设置器,比如我们的配置是一个文本,我们需要的是文本设置器,我们需要配置的是数字,我们需要的就是数字设置器。
下图中的标题和按钮类型配置就分别是文本设置器和下拉框设置器。 下图中的标题和按钮类型配置就分别是文本设置器和下拉框设置器。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644387350762-7337e729-53e9-4a6c-8da1-8f17260e1347.png#clientId=u39aebc41-90a1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=744&id=ztLvk&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1460&originWidth=2120&originalType=binary&ratio=1&rotation=0&showTitle=false&size=489840&status=done&style=stroke&taskId=u7375a322-b6c8-43f1-a096-07b204656aa&title=&width=1080)
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01uMd1zQ20fiXawR4IU_!!6000000006877-2-tps-2120-1460.png)
我们提供了常用的设置器作为内置设置器,也提供了定制能力帮助大家开发特定需求的设置器。 我们提供了常用的设置器作为内置设置器,也提供了定制能力帮助大家开发特定需求的设置器。
## 为物料配置设置器 ## 为物料配置设置器
我们提供了[常用的设置器](https://www.yuque.com/lce/doc/oc220p?view=doc_embed&from=kb&from=kb&outline=1&title=1)作为内置设置器。
我们提供了[常用的设置器](/site/docs/guide/appendix/setters)作为内置设置器。
我们可以将目标组件的属性值类型值配置到物料资源配置文件中: 我们可以将目标组件的属性值类型值配置到物料资源配置文件中:
```json ```json
{ {
"componentName": "Message", "componentName": "Message",
@ -35,10 +48,15 @@ sidebar_position: 4
} }
} }
``` ```
props 字段是入料模块扫描自动填入的类型,用户可以通过 configure 节点进行配置通过 override 节点对属性的声明重新定义setter 就是注册在引擎中的 setter。 props 字段是入料模块扫描自动填入的类型,用户可以通过 configure 节点进行配置通过 override 节点对属性的声明重新定义setter 就是注册在引擎中的 setter。
为物料配置引擎内置的 setter 时,均可以使用对应 setter 的高级功能,对应功能参考“全部内置设置器”章节下的对应 setter 文章。 为物料配置引擎内置的 setter 时,均可以使用对应 setter 的高级功能,对应功能参考“全部内置设置器”章节下的对应 setter 文章。
**_对高级功能的配置如下_**
例如我们需要在NumberSetter中配置units属性可以在asset.json中声明 ### 对高级功能的配置如下:
例如我们需要在 NumberSetter 中配置 units 属性,可以在 asset.json 中声明。
```json ```json
"configure": { "configure": {
"component": { "component": {
@ -81,27 +99,35 @@ props 字段是入料模块扫描自动填入的类型,用户可以通过 conf
} }
}, },
``` ```
## 自定义设置器 ## 自定义设置器
### 编写 AltStringSetter ### 编写 AltStringSetter
我们编写一个简单的 Setter它的功能如下 我们编写一个简单的 Setter它的功能如下
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644764687180-0121f0c0-d113-4907-a86d-e4f3a04ff221.png#clientId=ucb27c83c-48cf-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=45&id=u32dc8cd0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=90&originWidth=720&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17539&status=done&style=stroke&taskId=u0f886bda-a93e-4b10-ad7e-9ba9a38a3fb&title=&width=360)
**_代码如下_** ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01fQ4GLd1RzrPSdULiw_!!6000000002183-2-tps-720-90.png)
```typescript
**代码如下:**
```tsx
import * as React from "react"; import * as React from "react";
import { Input } from "@alifd/next"; import { Input } from "@alifd/next";
import "./index.scss"; import "./index.scss";
interface AltStringSetterProps { interface AltStringSetterProps {
// 当前值 // 当前值
value: string; value: string;
// 默认值 // 默认值
defaultValue: string; defaultValue: string;
// setter唯一输出 // setter 唯一输出
onChange: (val: string) => void; onChange: (val: string) => void;
// AltStringSetter 特殊配置 // AltStringSetter 特殊配置
placeholder: string; placeholder: string;
} }
export default class AltStringSetter extends React.PureComponent<AltStringSetterProps> { export default class AltStringSetter extends React.PureComponent<AltStringSetterProps> {
// 声明 Setter 的 title
static displayName = 'AltStringSetter';
componentDidMount() { componentDidMount() {
const { onChange, value, defaultValue } = this.props; const { onChange, value, defaultValue } = this.props;
if (value == undefined && defaultValue) { if (value == undefined && defaultValue) {
@ -109,9 +135,6 @@ export default class AltStringSetter extends React.PureComponent<AltStringSetter
} }
} }
// 声明Setter的title
static displayName = 'AltStringSetter';
render() { render() {
const { onChange, value, placeholder } = this.props; const { onChange, value, placeholder } = this.props;
return ( return (
@ -124,15 +147,18 @@ export default class AltStringSetter extends React.PureComponent<AltStringSetter
} }
} }
``` ```
#### setter 和 setter/plugin 之间的联动 #### setter 和 setter/plugin 之间的联动
我们采用 emit 来进行相互之前的通信,首先我们在 A setter 中进行事件注册: 我们采用 emit 来进行相互之前的通信,首先我们在 A setter 中进行事件注册:
```javascript ```javascript
import { event } from '@alilc/lowcode-engine'; import { event } from '@alilc/lowcode-engine';
componentDidMount() { componentDidMount() {
// 这里由于面板上会有多个setter这里我用field.id来标记setter名 // 这里由于面板上会有多个 setter这里我用 field.id 来标记 setter
this.emitEventName = `${SETTER_NAME}-${this.props.field.id}`; this.emitEventName = `${SETTER_NAME}-${this.props.field.id}`;
event.on(`${this.emitEventName}.bindEvent`, this.bindEvent) event.on(`${this.emitEventName}.bindEvent`, this.bindEvent);
} }
bindEvent = (eventName) => { bindEvent = (eventName) => {
@ -140,41 +166,52 @@ bindEvent = (eventName) => {
} }
componentWillUnmount() { componentWillUnmount() {
// setter是以实例为单位的每个setter注销的时候需要把事件也注销掉避免事件池过多 // setter 是以实例为单位的,每个 setter 注销的时候需要把事件也注销掉,避免事件池过多
event.off(`${this.emitEventName}.bindEvent`, this.bindEvent) event.off(`${this.emitEventName}.bindEvent`, this.bindEvent);
} }
``` ```
在 B setter 中触发事件,来完成通信: 在 B setter 中触发事件,来完成通信:
```javascript ```javascript
import { event } from '@alilc/lowcode-engine'; import { event } from '@alilc/lowcode-engine';
bindFunction = () => { bindFunction = () => {
const { field, value } = this.props; const { field, value } = this.props;
// 这里展示的和插件进行通信,事件规则是插件名+方法 // 这里展示的和插件进行通信,事件规则是插件名 + 方法
event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); event.emit('eventBindDialog.openDialog', field.name, this.emitEventName);
} }
``` ```
#### 修改同级 props 的其他属性值 #### 修改同级 props 的其他属性值
setter 本身只影响其中一个 props 的值,如果需要影响其他组件的 props 的值,需要使用 field 的 props setter 本身只影响其中一个 props 的值,如果需要影响其他组件的 props 的值,需要使用 field 的 props
```json
```javascript
bindFunction = () => { bindFunction = () => {
const { field, value } = this.props; const { field, value } = this.props;
const propsField = field.parent; const propsField = field.parent;
// 获取同级其他属性showJump的值 // 获取同级其他属性 showJump 的值
const otherValue = propsField.getPropValue('showJump'); const otherValue = propsField.getPropValue('showJump');
// set同级其他属性showJump的值 // set 同级其他属性 showJump 的值
propsField.setPropValue('showJump', false); propsField.setPropValue('showJump', false);
} }
``` ```
### 注册 AltStringSetter ### 注册 AltStringSetter
我们需要在低代码引擎中注册 Setter这样就可以通过 AltStringSetter 的名字在物料中使用了。 我们需要在低代码引擎中注册 Setter这样就可以通过 AltStringSetter 的名字在物料中使用了。
```typescript ```typescript
import AltStringSetter from './AltStringSetter'; import AltStringSetter from './AltStringSetter';
const registerSetter = window.AliLowCodeEngine.setters.registerSetter; const registerSetter = window.AliLowCodeEngine.setters.registerSetter;
registerSetter('AltStringSetter', AltStringSetter); registerSetter('AltStringSetter', AltStringSetter);
``` ```
### 物料中使用 ### 物料中使用
我们需要将目标组件的属性值类型值配置到物料资源配置文件中,其中核心配置如下: 我们需要将目标组件的属性值类型值配置到物料资源配置文件中,其中核心配置如下:
```json ```json
{ {
"props": [ "props": [
@ -185,7 +222,9 @@ registerSetter('AltStringSetter', AltStringSetter);
] ]
} }
``` ```
在物料中的相关配置如下: 在物料中的相关配置如下:
```json ```json
{ {
"componentName": "Message", "componentName": "Message",
@ -199,4 +238,4 @@ registerSetter('AltStringSetter', AltStringSetter);
] ]
} }
} }
``` ```

View File

@ -5,9 +5,9 @@ sidebar_position: 0
## 扩展点简述 ## 扩展点简述
我们可以从 Demo 的项目中看到页面中有很多的区块: 我们可以从 Demo 的项目中看到页面中有很多的区块:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447049972-e324320a-7f97-4e48-bef3-a4c5d2b06517.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=rGr7U&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=518455&status=done&style=none&taskId=u872d1136-0f18-41b3-900d-710e9fc9eea&title=&width=1920) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01WkdvNi1TamxZblYFA_!!6000000002399-2-tps-3840-2160.png)
这些功能点背后都是可扩展项目,如下图所示: 这些功能点背后都是可扩展项目,如下图所示:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447052089-8e340da7-3c2c-4a88-9ed8-c89516dccf75.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=957&id=lL1sN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=none&taskId=u43e8a14e-0d52-4a22-bd19-e5083814daf&title=&width=1919) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01wZLOzm24hmnMTwXdF_!!6000000007423-2-tps-3838-1914.png)
- 插件定制:可以配置低代码编辑器的功能和面板 - 插件定制:可以配置低代码编辑器的功能和面板
- 物料定制:可以配置能够拖入的物料 - 物料定制:可以配置能够拖入的物料
@ -16,7 +16,7 @@ sidebar_position: 0
我们从可扩展项目的视角,可以把低代码引擎架构理解为下图: 我们从可扩展项目的视角,可以把低代码引擎架构理解为下图:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447051959-7abb91ea-44af-46e0-b73a-dd2127648b32.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=M07o7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=779021&status=done&style=none&taskId=u640e4616-d38d-45fb-a560-e4a98cd1605&title=&width=1920) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01fhZ3Q11hwE7RwSq7g_!!6000000004341-2-tps-3840-2160.png)
(注:引擎内核中大量数据交互的细节被简化,这张图仅仅强调编辑器和外部扩展的交互) (注:引擎内核中大量数据交互的细节被简化,这张图仅仅强调编辑器和外部扩展的交互)
## 配置扩展点 ## 配置扩展点
@ -24,17 +24,17 @@ sidebar_position: 0
### 配置物料 ### 配置物料
通过配置注入物料,这里的配置是物料中心根据物料资产包协议生成的,后面“物料扩展”章节会有详细说明。 通过配置注入物料,这里的配置是物料中心根据物料资产包协议生成的,后面“物料扩展”章节会有详细说明。
```typescript ```typescript
import { material } from '@alilc/lowcode-engine' import { material } from '@alilc/lowcode-engine';
// 假设您已把物料配置在本地 // 假设您已把物料配置在本地
import assets from './assets.json' import assets from './assets.json';
// 静态加载 assets // 静态加载 assets
material.setAssets(assets) material.setAssets(assets);
``` ```
也可以通过异步加载物料中心上的物料。 也可以通过异步加载物料中心上的物料。
```typescript ```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine' import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine';
// 动态加载 assets // 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => { plugins.register((ctx: ILowCodePluginContext) => {
@ -51,27 +51,27 @@ plugins.register((ctx: ILowCodePluginContext) => {
} }
}, },
} }
}).catch(err => console.error(err)) }).catch(err => console.error(err));
``` ```
### 配置插件 ### 配置插件
可以通过 npm 包的方式引入社区插件,配置如下所示: 可以通过 npm 包的方式引入社区插件,配置如下所示:
```typescript ```typescript
import { ILowCodePluginContext, plugins } from '@alilc/lowcode-engine' import { ILowCodePluginContext, plugins } from '@alilc/lowcode-engine';
import PluginIssueTracker from '@alilc/lowcode-plugin-issue-tracker' import PluginIssueTracker from '@alilc/lowcode-plugin-issue-tracker';
// 注册一个提 issue 组件到您的编辑器中,方位默认在左栏下侧 // 注册一个提 issue 组件到您的编辑器中,方位默认在左栏下侧
plugins.register(PluginIssueTracker) plugins.register(PluginIssueTracker)
.catch(err => console.error(err)) .catch(err => console.error(err));
``` ```
后续“插件扩展”章节会详细说明。 后续“插件扩展”章节会详细说明。
### 配置设置器 ### 配置设置器
低代码引擎默认内置了设置器(详见“配置设置器”章节)。您可以通过 npm 包的方式引入自定义的设置器,配置如下所示: 低代码引擎默认内置了设置器(详见“配置设置器”章节)。您可以通过 npm 包的方式引入自定义的设置器,配置如下所示:
```typescript ```typescript
import { setters } from '@alilc/lowcode-engine' import { setters } from '@alilc/lowcode-engine';
// 假设您自定义了一个 setter // 假设您自定义了一个 setter
import MuxMonacoEditorSetter from './components/setters/MuxMonacoEditorSetter' import MuxMonacoEditorSetter from './components/setters/MuxMonacoEditorSetter';
// 注册设置器 // 注册设置器
setters.registerSetter({ setters.registerSetter({
@ -83,8 +83,8 @@ setters.registerSetter({
return typeof v === 'string' return typeof v === 'string'
}, },
}, },
}) });
``` ```
后续“设置器扩展”章节会详细说明。 后续“设置器扩展”章节会详细说明。
> 本章节所有可扩展配置内容在 demo 中均可找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/universal/plugin.tsx](https://github.com/alibaba/lowcode-demo/blob/main/src/universal/plugin.tsx) > 本章节所有可扩展配置内容在 demo 中均可找到:[https://github.com/alibaba/lowcode-demo/tree/main/demo-general](https://github.com/alibaba/lowcode-demo/tree/main/demo-general)

View File

@ -29,8 +29,8 @@ sidebar_position: 1
### 2) 通过设计器插件快速体验 ### 2) 通过设计器插件快速体验
1. 安装依赖: `npm install --save @alilc/lowcode-plugin-code-generator` 1. 安装依赖 `npm install --save @alilc/lowcode-plugin-code-generator`
2. 注册插件: 2. 注册插件
```typescript ```typescript
import { plugins } from '@alilc/lowcode-engine'; import { plugins } from '@alilc/lowcode-engine';
@ -49,14 +49,14 @@ await plugins.register(CodeGenPlugin, { disableCodeGenActionBtn: true });
此代码生成器一开始就是为服务端出码设计的,你可以直接这样来在 node.js 环境中使用: 此代码生成器一开始就是为服务端出码设计的,你可以直接这样来在 node.js 环境中使用:
1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` 1. 安装依赖 `npm install --save @alilc/lowcode-code-generator`
2. 引入代码生成器: 2. 引入代码生成器
```javascript ```javascript
import CodeGenerator from '@alilc/lowcode-code-generator'; import CodeGenerator from '@alilc/lowcode-code-generator';
``` ```
3. 创建项目构建器: 3. 创建项目构建器
```javascript ```javascript
const projectBuilder = CodeGenerator.solutions.icejs(); const projectBuilder = CodeGenerator.solutions.icejs();
@ -70,7 +70,7 @@ const project = await projectBuilder.generateProject(
); );
``` ```
5. 将生成的代码写入到磁盘中(也可以生成一个 zip 包) 5. 将生成的代码写入到磁盘中 (也可以生成一个 zip 包)
```javascript ```javascript
// 写入磁盘 // 写入磁盘
@ -94,17 +94,17 @@ await CodeGenerator.publishers.zip().publish({
随着现在电脑性能和浏览器技术的发展,出码其实已经不必非得在服务端做了,借助于 Web Worker 特性,可以在浏览器中进行出码: 随着现在电脑性能和浏览器技术的发展,出码其实已经不必非得在服务端做了,借助于 Web Worker 特性,可以在浏览器中进行出码:
1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` 1. 安装依赖 `npm install --save @alilc/lowcode-code-generator`
2. 引入代码生成器: 2. 引入代码生成器
```javascript ```javascript
import * as CodeGenerator from '@alilc/lowcode-code-generator/standalone-loader'; import * as CodeGenerator from '@alilc/lowcode-code-generator/standalone-loader';
``` ```
3. 【可选】提前初始化代码生成器: 3. 【可选】提前初始化代码生成器
```javascript ```javascript
// 提前初始化下,这样后面用的时候更快(这个 init 内部会提前准备好创建 worker 的一些资源) // 提前初始化下,这样后面用的时候更快 (这个 init 内部会提前准备好创建 worker 的一些资源)
await CodeGenerator.init(); await CodeGenerator.init();
``` ```
@ -116,7 +116,7 @@ const result = await CodeGenerator.generateCode({
schema, // 编排搭建出来的 schema schema, // 编排搭建出来的 schema
}); });
console.log(result); // 出码结果(默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果) console.log(result); // 出码结果 (默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果)
``` ```
注:一般来说在浏览器中出码适合做即时预览功能。 注:一般来说在浏览器中出码适合做即时预览功能。
@ -129,4 +129,4 @@ console.log(result); // 出码结果(默认是递归结构描述的,可以传
```shell ```shell
npx @alilc/lowcode-code-generator init-solution <your-solution-name> npx @alilc/lowcode-code-generator init-solution <your-solution-name>
``` ```
里面内置了一个示例的插件(在 `src/plugins/example.ts`中),您可以根据注释引导来完善相关插件,从而组合生成您的专属出码方案(`src/index.ts`)。您所生成的出码方案可以发布成 NPM 包,从而能按上文 1~4 中的使用方案进行使用。 里面内置了一个示例的插件 (在 `src/plugins/example.ts`中),您可以根据注释引导来完善相关插件,从而组合生成您的专属出码方案 (`src/index.ts`)。您所生成的出码方案可以发布成 NPM 包,从而能按上文 1~4 中的使用方案进行使用。

View File

@ -43,7 +43,7 @@ ReactDOM.render((
- rax-renderernpm 包替换为 @alilc/lowcode-rax-renderer - rax-renderernpm 包替换为 @alilc/lowcode-rax-renderer
#### ####
### 项目使用示例 ### 项目使用示例
> 设计器 demo[https://lowcode-engine.cn/demo](https://lowcode-engine.cn/demo) > [设计器 demo](https://lowcode-engine.cn/demo/demo-general/index.html)
> 项目代码完整示例:[https://github.com/alibaba/lowcode-demo](https://github.com/alibaba/lowcode-demo) > 项目代码完整示例:[https://github.com/alibaba/lowcode-demo](https://github.com/alibaba/lowcode-demo)
**step 1在设计器中获取组件列表** **step 1在设计器中获取组件列表**
@ -310,13 +310,13 @@ designMode 属性主要在搭建场景中使用,主要有以下作用:
### suspended ### suspended
渲染模块是否挂起,当设置为 `true` 时,渲染模块最外层容器的 `shouldComponentUpdate` 将始终返回false在下钻编辑或者多引擎渲染的场景会用到该参数。 渲染模块是否挂起,当设置为 `true` 时,渲染模块最外层容器的 `shouldComponentUpdate`将始终返回 false在下钻编辑或者多引擎渲染的场景会用到该参数。
### onCompGetRef ### onCompGetRef
组件 ref 的回调,在搭建场景下编排模块可以根据该回调获取组件实例并实现生命周期注入或者组件 DOM 操作等功能,回调函数主要包含两个参数: 组件 ref 的回调,在搭建场景下编排模块可以根据该回调获取组件实例并实现生命周期注入或者组件 DOM 操作等功能,回调函数主要包含两个参数:
- `schema` 当前组件的 schema 模型结构 - `schema`:当前组件的 schema 模型结构
- `ref`:当前组件的 ref 实例 - `ref`:当前组件的 ref 实例
### onCompGetCtx ### onCompGetCtx

View File

@ -2,46 +2,55 @@
title: 试用低代码引擎 Demo title: 试用低代码引擎 Demo
sidebar_position: 1 sidebar_position: 1
--- ---
# 访问地址 ## 访问地址
低代码引擎的 Demo 可以通过如下永久链接访问到: 低代码引擎的 Demo 可以通过如下永久链接访问到:
[https://lowcode-engine.cn/demo](https://lowcode-engine.cn/demo) [设计器 demo](https://lowcode-engine.cn/demo/demo-general/index.html)
> 注意我们会经常更新 demo所以您可以通过上述链接得到最新版地址。 > 注意我们会经常更新 demo所以您可以通过上述链接得到最新版地址。
# 低代码引擎 Demo 功能概览 ## 低代码引擎 Demo 功能概览
我们可以从 Demo 的项目中看到页面中有很多的区块:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447049972-e324320a-7f97-4e48-bef3-a4c5d2b06517.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=rGr7U&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=518455&status=done&style=none&taskId=u872d1136-0f18-41b3-900d-710e9fc9eea&title=&width=1920)<br />它主要包含这些功能点:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447051103-de714f27-ec70-4982-b180-e1ebe444b0fe.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=lD0YM&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=616472&status=done&style=none&taskId=u61de17fa-6df0-43c8-9171-96388fda32e&title=&width=1920) 我们可以从 Demo 的项目中看到页面中有很多的区块:
- 顶部:操作区 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01vlxdTD28c4JZcebbf_!!6000000007952-2-tps-3840-2160.png)
- 右侧:撤回和重做、保存到本地、重置页面、预览、异步加载资源
- 左侧:面板与操作区
- 大纲面板:可以调整页面内的组件树结构
- 物料面板:可以查找组件,并在此拖动组件到编辑器画布中
- 源码面板:可以编辑页面级别的 JavaScript 代码和 CSS 配置
- 提交 Issue可以给引擎开发提 bug
- Schema 编辑:可以编辑页面的底层数据
- 中英文切换:可以切换编辑器的语言
- 中部:可视化页面编辑画布区域
- 点击组件在右侧面板中能够显示出对应组件的属性配置选项
- 拖拽修改组件的排列顺序
- 将组件拖拽到容器类型的组件中
- 复制组件:点击组件右上角的复制按钮
- 删除组件:点击组件右上角的 X 或者直接使用 `Delete`
- 右侧:组件级别配置
- 选中的组件:从页面开始一直到当前选中的组件位置,点击对应的名称可以切换到对应的组件上
- 选中组件的配置:当前组件的大类目选项,根据组件类型不同,包含如下子类目:
- 属性:组件的基础属性值设置
- 样式:组件的样式配置
- 事件:绑定组件对外暴露的事件
- 高级:循环、条件渲染与 key 设置
# 深入使用低代码引擎 Demo 它主要包含这些功能点:
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01QITHRY1sQaWzlvJv9_!!6000000005761-2-tps-3840-2160.png)
### 顶部:操作区
- 右侧:撤回和重做、保存到本地、重置页面、预览、异步加载资源
### 左侧:面板与操作区
- 大纲面板:可以调整页面内的组件树结构
- 物料面板:可以查找组件,并在此拖动组件到编辑器画布中
- 源码面板:可以编辑页面级别的 JavaScript 代码和 CSS 配置
- 提交 Issue可以给引擎开发提 bug
- Schema 编辑:可以编辑页面的底层数据
- 中英文切换:可以切换编辑器的语言
### 中部:可视化页面编辑画布区域
- 点击组件在右侧面板中能够显示出对应组件的属性配置选项
- 拖拽修改组件的排列顺序
- 将组件拖拽到容器类型的组件中
- 复制组件:点击组件右上角的复制按钮
- 删除组件:点击组件右上角的 X 或者直接使用 `Delete`
### 右侧:组件级别配置
- 选中的组件:从页面开始一直到当前选中的组件位置,点击对应的名称可以切换到对应的组件上
- 选中组件的配置:当前组件的大类目选项,根据组件类型不同,包含如下子类目:
- 属性:组件的基础属性值设置
- 样式:组件的样式配置
- 事件:绑定组件对外暴露的事件
- 高级:循环、条件渲染与 key 设置
## 深入使用低代码引擎 Demo
我们在低代码引擎 Demo 中直接内置了产品使用文档,对常见场景中的使用进行了向导,它的入口如下: 我们在低代码引擎 Demo 中直接内置了产品使用文档,对常见场景中的使用进行了向导,它的入口如下:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647163471895-a12d0f5d-e09e-462d-bd0b-b633c64afb15.png#clientId=uecc3752b-3539-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=825&id=u86d6fa24&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1650&originWidth=3070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1040703&status=done&style=none&taskId=u54aeddda-78e0-4259-b184-d06e2dba10b&title=&width=1535) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01YU2LYS29YEbuLTtLL_!!6000000008079-2-tps-3070-1650.png)
如果暂时没有看到对应的产品使用文档,可以通过此永久链接直接访问:[https://www.yuque.com/lce/usage](https://www.yuque.com/lce/usage) 如果暂时没有看到对应的产品使用文档,可以通过此永久链接直接访问:[https://lowcode-engine.cn/site/docs/demoUsage/intro](https://lowcode-engine.cn/site/docs/demoUsage/intro)

View File

@ -18,7 +18,7 @@ sidebar_position: 0
- **可视化页面搭建**,通过简单的拖拽完成应用页面开发,对前端技能没有要求或不需要特别专业的了解; - **可视化页面搭建**,通过简单的拖拽完成应用页面开发,对前端技能没有要求或不需要特别专业的了解;
- **可视化模型设计**,与业务相关的数据存储变得更容易理解,甚至大多数简单场景可以做到表单即模型,模型字段的类型更加业务化; - **可视化模型设计**,与业务相关的数据存储变得更容易理解,甚至大多数简单场景可以做到表单即模型,模型字段的类型更加业务化;
- **可视化流程设计**,不管是业务流程还是审批流程,都可以通过简单的点线连接来进行配置; - **可视化流程设计**,不管是业务流程还是审批流程,都可以通过简单的点线连接来进行配置;
- **可视化报表及数据分析**BI数据分析能力成为标配随时随地通过拖拽选择来定义自定义分析报表 - **可视化报表及数据分析**BI 数据分析能力成为标配,随时随地通过拖拽选择来定义自定义分析报表;
- **可视化服务与数据开放、集成**,具备与其他系统互联互通的配置; - **可视化服务与数据开放、集成**,具备与其他系统互联互通的配置;
- **权限、角色设置标准化和业务化**,通过策略规则配置来将数据、操作的权限进行精细化管理; - **权限、角色设置标准化和业务化**,通过策略规则配置来将数据、操作的权限进行精细化管理;
- **无需关心服务器、数据库等底层运维、计算设施设备、网络等等复杂技术概念**,具备安全、性能的统一解决方案,开发者只需要专注于业务本身; - **无需关心服务器、数据库等底层运维、计算设施设备、网络等等复杂技术概念**,具备安全、性能的统一解决方案,开发者只需要专注于业务本身;
@ -35,14 +35,14 @@ sidebar_position: 0
**低代码设计器** **低代码设计器**
现如今低代码平台越来越多,而每一个低代码平台中都会有的一个能力就是搭建和配置页面、模块的页面,这个页面我们称为设计器。例如,下图是中后台低代码平台的设计器。 现如今低代码平台越来越多,而每一个低代码平台中都会有的一个能力就是搭建和配置页面、模块的页面,这个页面我们称为设计器。例如,下图是中后台低代码平台的设计器。
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01LunuQh23b5NtP8k86_!!6000000007273-2-tps-1682-969.png?originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=stroke&taskId=u9a19d4d1-4d87-4b4e-b7cc-3aedfb00aaa&title=&width=1080) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01sXuwkK1j8sg4S53Dx_!!6000000004504-2-tps-1682-969.png)
设计器承载着低代码平台的核心功能,包括入料、编排、组件配置、画布渲染等等。由于其功能多,打磨精细难,也是低代码平台建设最耗时的地方。 设计器承载着低代码平台的核心功能,包括入料、编排、组件配置、画布渲染等等。由于其功能多,打磨精细难,也是低代码平台建设最耗时的地方。
**定制扩展能力** **定制扩展能力**
什么是扩展能力呢,一方面我们可以快速拥有一份标准的低代码设计器,另外一方面如果有业务独特的功能需要,我们可以不用看它的源码、不用关心其实现,可以使用 API、插件等方式快速完成能力的开发。 什么是扩展能力呢,一方面我们可以快速拥有一份标准的低代码设计器,另外一方面如果有业务独特的功能需要,我们可以不用看它的源码、不用关心其实现,可以使用 API、插件等方式快速完成能力的开发。
而低代码引擎对于设计器的扩展能力支持基本上覆盖了低代码设计器的所有功能点。下图是针对标准的设计器提供了扩展功能的区域。 而低代码引擎对于设计器的扩展能力支持基本上覆盖了低代码设计器的所有功能点。下图是针对标准的设计器提供了扩展功能的区域。
![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643446752531-8b1493d4-ea8a-463b-9631-6bb4fc681719.png#clientId=u2b839b63-1827-4&crop=0&crop=0&crop=1&crop=1&from=drop&height=539&id=ucff2881c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=stroke&taskId=u9a19d4d1-4d87-4b4e-b7cc-3aedfb00aaa&title=&width=1080) ![](https://img.alicdn.com/imgextra/i1/O1CN01ZVgAE31wltQ4BVnCe_!!6000000006349-2-tps-3838-1914.png)
**低代码设计器研发框架** **低代码设计器研发框架**
低代码引擎的核心是设计器,通过扩展、周边生态等可以产出各式各样的设计器。它不是一套可以适合所有人的低代码平台,而是帮助低代码平台的开发者,快速生产低代码平台的工具。 低代码引擎的核心是设计器,通过扩展、周边生态等可以产出各式各样的设计器。它不是一套可以适合所有人的低代码平台,而是帮助低代码平台的开发者,快速生产低代码平台的工具。

View File

@ -2,70 +2,83 @@
sidebar_position: 2 sidebar_position: 2
title: 快速开始 title: 快速开始
--- ---
# 前置知识 ## 前置知识
我们假定你已经对 HTML 和 JavaScript 都比较熟悉了。即便你之前使用其他编程语言,你也可以跟上这篇教程的。除此之外,我们假定你也已经熟悉了一些编程的概念,例如,函数、对象、数组,以及 class 的一些内容。<br />如果你想回顾一下 JavaScript你可以阅读[这篇教程](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript)。注意,我们也用到了一些 ES6较新的 JavaScript 版本)的特性。在这篇教程里,我们主要使用了[箭头函数arrow functions](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)、[class](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes)、[let](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let) 语句和 [const](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const) 语句。你可以使用 [Babel REPL](https://babeljs.io/repl/#?presets=react&code_lz=MYewdgzgLgBApgGzgWzmWBeGAeAFgRgD4AJRBEAGhgHcQAnBAEwEJsB6AwgbgChRJY_KAEMAlmDh0YWRiGABXVOgB0AczhQAokiVQAQgE8AkowAUAcjogQUcwEpeAJTjDgUACIB5ALLK6aRklTRBQ0KCohMQk6Bx4gA) 在线预览 ES6 的编译结果。 我们假定你已经对 HTML 和 JavaScript 都比较熟悉了。即便你之前使用其他编程语言,你也可以跟上这篇教程的。除此之外,我们假定你也已经熟悉了一些编程的概念,例如,函数、对象、数组,以及 class 的一些内容。
# 环境准备 如果你想回顾一下 JavaScript你可以阅读[这篇教程](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript)。注意,我们也用到了一些 ES6较新的 JavaScript 版本)的特性。在这篇教程里,我们主要使用了[箭头函数arrow functions](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)、[class](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes)、[let](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let) 语句和 [const](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const) 语句。你可以使用 [Babel REPL](https://babeljs.io/repl/#?presets=react&code_lz=MYewdgzgLgBApgGzgWzmWBeGAeAFgRgD4AJRBEAGhgHcQAnBAEwEJsB6AwgbgChRJY_KAEMAlmDh0YWRiGABXVOgB0AczhQAokiVQAQgE8AkowAUAcjogQUcwEpeAJTjDgUACIB5ALLK6aRklTRBQ0KCohMQk6Bx4gA) 在线预览 ES6 的编译结果。
## WSLWindow 电脑)
## 环境准备
### WSLWindow 电脑)
Window 环境需要使用 WSL 在 windows 下进行低代码引擎相关的开发。安装教程 ➡️ [WSL 安装教程](https://docs.microsoft.com/zh-cn/windows/wsl/install)。<br />**对于 Window 环境来说,之后所有需要执行命令的操作都是在 WSL 终端执行的。** Window 环境需要使用 WSL 在 windows 下进行低代码引擎相关的开发。安装教程 ➡️ [WSL 安装教程](https://docs.microsoft.com/zh-cn/windows/wsl/install)。<br />**对于 Window 环境来说,之后所有需要执行命令的操作都是在 WSL 终端执行的。**
## Node ### Node
node 版本推荐 14.17.0。 node 版本推荐 14.17.0。
### 查看 Node 版本 #### 查看 Node 版本
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660653856191-128d8e3f-9636-4b73-94ab-c03cf6965365.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=35&id=u44a9af04&margin=%5Bobject%20Object%5D&name=image.png&originHeight=70&originWidth=238&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11948&status=done&style=none&taskId=udb616117-a27c-409d-9e1c-1b89931a714&title=&width=119) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01oCZKNz290LIu8YUTk_!!6000000008005-2-tps-238-70.png)
### 变更 node 版本 #### 通过 n 来管理 node 版本
可以安装 [n](https://www.npmjs.com/package/n) 来管理和变更 node 版本。 可以安装 [n](https://www.npmjs.com/package/n) 来管理和变更 node 版本。
#### 安装 ##### 安装 n
```json ```bash
npm install -g n npm install -g n
``` ```
#### 变更 node 版本 ##### 变更 node 版本
```json ```bash
n 14.17.0 n 14.17.0
``` ```
## React ### React
低代码引擎的扩展能力都是基于 React 来研发的,在继续阅读之前最好有一定的 React 基础React 学习教程 ➡️ [React 快速开始教程](https://zh-hans.reactjs.org/docs/getting-started.html)。 低代码引擎的扩展能力都是基于 React 来研发的,在继续阅读之前最好有一定的 React 基础React 学习教程 ➡️ [React 快速开始教程](https://zh-hans.reactjs.org/docs/getting-started.html)。
## 下载 Demo ### 下载 Demo
可以前往 githubhttps://github.com/alibaba/lowcode-demo将 DEMO 下载到本地。 可以前往 githubhttps://github.com/alibaba/lowcode-demo将 DEMO 下载到本地。
### git clone #### git clone
#### HTTPS ##### HTTPS
需要使用到 git 工具 需要使用到 git 工具
```json ```bash
git clone https://github.com/alibaba/lowcode-demo.git git clone https://github.com/alibaba/lowcode-demo.git
``` ```
#### SSH ##### SSH
需要配置 SSH key如果没有配置可以 需要配置 SSH key如果没有配置可以
```json ```bash
git clone git@github.com:alibaba/lowcode-demo.git git clone git@github.com:alibaba/lowcode-demo.git
``` ```
### 下载 Zip 包 #### 下载 Zip 包
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660653725650-ab734ba4-64a7-4801-9d2f-5c496879054f.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=897&id=uc1b07458&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1794&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1306258&status=done&style=stroke&taskId=ubaa4eb12-0e87-464e-b3da-306ed9685b7&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01iYC7E11phaNwLFUrN_!!6000000005392-2-tps-3584-1794.png)
## 安装依赖 ### 选择一个 demo 项目
在 lowcode-demo 目录下执行: 在 以 `demo-general` 为例:
```json ```bash
cd demo-general
```
### 安装依赖
`lowcode-demo/demo-general` 目录下执行:
```bash
npm install npm install
``` ```
## 启动 demo ### 启动 demo
在 lowcode-demo 目录下执行: `lowcode-demo/demo-general` 目录下执行:
```json ```bash
npm run start npm run start
``` ```
之后就可以通过 [http://localhost:5556/](http://localhost:5556/) 来访问我们的 DEMO 了。 之后就可以通过 [http://localhost:5556/](http://localhost:5556/) 来访问我们的 DEMO 了。
# 认识 Demo
我们的 Demo 是一个**低代码平台的设计器**。它是一个低代码平台中最重要的一环,用户可以在这里通过拖拽、配置、写代码等等来完成一个页面的开发。由于用户的人群不同、场景不同、诉求不同等等,这个页面的功能就会有所差异。<br />这里记住**设计器**这个词,它描述的就是下面的这个页面,后面我们会经常看到它。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654189055-45fd0c7e-75cb-4072-a4d4-7cf244405c7d.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.008&crop=1&crop=1&from=paste&height=904&id=LBi2j&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1808&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=763122&status=done&style=stroke&taskId=u82753ad5-3b5d-43b2-b309-a99c2a7bb24&title=&width=1792)
## 场景介绍 ## 认识 Demo
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654738730-490fc94a-8b42-4c48-b21e-4c0694416b07.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=903&id=ub700edc2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=802013&status=done&style=stroke&taskId=u317bff98-636d-402a-98f2-f9e0b08293b&title=&width=1792) 我们的 Demo 是一个**低代码平台的设计器**。它是一个低代码平台中最重要的一环,用户可以在这里通过拖拽、配置、写代码等等来完成一个页面的开发。由于用户的人群不同、场景不同、诉求不同等等,这个页面的功能就会有所差异。
这里记住**设计器**这个词,它描述的就是下面的这个页面,后面我们会经常看到它。
![image.png](https://img.alicdn.com/imgextra/i1/O1CN014nYXgF20pKrQIG2zV_!!6000000006898-2-tps-3584-1808.png)
### 场景介绍
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01nnP60l1dqUhUiNSx6_!!6000000003787-2-tps-2852-1156.png)
Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8 个场景: Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8 个场景:
@ -75,30 +88,39 @@ Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8
- 基础 antd 组件 - 基础 antd 组件
- 自定义初始化引擎 - 自定义初始化引擎
- 扩展节点操作项 - 扩展节点操作项
- 基于next实现的高级表单低代码物料 - 基于 next 实现的高级表单低代码物料
- antd 高级组件 + formily 表单组件 - antd 高级组件 + formily 表单组件
可以点开不同的场景,看看他们使用的物料。 可以点开不同的场景,看看他们使用的物料。
![](https://img.alicdn.com/imgextra/i1/O1CN01EU2jRN1wUwlal17WK_!!6000000006312-2-tps-3110-1974.png)
## 目录介绍 ### 目录介绍
仓库下的 src/scenarios 目录就对应刚刚介绍的场景。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660655237007-fddd8534-d4ed-4a25-ba2f-f335f8ac3c36.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=348&id=ubf68019d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=696&originWidth=696&originalType=binary&ratio=1&rotation=0&showTitle=false&size=148777&status=done&style=stroke&taskId=u68648c51-7648-494e-bd41-4f29fb144f9&title=&width=348) 仓库下每个 demo-xxx-xxx 目录都是一个可独立运行的 demo 工程,分别对应到刚刚介绍的场景。
不同场景的目录结构实际上都是类似的,这里我们主要介绍一下综合场景的目录结构即可。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660655399364-b40d206a-977d-4000-9be1-681823f8a995.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=ub727a7fa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1373541&status=done&style=stroke&taskId=ue55dc86f-375d-4c7f-a63f-d5208683035&title=&width=1792)<br />综合场景目录下只有一个文件,这个文件做了几个事情: ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01ztxv5Y1mJozBsLdni_!!6000000004934-2-tps-696-958.png)
- 通过 plugins.register 注册「切换场景」的插件,也就是上面介绍的切换场景的功能。 不同场景的目录结构实际上都是类似的,这里我们主要介绍一下综合场景的目录结构即可。
- 通过 registerPlugins 注册更多的插件:
- ManualPlugin增加弹出「低代码产品使用文档」按钮
- Inject支持调试功能
- registerRefProp支持给每个组件注入 ref
- ...
- 通过 init 初始化低代码设计器
做了这些事情之后,我们的低代码设计器就已经有了基本的能力了。也就是最开始我们看到的这样。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654189055-45fd0c7e-75cb-4072-a4d4-7cf244405c7d.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.008&crop=1&crop=1&from=paste&height=904&id=MZdfk&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1808&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=763122&status=done&style=stroke&taskId=u82753ad5-3b5d-43b2-b309-a99c2a7bb24&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01A50oW522S5zg2eDUH_!!6000000007118-2-tps-732-1384.png)
介绍下其中主要的内容
- 设计器入口文件 `source/index.ts` 这个文件做了下述几个事情:
- 通过 plugins.register 注册各种插件,包括官方插件 (已发布 npm 包形式的插件) 和 `plugins` 目录下内置的示例插件
- 通过 init 初始化低代码设计器
- plugins 目录,存放的都是示例插件,方便用户从中看到一个插件是如何实现的
- services 目录,模拟数据请求、提供默认 schema、默认资产包等此目录下内容在真是项目中应替换成真是的与服务端交互的服务。
- 预览页面入口文件 `preview.tsx`
剩下的各位看官可以通过源码来进一步了解。
做了这些事情之后,我们的低代码设计器就已经有了基本的能力了。也就是最开始我们看到的这样。
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01YJVcOd1PiL1am6bz2_!!6000000001874-2-tps-3248-1970.png)
接下来我们就根据我们自己的诉求通过对设计器进行扩展,改动成我们需要的设计器功能。 接下来我们就根据我们自己的诉求通过对设计器进行扩展,改动成我们需要的设计器功能。
# 开发一个插件 ## 开发一个插件
## 方式1在 DEMO 中直接新增插件 ### 方式 1在 DEMO 中直接新增插件
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656064139-8da57c37-7e0b-4e8d-9f2d-8ea86d5af134.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=280&id=uc7f75c37&margin=%5Bobject%20Object%5D&name=image.png&originHeight=560&originWidth=820&originalType=binary&ratio=1&rotation=0&showTitle=false&size=125690&status=done&style=stroke&taskId=u53c07118-a2ca-4a77-a27f-3b2b20085ac&title=&width=410) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01pXpSRs1QvRyut2EE3_!!6000000002038-2-tps-718-1144.png)
可以在 demo/sample-plugins 直接新增插件,这里我新增的插件目录是 plugin-demo。并且新增了 index.tsx 文件,将下面的代码粘贴到 index.tsx 中。 可以在 demo/sample-plugins 直接新增插件,这里我新增的插件目录是 plugin-demo。并且新增了 index.tsx 文件,将下面的代码粘贴到 index.tsx 中。
```javascript ```javascript
@ -153,64 +175,94 @@ LowcodePluginPluginDemo.meta = {
export default LowcodePluginPluginDemo; export default LowcodePluginPluginDemo;
``` ```
在 src/scenarios/index/index.ts 中新增下面代码<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656497051-49e08633-2d78-428c-becc-c282905cdb90.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u426edc7b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1458910&status=done&style=stroke&taskId=uf1e42399-caf7-4d82-a797-698fa730486&title=&width=1792) 在 src/index.ts 中新增下面代码
这样在我们的设计器中就新增了一个 Demo 面板。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656566260-86dfed37-60d0-45ca-967e-5df8ea7a34d0.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.0053&crop=1&crop=1&from=paste&height=903&id=u17565cd3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=734227&status=done&style=stroke&taskId=u5dbe00f3-447b-451e-ac48-9b02281afc3&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01pNTr4N1kldoYZRzgI_!!6000000004724-2-tps-1976-1250.png)
## 方式2在新的仓库下开发插件
这样在我们的设计器中就新增了一个 Demo 面板。
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01wtPIOV1TQiFLz5Vkf_!!6000000002377-2-tps-3584-1806.png)
### 方式 2在新的仓库下开发插件
初始化 初始化
```json ```bash
npm init @alilc/element your-plugin-name npm init @alilc/element your-plugin-name
``` ```
选择设计器插件plugin<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702297326-ccfe60f9-ee22-4a24-a293-26351d107663.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=107&id=ub2bf5248&margin=%5Bobject%20Object%5D&name=image.png&originHeight=214&originWidth=730&originalType=binary&ratio=1&rotation=0&showTitle=false&size=82091&status=done&style=stroke&taskId=u82628265-73f0-4d57-b4ba-1b18600a1f0&title=&width=365) 选择设计器插件plugin
根据操作完善信息<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702439529-867a893f-f27a-4e48-8a5a-ee45aa97e355.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=109&id=uc9b09fec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=218&originWidth=866&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102705&status=done&style=stroke&taskId=ue4a95f21-43d3-4da8-9c0e-b21dfe239bf&title=&width=433) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01sA6sYW1tijqVeQCuq_!!6000000005936-2-tps-730-214.png)
插件项目就初始化完成了<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702464438-3d7e07eb-53c7-417c-9e6d-06fdf9acfb86.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=280&id=u0ee65b4e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1197702&status=done&style=stroke&taskId=u5f9fdae3-1adc-4b02-969c-5c43c3d4c9c&title=&width=496) 根据操作完善信息
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01BzM1Jb1RcxbiJ0tJi_!!6000000002133-2-tps-866-218.png)
插件项目就初始化完成了
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01iVIAXD1XVWsOdKttI_!!6000000002929-2-tps-3584-2020.png)
在插件项目下安装依赖 在插件项目下安装依赖
```json ```bash
npm install npm install
``` ```
启动项目 启动项目
```json ```bash
npm run start npm run start
``` ```
调试项目<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660705712773-f2446689-2b5f-42e7-9e85-30857270dfbb.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=346&id=u448649c5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1936&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=757713&status=done&style=stroke&taskId=u0b617456-826e-4993-951e-303da417172&title=&width=641) 调试项目
在 Demo 中调试项目<br />在 build.json 下面新增 "inject": true就可以在 [https://lowcode-engine.cn/demo/index.html?debug](https://lowcode-engine.cn/demo/index.html?debug) 页面下进行调试了。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660705860117-5a11a5fa-9215-4b94-84b7-497899cafe10.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u3a36c42f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=887101&status=done&style=stroke&taskId=u747bc337-5212-4a8b-a88f-127c53ea621&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01A4vPqC1xbeAqNxBRM_!!6000000006462-2-tps-3584-1936.png)
# 开发一个自定义物料
## 初始化物料 在 Demo 中调试项目
```json
在 build.json 下面新增 "inject": true就可以在 [https://lowcode-engine.cn/demo/demo-general/index.html?debug](https://lowcode-engine.cn/demo/demo-general/index.html?debug) 页面下进行调试了。
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01uqSmrX1oqupxeGH1m_!!6000000005277-2-tps-3584-2020.png)
## 开发一个自定义物料
### 初始化物料
```bash
npm init @alilc/element your-material-demo npm init @alilc/element your-material-demo
``` ```
选择组件/物料栏<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706045985-db73ca55-925a-446b-ace4-b59fa1e18469.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=104&id=kuWIf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=208&originWidth=824&originalType=binary&ratio=1&rotation=0&showTitle=false&size=88910&status=done&style=stroke&taskId=u92f5fa65-386a-4f52-a093-bcbbebdc2d7&title=&width=412)
配置其他信息<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706116845-9b3b938f-c132-426b-81bd-d49283ebf9e8.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=124&id=u941c9808&margin=%5Bobject%20Object%5D&name=image.png&originHeight=248&originWidth=800&originalType=binary&ratio=1&rotation=0&showTitle=false&size=111864&status=done&style=stroke&taskId=ue4ff4dab-3a53-4811-bf70-7fa6fc0c8b6&title=&width=400) 选择组件/物料栏
这样我们就初始化好了一个 React 物料。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706173968-3e5db25a-e08d-4852-90c9-ffaa0968fd62.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u854b37cc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1080400&status=done&style=stroke&taskId=u10e21350-23d4-4d8f-8c16-0c5a221fc2e&title=&width=1792) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01qVJQvG1Yhj2PJhhvk_!!6000000003091-2-tps-824-208.png)
## 启动并调试物料
### 安装依赖 配置其他信息
```json
![image.png](https://img.alicdn.com/imgextra/i3/O1CN017fFT8O1IVmrLYg87F_!!6000000000899-2-tps-800-248.png)
这样我们就初始化好了一个 React 物料。
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01SU2xn91TZPlzcARVI_!!6000000002396-2-tps-3584-2020.png)
### 启动并调试物料
#### 安装依赖
```bash
npm i npm i
``` ```
### 启动 #### 启动
```json ```bash
npm run lowcode:dev npm run lowcode:dev
``` ```
我们就可以通过 [http://localhost:3333/](http://localhost:3333/) 看到我们的研发的物料了。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706484894-73798e35-1e58-4ffe-bb3c-bfba7b014433.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=895&id=zVMiy&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1790&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=678753&status=done&style=stroke&taskId=u241f50c0-1a43-4854-8443-7e972f15623&title=&width=1792) 我们就可以通过 [http://localhost:3333/](http://localhost:3333/) 看到我们的研发的物料了。
### 在 Demo 中调试
```json ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01JqoHqc1z7zlSWFYJD_!!6000000006668-2-tps-3584-1790.png)
#### 在 Demo 中调试
```bash
npm i @alilc/build-plugin-alt npm i @alilc/build-plugin-alt
``` ```
修改 build.lowcode.js<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706733149-0170b2fb-88de-40e3-8204-f510d7e42f77.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=311&id=u8a1a8bea&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1046&originWidth=1388&originalType=binary&ratio=1&rotation=0&showTitle=false&size=291155&status=done&style=stroke&taskId=u61ede7d2-f92d-43b9-8582-a2362a9ea14&title=&width=413) 修改 build.lowcode.js
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01K7u7ci1KCfYlBj2yf_!!6000000001128-2-tps-1388-1046.png)
如图,新增如下代码 如图,新增如下代码
```json ```javascript
[ [
'@alilc/build-plugin-alt', '@alilc/build-plugin-alt',
{ {
@ -224,16 +276,18 @@ npm i @alilc/build-plugin-alt
], ],
``` ```
我们重新启动项目,就可以在 Demo 中找到我们的自定义组件。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706823666-ca28a08d-6241-4112-bc78-b9078c81fb75.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=906&id=u31bdc31a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1812&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=788013&status=done&style=stroke&taskId=uaa4789a2-452f-4b04-8894-759989e4568&title=&width=1792) 我们重新启动项目,就可以在 Demo 中找到我们的自定义组件。
## 发布 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN0166WywE26Lv7NuJMus_!!6000000007646-2-tps-3584-1812.png)
### 发布
首先进行构建 首先进行构建
```json ```bash
npm run lowcode:build npm run lowcode:build
``` ```
发布组件 发布组件
```json ```bash
npm publish npm publish
``` ```
@ -243,7 +297,8 @@ npm publish
- 组件代码:[https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js) - 组件代码:[https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js)
我们也可以从 [https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json) 找到我们的资产包描述。 我们也可以从 [https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json) 找到我们的资产包描述。
```json
```bash
{ {
"packages": [ "packages": [
{ {
@ -288,9 +343,18 @@ npm publish
} }
``` ```
## 使用 ### 使用
我们将刚刚发布的组件的 assets-prod.json 的内容放到 demo 的 src/universal/assets.json 中。<br />*最好放到最后,防止因为资源加载顺序问题导致出现报错。<br />如图,新增 packages 配置<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660707789785-ea75a399-6845-45a8-8c53-08402749c9a8.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=uf0f75c17&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1327766&status=done&style=stroke&taskId=ub053d846-69fd-4a55-8e9e-b41d1e06e47&title=&width=1792)<br />如图,新增 components 配置<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660707811725-a0e36f48-910d-45b5-b162-3aa4e2f87e9b.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=uf8c9506f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1222080&status=done&style=stroke&taskId=u10147f1f-27ed-4cec-bfc9-2cb3d61d6a2&title=&width=1792) 我们将刚刚发布的组件的 assets-prod.json 的内容放到 demo 的 src/universal/assets.json 中。
> 最好放到最后,防止因为资源加载顺序问题导致出现报错。
如图,新增 packages 配置
![image.png](https://img.alicdn.com/imgextra/i1/O1CN018dnIB91XHmzeTrq3n_!!6000000002899-2-tps-3584-2020.png)
如图,新增 components 配置
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01UNp89s1vQXKyfsFaL_!!6000000006167-2-tps-3584-2020.png)
这时候再启动 DEMO 项目,就会有新的低代码物料了。接下来就按照你们的需求,继续扩展物料吧。 这时候再启动 DEMO 项目,就会有新的低代码物料了。接下来就按照你们的需求,继续扩展物料吧。
# 总结 ## 总结
这里只是简单的介绍了一些低代码引擎的基础能力,带大家简单的对低代码 DEMO 进行扩展,定制一些新的功能。低代码引擎的能力还有很多很多,可以继续去探索更多的功能。 这里只是简单的介绍了一些低代码引擎的基础能力,带大家简单的对低代码 DEMO 进行扩展,定制一些新的功能。低代码引擎的能力还有很多很多,可以继续去探索更多的功能。

View File

@ -2,7 +2,7 @@
title: 工程化配置 title: 工程化配置
sidebar_position: 3 sidebar_position: 3
--- ---
目前引擎体系共包含 3 个 js 文件,即: 目前引擎体系共包含 2 个 js 文件,即:
```html ```html
<!-- engine-core 引擎的 core负责引擎的基础模块 --> <!-- engine-core 引擎的 core负责引擎的基础模块 -->
<script crossorigin="anonymous" src="//alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js"></script> <script crossorigin="anonymous" src="//alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js"></script>

View File

@ -7,11 +7,19 @@ sidebar_position: 3
### 维护方式 ### 维护方式
- 官方文档通过 github 管理文档源, 官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。 - 官方文档通过 github 管理文档源官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。
- 点击每篇文档下发的 `编辑此页` 可直接定位到 github 中位置。 - 点击每篇文档下发的 `编辑此页` 可直接定位到 github 中位置。
- 欢迎 PR 文档 PR 也会作为贡献者贡献,会用于贡献度统计。 - 欢迎 PR文档 PR 也会作为贡献者贡献,会用于贡献度统计。
- 文档同步到官方网站由官方人员进行操作,如有需要可以通过 issue 或 贡献者群与相关人员沟通。 - 文档同步到官方网站由官方人员进行操作,如有需要可以通过 issue 或 贡献者群与相关人员沟通。
- 为了提供更好的阅读和使用体验,文档中的图片文件会定期转换成可信的 CDN 地址。
### PR 方式 ### PR 提交注意事项
- 操作与代码贡献一致,指向 develop 分支。 - 指向 develop 分支。
- 涉及到图片的,需附在文档同级的 img 目录下,通过相对地址引用。
### 文档格式
本项目文档参考[文档编写指南](https://github.com/sparanoid/chinese-copywriting-guidelines)。
使用 vscode 进行编辑的朋友可以安装 vscode 插件 [huacnlee.autocorrect](https://github.com/huacnlee/autocorrect) 辅助文档 lint。

View File

@ -44,7 +44,7 @@ sidebar_position: 2
- 日常迭代 2 周,一般月中或月底 - 日常迭代 2 周,一般月中或月底
- 特殊情况紧急迭代随时发 - 特殊情况紧急迭代随时发
- 大Feature迭代每年 2 - 4 次 - 大 Feature 迭代,每年 2 - 4 次
### 发布步骤 ### 发布步骤
@ -57,7 +57,7 @@ sidebar_position: 2
```bash ```bash
git checkout develop git checkout develop
``` ```
2. 创建release分支 2. 创建 release 分支
```bash ```bash
git checkout -b release/1.0.0 git checkout -b release/1.0.0
``` ```
@ -65,7 +65,7 @@ sidebar_position: 2
```bash ```bash
npm run build npm run build
``` ```
4. 发布到npm 4. 发布到 npm
```bash ```bash
npm run pub npm run pub
``` ```
@ -77,9 +77,9 @@ sidebar_position: 2
7. 合并 release/x.x.x 到 main 分支 7. 合并 release/x.x.x 到 main 分支
8. 合并 main 分支到 develop 分支 8. 合并 main 分支到 develop 分支
如果是发布beta 版本,步骤如下(以发布 1.0.1 版本为例): 如果是发布 beta 版本,步骤如下(以发布 1.0.1 版本为例):
#### 发某版本首个 beta ,如 1.0.1-beta.0 #### 发某版本首个 beta如 1.0.1-beta.0
1. 拉 develop 分支 1. 拉 develop 分支
```bash ```bash
git checkout develop git checkout develop
@ -105,7 +105,7 @@ sidebar_position: 2
tnpm run sync tnpm run sync
``` ```
#### 发某版本非首个 beta ,如 1.0.1-beta.0 -> 1.0.1-beta.1 #### 发某版本非首个 beta如 1.0.1-beta.0 -> 1.0.1-beta.1
1. 切换到 release 分支 1. 切换到 release 分支
```bash ```bash
git checkout release/1.0.1-beta git checkout release/1.0.1-beta
@ -136,7 +136,7 @@ sidebar_position: 2
```bash ```bash
npm run build npm run build
``` ```
3. publish (此步骤需要 npm 发包权限) 3. publish此步骤需要 npm 发包权限)
```bash ```bash
npm run pub npm run pub
``` ```

View File

@ -65,7 +65,7 @@ sidebar_position: 2
- setters { Array } 设计器中设置器描述协议列表 - setters { Array } 设计器中设置器描述协议列表
- extConfig { Object } 平台自定义扩展字段 - extConfig { Object } 平台自定义扩展字段
### 2.1 versionA ### 2.1 version (A)
定义当前协议 schema 的版本号; 定义当前协议 schema 的版本号;
@ -73,9 +73,9 @@ sidebar_position: 2
| ---------- | ------ | ---------- | -------- | ------ | | ---------- | ------ | ---------- | -------- | ------ |
| version | String | 协议版本号 | - | 1.1.0 | | version | String | 协议版本号 | - | 1.1.0 |
### 2.2 packagesA ### 2.2 packages (A)
定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等; 定义低代码编辑器中加载的资源列表,包含公共库和组件 (库) cdn 资源等;
| 字段 | 字段描述 | 字段类型 | 规范等级 | 备注 | | 字段 | 字段描述 | 字段类型 | 规范等级 | 备注 |
| -------------------- | --------------------------------------------------------------- | ------------- | -------- | -------------------------------------------------------------------------------------------------------- | | -------------------- | --------------------------------------------------------------- | ------------- | -------- | -------------------------------------------------------------------------------------------------------- |
@ -92,13 +92,13 @@ sidebar_position: 2
| packages[].advancedEditUrls | 组件多个编辑态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个编辑态的资源,低代码引擎编辑器会加载这些资源,优先级高于 packages[].editUrls | | packages[].advancedEditUrls | 组件多个编辑态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个编辑态的资源,低代码引擎编辑器会加载这些资源,优先级高于 packages[].editUrls |
| packages[].advancedUrls | 组件多个端的渲染态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个渲染态的资源, 低代码引擎渲染模块会加载这些资源,优先级高于 packages[].urls | | packages[].advancedUrls | 组件多个端的渲染态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个渲染态的资源, 低代码引擎渲染模块会加载这些资源,优先级高于 packages[].urls |
| packages[].external | 当前资源在作为其他资源的依赖,在其他依赖打包时时是否被排除了(同 webpack 中 external 概念) | Boolean | AAA | 某些资源会被单独提取出来,是其他依赖的前置依赖,根据这个字段决定是否提前加载该资源 | | packages[].external | 当前资源在作为其他资源的依赖,在其他依赖打包时时是否被排除了(同 webpack 中 external 概念) | Boolean | AAA | 某些资源会被单独提取出来,是其他依赖的前置依赖,根据这个字段决定是否提前加载该资源 |
| packages[].loadEnv | 指定当前资源加载的环境 | Array<String\> | AAA | 主要用于指定 external 资源加载的环境取值为 design(设计态)、runtime(预览态)中的一个或多个 | | packages[].loadEnv | 指定当前资源加载的环境 | Array<String\> | AAA | 主要用于指定 external 资源加载的环境取值为 design(设计态)、runtime(预览态) 中的一个或多个 |
| packages[].exportSourceId | 标识当前 package 内容是从哪个 package 导出来的 | String | AAA | 此时 urls 无效 | | packages[].exportSourceId | 标识当前 package 内容是从哪个 package 导出来的 | String | AAA | 此时 urls 无效 |
| packages[].exportSourceLibrary | 标识当前 package 是从 window 上的哪个属性导出来的 | String | AAA | exportSourceId 的优先级高于exportSourceLibrary ,此时 urls 无效 | | packages[].exportSourceLibrary | 标识当前 package 是从 window 上的哪个属性导出来的 | String | AAA | exportSourceId 的优先级高于exportSourceLibrary ,此时 urls 无效 |
| packages[].async | 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 | Boolean | A | async 为 true 时,需要通过 await 才能拿到真正内容 | | packages[].async | 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 | Boolean | A | async 为 true 时,需要通过 await 才能拿到真正内容 |
| packages[].exportMode | 标识当前 package 从其他 package 的导出方式 | String | A | 目前只支持 `"functionCall"`, exportMode等于 `"functionCall"`当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any | Promise<any\>, library 为当前 package library, packageName 为当前的包名返回值为当前 package 的导出内容 | | packages[].exportMode | 标识当前 package 从其他 package 的导出方式 | String | A | 目前只支持 `"functionCall"`, exportMode等于 `"functionCall"`当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any | Promise<any\>, library 为当前 package library, packageName 为当前的包名返回值为当前 package 的导出内容 |
描述举例: 描述举例
```json ```json
{ {
@ -298,14 +298,14 @@ sidebar_position: 2
} }
``` ```
### 2.3 components A ### 2.3 components (A)
定义资产包中包含的所有组件的低代码描述的集合分为“ComponentDescription”和“RemoteComponentDescription”(详见 2.6 TypeScript 定义) 定义资产包中包含的所有组件的低代码描述的集合分为“ComponentDescription”和“RemoteComponentDescription”(详见 2.6 TypeScript 定义)
- ComponentDescription: 符合“组件描述协议”的数据,详见物料规范中`2.2.2 组件描述协议`部分; - ComponentDescription: 符合“组件描述协议”的数据,详见物料规范中`2.2.2 组件描述协议`部分;
- RemoteComponentDescription 是将一个或多个 ComponentDescription 构建打包的 js 资源的描述,在浏览器中加载该资源后可获取到其中包含的每个组件的 ComponentDescription 的具体内容; - RemoteComponentDescription 是将一个或多个 ComponentDescription 构建打包的 js 资源的描述,在浏览器中加载该资源后可获取到其中包含的每个组件的 ComponentDescription 的具体内容;
### 2.4 sort AA ### 2.4 sort (AA)
定义组件列表分组 定义组件列表分组
@ -346,7 +346,7 @@ sidebar_position: 2
### 2.7 extConfig (AAA) ### 2.7 extConfig (AAA)
定义平台相关的扩展内容,用于存放平台自身实现的一些私有协议, 以允许存量平台能够平滑地迁移至标准协议。 extConfig 是一个 key-value 结构的对象,协议不会规定 extConfig 中的字段名称以及类型, 完全自定义 定义平台相关的扩展内容,用于存放平台自身实现的一些私有协议以允许存量平台能够平滑地迁移至标准协议。extConfig 是一个 key-value 结构的对象,协议不会规定 extConfig 中的字段名称以及类型完全自定义
### 2.8 TypeScript 定义 ### 2.8 TypeScript 定义

View File

@ -78,7 +78,7 @@ sidebar_position: 0
### 1.7 背景 ### 1.7 背景
- **协议目标** 通过约束低代码引擎的搭建协议规范,让上层低代码编辑器的产出物(低代码业务组件、区块、应用)保持一致性,可跨低代码研发平台进行流通而提效,亦不阻碍集团业务间融合的发展。  - **协议目标**:通过约束低代码引擎的搭建协议规范,让上层低代码编辑器的产出物(低代码业务组件、区块、应用)保持一致性,可跨低代码研发平台进行流通而提效,亦不阻碍集团业务间融合的发展。 
- **协议通** - **协议通**
- 协议顶层结构统一 - 协议顶层结构统一
- 协议 schema 具备有完整的描述能力,包含版本、国际化、组件树、组件映射关系等; - 协议 schema 具备有完整的描述能力,包含版本、国际化、组件树、组件映射关系等;
@ -179,10 +179,10 @@ sidebar_position: 0
"props": { "props": {
"prop1": 1234, // 简单 json 数据 "prop1": 1234, // 简单 json 数据
"prop2": [{ // 简单 json 数据 "prop2": [{ // 简单 json 数据
"label": "选项1", "label": "选项 1",
"value": 1 "value": 1
}, { }, {
"label": "选项2", "label": "选项 2",
"value": 2 "value": 2
}], }],
"prop3": [{ "prop3": [{
@ -232,8 +232,8 @@ sidebar_position: 0
"primary": "#ff9966" "primary": "#ff9966"
} }
}, },
"meta": { // 应用元数据信息, key 为业务自定义 "meta": { // 应用元数据信息key 为业务自定义
"name": "demo 应用", // 应用中文名称, "name": "demo 应用", // 应用中文名称
"git_group": "appGroup", // 应用对应 git 分组名 "git_group": "appGroup", // 应用对应 git 分组名
"project_name": "app_demo", // 应用对应 git 的 project 名称 "project_name": "app_demo", // 应用对应 git 的 project 名称
"description": "这是一个测试应用", // 应用描述 "description": "这是一个测试应用", // 应用描述
@ -343,7 +343,7 @@ sidebar_position: 0
出码结果: 出码结果:
```javascript ```javascript
// 使用解构方式, destructuring is true. // 使用解构方式destructuring is true.
import { Button } from '@alifd/next'; import { Button } from '@alifd/next';
// 使用解构方式,且 exportName 和 componentName 不同 // 使用解构方式,且 exportName 和 componentName 不同
@ -376,7 +376,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input';
与源码对应的转换关系如下: 与源码对应的转换关系如下:
- 组件结构:转换成一个 .jsx 文件内 React Class 类 render 函数返回的 **jsx** 代码。 - 组件结构:转换成一个 .jsx 文件内 React Class 类 render 函数返回的 **jsx** 代码。
- 容器结构:将转换成一个标准文件,如 React 的 jsx 文件, export 一个 React Class包含生命周期定义、自定义方法、事件属性绑定、异步数据请求等。 - 容器结构:将转换成一个标准文件,如 React 的 jsx 文件export 一个 React Class包含生命周期定义、自定义方法、事件属性绑定、异步数据请求等。
#### 2.3.1 基础结构描述 (A) #### 2.3.1 基础结构描述 (A)
@ -427,9 +427,9 @@ import { Input as CustomInput } from '@ali/custom/lib/input';
| shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | ```() => true``` | function 参数参考 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | | shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | ```() => true``` | function 参数参考 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) |
| willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数options返回值作为请求的 options当处理异常时使用原 options。也可以返回一个 Promiseresolve 的值作为请求的 optionsreject 时,使用原 options | | willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数options返回值作为请求的 options当处理异常时使用原 options。也可以返回一个 Promiseresolve 的值作为请求的 optionsreject 时,使用原 options |
| requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type='custom' 时生效 | | requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type='custom' 时生效 |
| dataHandler | request 成功后的回调函数 | Function | - | `response => response.data` | 参数: 请求成功后 promise 的 value 值 | | dataHandler | request 成功后的回调函数 | Function | - | `response => response.data`| 参数:请求成功后 promise 的 value 值 ||
| errorHandler | request 失败后的回调函数 | Function | - | - | 参数: 请求出错 promise 的 error 内容 | | errorHandler | request 失败后的回调函数 | Function | - | - | 参数请求出错 promise 的 error 内容 |
| options {} | 请求参数 | **ComponentDataSourceItemOptions** | - | - | 每种请求类型对应不同参数, 详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | | options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见 | 每种请求类型对应不同参数,详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) |
**关于 dataHandler 于 errorHandler 的细节说明:** **关于 dataHandler 于 errorHandler 的细节说明:**
@ -518,7 +518,7 @@ try {
| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 |
| ------------ | ---------- | -------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------- | | ------------ | ---------- | -------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------- |
| name | 属性名称 | String | - | - | | | name | 属性名称 | String | - | - | |
| propType | 属性类型 | String\|Object | - | - | 具体值内容结构,参考《低代码引擎物料协议规范》 内的 “2.2.2.3 组件属性信息”中描述的**基本类型**和**复合类型** | | propType | 属性类型 | String\|Object | - | - | 具体值内容结构参考《低代码引擎物料协议规范》内的“2.2.2.3 组件属性信息”中描述的**基本类型**和**复合类型** |
| description | 属性描述 | String | - | '' | | | description | 属性描述 | String | - | '' | |
| defaultValue | 属性默认值 | Any | - | undefined | 当 defaultValue 和 defaultProps 中存在同一个 prop 的默认值时,优先使用 defaultValue。 | | defaultValue | 属性默认值 | Any | - | undefined | 当 defaultValue 和 defaultProps 中存在同一个 prop 的默认值时,优先使用 defaultValue。 |
@ -544,9 +544,9 @@ try {
| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 |
| ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | | ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- |
| id | 组件唯一标识 | String | - | | 可选, 组件 id 由引擎随机生成UUID并保证唯一性消费方为上层应用平台在组件发生移动等场景需保持 id 不变 | | id | 组件唯一标识 | String | - | | 可选组件 id 由引擎随机生成UUID并保证唯一性消费方为上层应用平台在组件发生移动等场景需保持 id 不变 |
| componentName | 组件名称 | String | - | Div | 必填,首字母大写, 同 [componentsMap](#22-组件映射关系 a) 中的要求 | | componentName | 组件名称 | String | - | Div | 必填,首字母大写同 [componentsMap](#22-组件映射关系 a) 中的要求 |
| props {} | 组件属性对象 | **Props** | - | {} | 必填, 详见 [Props 结构描述](#2311-props-结构描述) | | props {} | 组件属性对象 | **Props**| - | {} | 必填,详见 | 必填,详见 [Props 结构描述](#2311-props-结构描述) |
| condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 |
| loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 | | loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 |
| loopArgs | 循环迭代对象、索引名称 | [String, String] | | ["item", "index"] | 选填,仅支持字符串 | | loopArgs | 循环迭代对象、索引名称 | [String, String] | | ["item", "index"] | 选填,仅支持字符串 |
@ -611,10 +611,10 @@ try {
| condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 |
| state | 容器初始数据 | Object | ✅ | - | 选填,支持变量表达式 | | state | 容器初始数据 | Object | ✅ | - | 选填,支持变量表达式 |
| children | 子组件 | Array | - | | 选填,支持变量表达式 | | children | 子组件 | Array | - | | 选填,支持变量表达式 |
| css/less/scss | 样式属性 | String | ✅ | - | 选填, 详见 [css/less/scss 样式描述](#2312-csslessscss 样式描述) | | css/less/scss | 样式属性 | String | ✅ | - | 选填,详见 [css/less/scss 样式描述](#2312-csslessscss 样式描述) |
| lifeCycles | 生命周期对象 | **ComponentLifeCycles** | - | - | 详见 [ComponentLifeCycles 对象描述](#2316-componentlifecycles-对象描述) | | lifeCycles | 生命周期对象 | **ComponentLifeCycles** | - | - | 详见 [ComponentLifeCycles 对象描述](#2316-componentlifecycles-对象描述) |
| methods | 自定义方法对象 | Object | - | - | 选填,对象成员为函数类型 | | methods | 自定义方法对象 | Object | - | - | 选填,对象成员为函数类型 |
| dataSource {} | 数据源对象 | **ComponentDataSource** | - | - | 选填,异步数据源, 详见 [ComponentDataSource 对象描述](#2313-componentdatasource-对象描述) | | dataSource {} | 数据源对象 | **ComponentDataSource**| - | - | 选填,异步数据源,详见 | - | - | 选填,异步数据源,详见 [ComponentDataSource 对象描述](#2313-componentdatasource-对象描述) |
@ -891,7 +891,7 @@ try {
"value": "this.state.num - this.state.num2" "value": "this.state.num - this.state.num2"
} }
``` ```
- return "8万" 字符串类型 - return "8 万" 字符串类型
```json ```json
{ {
@ -899,7 +899,7 @@ try {
"value": "`${this.state.num}万`" "value": "`${this.state.num}万`"
} }
``` ```
- return "8万" 字符串类型 - return "8 万" 字符串类型
```json ```json
{ {
@ -1056,7 +1056,7 @@ type Ti18n = {
请将 `setState()` 视为请求而不是立即更新组件的命令。为了更好的感知性能,低代码引擎会延迟调用它,然后通过一次传递更新多个组件。低代码引擎并不会保证 state 的变更会立即生效。 请将 `setState()` 视为请求而不是立即更新组件的命令。为了更好的感知性能,低代码引擎会延迟调用它,然后通过一次传递更新多个组件。低代码引擎并不会保证 state 的变更会立即生效。
`setState()` 并不总是立即更新组件, 它会批量推迟更新。这使得在调`setState()` 后立即读取 `this.state` 成为了隐患。为了消除隐患,请使用 `setState` 的回调函数(`setState(updater, callback)``callback` 将在应用更新后触发。即,如下例所示: `setState()`并不总是立即更新组件,它会批量推迟更新。这使得在调用`setState()` 后立即读取 `this.state` 成为了隐患。为了消除隐患,请使用 `setState` 的回调函数(`setState(updater, callback)``callback` 将在应用更新后触发。即,如下例所示:
```js ```js
this.setState(newState, () => { this.setState(newState, () => {
@ -1087,7 +1087,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 }));
| data | 获取上次请求成功后的数据 | Any | | | data | 获取上次请求成功后的数据 | Any | |
| error | 获取上次请求失败的错误对象 | Error 对象 | | | error | 获取上次请求失败的错误对象 | Error 对象 | |
备注: 如果组件没有在区块容器内,而是直接在页面内,那么 `this === this.page` 备注:如果组件没有在区块容器内,而是直接在页面内,那么 `this === this.page`
##### 2.3.5.2 循环数据 API ##### 2.3.5.2 循环数据 API
@ -1108,7 +1108,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 }));
| ------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------- | ------ | | ------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------- | ------ |
| utils[] | 工具类扩展映射关系 | Array\<**UtilItem**\> | - | | | utils[] | 工具类扩展映射关系 | Array\<**UtilItem**\> | - | |
| *UtilItem*.name | 工具类扩展项名称 | String | - | | | *UtilItem*.name | 工具类扩展项名称 | String | - | |
| *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | | | *UtilItem*.type | 工具类扩展项类型 | 枚举 `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | |
| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | | | *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | |
描述示例: 描述示例:
@ -1161,7 +1161,7 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) {
... ...
``` ```
扩展的工具类,用户可以通过统一的上下文 this.utils 方法获取所有扩展的工具类或自定义函数 例如this.utils.moment、this.utils.clone。搭建协议中的使用方式如下所示 扩展的工具类,用户可以通过统一的上下文 this.utils 方法获取所有扩展的工具类或自定义函数例如this.utils.moment、this.utils.clone。搭建协议中的使用方式如下所示
```javascript ```javascript
{ {
@ -1202,7 +1202,7 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) {
} }
``` ```
使用举例: 使用举例
```json ```json
{ {
@ -1303,11 +1303,11 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) {
│ │ └── app.js # 应用配置文件 │ │ └── app.js # 应用配置文件
│ ├── utils/ # 工具库 │ ├── utils/ # 工具库
│ │ └── index.js # 应用第三方扩展函数 │ │ └── index.js # 应用第三方扩展函数
│ ├── locales/ # [可选]国际化资源 │ ├── locales/ # [可选] 国际化资源
│ │ ├── en-US │ │ ├── en-US
│ │ └── zh-CN │ │ └── zh-CN
│ ├── global.scss # 全局样式 │ ├── global.scss # 全局样式
│ └── index.jsx # 应用入口脚本, 依赖 config/routes.js 的路由配置动态生成路由; │ └── index.jsx # 应用入口脚本依赖 config/routes.js 的路由配置动态生成路由;
├── webpack.config.js # 项目工程配置,包含插件配置及自定义 webpack 配置等 ├── webpack.config.js # 项目工程配置,包含插件配置及自定义 webpack 配置等
├── README.md ├── README.md
├── package.json ├── package.json

View File

@ -250,7 +250,7 @@ API 是组件的属性解释,给开发者作为组件属性配置的参考。
| direction | enum | 方向,取值采用缩写的方式。 | hoz水平, ver垂直 | | direction | enum | 方向,取值采用缩写的方式。 | hoz水平, ver垂直 |
| align | enum | 对齐方式 | tl, tc, tr, cl, cc, cr, bl, bc, br | | align | enum | 对齐方式 | tl, tc, tr, cl, cc, cr, bl, bc, br |
| status | enum | 状态 | normal, success, error, warning | | status | enum | 状态 | normal, success, error, warning |
| size | enum | 大小 | small, medium, large 更大或更小可用(xxs, xs, xl, xxl) | | size | enum | 大小 | small, medium, large 更大或更小可用 (xxs, xs, xl, xxl) |
| type | enum or string | 分类:1. dom 结构不变、只有皮肤的变化 2.组件类型只有并列的几类 | normal, primary, secondary | | type | enum or string | 分类:1. dom 结构不变、只有皮肤的变化 2.组件类型只有并列的几类 | normal, primary, secondary |
| visible | boolean | 是否显示 | | | visible | boolean | 是否显示 | |
| defaultVisible | boolean | 是否显示(非受控) | | | defaultVisible | boolean | 是否显示(非受控) | |
@ -266,7 +266,7 @@ API 是组件的属性解释,给开发者作为组件属性配置的参考。
当某个 API 的接口,允许用户指定多个枚举值的时候,我们把这个接口定义为多选枚举。一个很典型的例子是某个弹层组件的 `closable` 属性,我们会允许:键盘 esc 按键、点击 mask、点击 close 按钮、点击组件以外的任何区域进行关闭。 当某个 API 的接口,允许用户指定多个枚举值的时候,我们把这个接口定义为多选枚举。一个很典型的例子是某个弹层组件的 `closable` 属性,我们会允许:键盘 esc 按键、点击 mask、点击 close 按钮、点击组件以外的任何区域进行关闭。
不要有一个 API 值,支持多种类型。例如某个弹层的组件,我们会允许 esc、点击 mask、点击 close 按钮等进行关闭。此时 API 设计可以通过多个 API 承载,例如: 不要有一个 API 值,支持多种类型。例如某个弹层的组件,我们会允许 esc、点击 mask、点击 close 按钮等进行关闭。此时 API 设计可以通过多个 API 承载,例如
```js ```js
closable?: boolean; // 默认为 true closable?: boolean; // 默认为 true
@ -283,14 +283,14 @@ true 表示触发规则都会关闭false 表示触发规则不会关闭。
#### 事件 #### 事件
- 标准事件或者自定义的符合 w3c 标准的事件,命名必须 on 开头, 即 `on` + 事件名,如 onExpand。 - 标准事件或者自定义的符合 w3c 标准的事件,命名必须 on 开头 即 `on` + 事件名,如 onExpand。
#### 表单规范 #### 表单规范
- 支持[受控模式](https://reactjs.org/docs/forms.html#controlled-components)(value + onChange) A) - 支持[受控模式](https://reactjs.org/docs/forms.html#controlled-components)(value + onChange) A)
- value 控制组件数据展现 - value 控制组件数据展现
- onChange 组件发生变化时候的回调函数(第一个参数可以给到 value) - onChange 组件发生变化时候的回调函数(第一个参数可以给到 value)
- `value={undefined}` 的时候清空数据, field 的 reset 函数会给所有组件下发 undefined 数据 (AA) - `value={undefined}`的时候清空数据,field 的 reset 函数会给所有组件下发 undefined 数据 (AA))
- 一次完整操作抛一次 onChange 事件 `建议` 比如有 Process 表示进展中的状态,建议增加 API `onProcess`;如果有 Start 表示启动状态,建议增加 API `onStart`  (AA) - 一次完整操作抛一次 onChange 事件 `建议` 比如有 Process 表示进展中的状态,建议增加 API `onProcess`;如果有 Start 表示启动状态,建议增加 API `onStart`  (AA)
#### 属性的传递 #### 属性的传递
@ -357,7 +357,7 @@ $ iceworks sync
#### 目录规范 #### 目录规范
在 `src` 目录新增 `locale` 目录用于管理不同语言的文案. 在 `src` 目录新增 `locale` 目录用于管理不同语言的文案。
``` ```
|- BizHello |- BizHello
@ -499,9 +499,9 @@ export default {
api 属性标准参考 [https://fusion.design/help.html#/dev-biz](https://fusion.design/help.html#/dev-biz) api 属性标准参考 [https://fusion.design/help.html#/dev-biz](https://fusion.design/help.html#/dev-biz)
#### 2.1.7 无障碍访问规范(AAA) #### 2.1.7 无障碍访问规范 (AAA)
无障碍需要符合 [WCAG 2.1 A级标准](https://www.w3.org/TR/WCAG21/),可参考 [W3C 无障碍最佳实践](https://www.w3.org/TR/wai-aria-practices-1.1/)、[Fusion 无障碍指引 2.3.1](https://alibaba-fusion.github.io/next/part1/basics.html) 章节等。 无障碍需要符合 [WCAG 2.1 A 级标准](https://www.w3.org/TR/WCAG21/),可参考 [W3C 无障碍最佳实践](https://www.w3.org/TR/wai-aria-practices-1.1/)、[Fusion 无障碍指引 2.3.1](https://alibaba-fusion.github.io/next/part1/basics.html) 章节等。
#### 增加 a11y.md 无障碍 demo #### 增加 a11y.md 无障碍 demo
@ -552,7 +552,7 @@ component
| -------------- | ------------------------------------------------------------------------------------------------- | ------ | | -------------- | ------------------------------------------------------------------------------------------------- | ------ |
| version | 协议版本号 | String | | version | 协议版本号 | String |
| componentsMap | 描述组件映射关系的集合 | Array | | componentsMap | 描述组件映射关系的集合 | Array |
| componentsTree | 低代码业务组件树描述,是长度固定为1的数组, 即数组内仅包含根容器的描述(低代码业务组件容器类型) | Array | | componentsTree | 低代码业务组件树描述,是长度固定为 1 的数组,即数组内仅包含根容器的描述(低代码业务组件容器类型) | Array |
| utils | 工具类扩展映射关系 | Array | | utils | 工具类扩展映射关系 | Array |
| i18n | 国际化语料 | Object | | i18n | 国际化语料 | Object |
@ -572,7 +572,7 @@ component
"name": "lucy", "name": "lucy",
}, },
"static": {}, // 用于定义自定组件的 static 属性 "static": {}, // 用于定义自定组件的 static 属性
"defaultProps": { // 默认 props 选填仅用于定义低代码业务组件的默认属性固定对象 "defaultProps": { // 默认 props选填仅用于定义低代码业务组件的默认属性固定对象
"name": "xxx" "name": "xxx"
}, },
"children": [{ "children": [{
@ -609,8 +609,6 @@ component
- **组件属性信息 (A)** 描述组件属性信息,通常包含参数、说明、类型、默认值 4 项内容。 - **组件属性信息 (A)** 描述组件属性信息,通常包含参数、说明、类型、默认值 4 项内容。
- **能力配置/体验增强:** 推荐用于优化搭建产品编辑体验,定制编辑能力的配置信息。 - **能力配置/体验增强:** 推荐用于优化搭建产品编辑体验,定制编辑能力的配置信息。
整体结构概览: [http://lowcode-engine.cn/doc?url=sde3wf](http://lowcode-engine.cn/doc?url=sde3wf)
##### 2.2.2.2 基础信息A ##### 2.2.2.2 基础信息A
| 字段 | 字段描述 | 字段类型 | 允许空 | | 字段 | 字段描述 | 字段类型 | 允许空 |
@ -837,7 +835,7 @@ props 数组下对象字段描述:
| defaultValue | 默认值 | Any(视字段类型而定) | type = 'field' 生效 | | defaultValue | 默认值 | Any(视字段类型而定) | type = 'field' 生效 |
| supportVariable | 是否支持配置变量 | Boolean | type = 'field' 生效 | | supportVariable | 是否支持配置变量 | Boolean | type = 'field' 生效 |
| condition | 配置当前 prop 是否展示 | (target: SettingTarget) => boolean; | - | | condition | 配置当前 prop 是否展示 | (target: SettingTarget) => boolean; | - |
| setter | 单个控件(setter)描述,搭建基础协议组件的描述对象,支持 JSExpression / JSFunction / JSSlot | `String\|Object\|Function` | type = 'field' 生效 | | setter | 单个控件 (setter) 描述,搭建基础协议组件的描述对象,支持 JSExpression / JSFunction / JSSlot | `String\|Object\|Function` | type = 'field' 生效 |
| extraProps | 其他配置属性(不做流通要求) | Object | 其他配置 | | extraProps | 其他配置属性(不做流通要求) | Object | 其他配置 |
| extraProps.getValue | setter 渲染时被调用setter 会根据该函数的返回值设置 setter 当前值 | Function | (target: SettingTarget, value: any) => any; | | extraProps.getValue | setter 渲染时被调用setter 会根据该函数的返回值设置 setter 当前值 | Function | (target: SettingTarget, value: any) => any; |
| extraProps.setValue | setter 内容修改时调用,开发者可在该函数内部修改节点 schema 或者进行其他操作 | Function | (target: SettingTarget, value: any) => void; | | extraProps.setValue | setter 内容修改时调用,开发者可在该函数内部修改节点 schema 或者进行其他操作 | Function | (target: SettingTarget, value: any) => void; |
@ -885,7 +883,7 @@ props 数组下对象字段描述:
| nestingRule.descendantBlacklist | 后裔节点类型黑名单 | `String\|Function` | | nestingRule.descendantBlacklist | 后裔节点类型黑名单 | `String\|Function` |
| nestingRule.ancestorWhitelist | 祖父节点类型白名单 | `String\|Function` | | nestingRule.ancestorWhitelist | 祖父节点类型白名单 | `String\|Function` |
| isNullNode(AAA) | 是否存在渲染的根节点 | Boolean | | isNullNode(AAA) | 是否存在渲染的根节点 | Boolean |
| isLayout(AAA) | 是否是layout布局组件 | Boolean | | isLayout(AAA) | 是否是 layout 布局组件 | Boolean |
| rootSelector(AAA) | 组件选中框的 cssSelector | String | | rootSelector(AAA) | 组件选中框的 cssSelector | String |
| disableBehaviors(AAA) | 用于屏蔽在设计器中选中组件时提供的操作项,默认操作项有 copy、hide、remove | String[] | | disableBehaviors(AAA) | 用于屏蔽在设计器中选中组件时提供的操作项,默认操作项有 copy、hide、remove | String[] |
| actions(AAA) | 用于详细配置上述操作项的内容 | Object | | actions(AAA) | 用于详细配置上述操作项的内容 | Object |
@ -925,20 +923,20 @@ props 数组下对象字段描述:
| 字段 | 用途 | 类型 | 备注 | | 字段 | 用途 | 类型 | 备注 |
| ------------------------------- | --------------------------------------------------------------------------------------------------- | ------- | --- | | ------------------------------- | --------------------------------------------------------------------------------------------------- | ------- | --- |
|initialChildren |组件拖入“设计器”时根据此配置自动生成 children 节点 schema |NodeData[]/Function NodeData[] | ((target: SettingTarget) => NodeData[]);| |initialChildren | 组件拖入“设计器”时根据此配置自动生成 children 节点 schema |NodeData[]/Function NodeData[] | ((target: SettingTarget) => NodeData[]);|
|getResizingHandlers| 用于配置设计器中组件 resize 操作工具的样式和内容| Function| (currentNode: any) => Array<{ type: 'N' | 'W' | 'S' | 'E' | 'NW' | 'NE' | 'SE' | 'SW'; content?: ReactElement; propTarget?: string; appearOn?: 'mouse-enter' | 'mouse-hover' | 'selected' | 'always'; }> / ReactElement[]; |getResizingHandlers| 用于配置设计器中组件 resize 操作工具的样式和内容 | Function| (currentNode: any) => Array<{ type: 'N' | 'W' | 'S' | 'E' | 'NW' | 'NE' | 'SE' | 'SW'; content?: ReactElement; propTarget?: string; appearOn?: 'mouse-enter' | 'mouse-hover' | 'selected' | 'always'; }> / ReactElement[];
|callbacks| 配置 callbacks 可捕获引擎抛出的一些事件,例如 onNodeAdd、onResize 等| Callback| - |callbacks| 配置 callbacks 可捕获引擎抛出的一些事件,例如 onNodeAdd、onResize 等 | Callback| -
|callbacks.onNodeAdd| 在容器中拖入组件时触发的事件回调| Function| (e: MouseEvent, currentNode: any) => any |callbacks.onNodeAdd| 在容器中拖入组件时触发的事件回调| Function| (e: MouseEvent, currentNode: any) => any
|callbacks.onNodeRemove| 在容器中删除组件时触发的事件回调| Function| (e: MouseEvent, currentNode: any) => any |callbacks.onNodeRemove| 在容器中删除组件时触发的事件回调| Function| (e: MouseEvent, currentNode: any) => any
|callbacks.onResize| 调整容器尺寸时触发的事件回调,常常与 getResizingHandlers搭配使用| Function| 详见 Types 定义 |callbacks.onResize| 调整容器尺寸时触发的事件回调,常常与 getResizingHandlers 搭配使用 | Function| 详见 Types 定义
|callbacks.onResizeStart| 调整容器尺寸开始时触发的事件回调,常常与 getResizingHandlers搭配使用| Function| 详见 Types 定义 |callbacks.onResizeStart| 调整容器尺寸开始时触发的事件回调,常常与 getResizingHandlers 搭配使用 | Function| 详见 Types 定义
|callbacks.onResizeEnd| 调整容器尺寸结束时触发的事件回调,常常与 getResizingHandlers搭配使用| Function| 详见 Types 定义 |callbacks.onResizeEnd| 调整容器尺寸结束时触发的事件回调,常常与 getResizingHandlers 搭配使用 | Function| 详见 Types 定义
|callbacks.onSubtreeModified| 容器节点结构树发生变化时触发的回调| Function| (currentNode: any, options: any) => void; |callbacks.onSubtreeModified| 容器节点结构树发生变化时触发的回调| Function| (currentNode: any, options: any) => void;
|callbacks.onMouseDownHook| 鼠标按下操作回调| Function| (e: MouseEvent, currentNode: any) => any; |callbacks.onMouseDownHook| 鼠标按下操作回调| Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onClickHook| 鼠标单击操作回调| Function| (e: MouseEvent, currentNode: any) => any; |callbacks.onClickHook| 鼠标单击操作回调| Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onDblClickHook| 鼠标双击操作回调| Function| (e: MouseEvent, currentNode: any) => any; |callbacks.onDblClickHook| 鼠标双击操作回调| Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onMoveHook| 节点被拖动回调| Function| (currentNode: any) => boolean; |callbacks.onMoveHook| 节点被拖动回调 | Function| (currentNode: any) => boolean;
|callbacks.onHoverHook| 节点被 hover 回调| Function| (currentNode: any) => boolean; |callbacks.onHoverHook| 节点被 hover 回调 | Function| (currentNode: any) => boolean;
|callbacks.onChildMoveHook| 容器节点的子节点被拖动回调| Function| (childNode: any, currentNode: any) => boolean; |callbacks.onChildMoveHook| 容器节点的子节点被拖动回调| Function| (childNode: any, currentNode: any) => boolean;
@ -1211,7 +1209,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中
- components { Array } 所有组件的描述协议列表 - components { Array } 所有组件的描述协议列表
- sort { Object } 用于描述组件面板中的 tab 和 category - sort { Object } 用于描述组件面板中的 tab 和 category
##### 2.2.3.2 versionA ##### 2.2.3.2 version (A)
定义当前协议 schema 的版本号; 定义当前协议 schema 的版本号;
@ -1219,9 +1217,9 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中
| ---------- | ------ | ---------- | -------- | ------ | | ---------- | ------ | ---------- | -------- | ------ |
| version | String | 协议版本号 | - | 1.0.0 | | version | String | 协议版本号 | - | 1.0.0 |
##### 2.2.3.3 packagesA ##### 2.2.3.3 packages (A)
定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等; 定义低代码编辑器中加载的资源列表,包含公共库和组件 (库) cdn 资源等;
| 字段 | 字段描述 | 字段类型 | 备注 | | 字段 | 字段描述 | 字段类型 | 备注 |
| --------------- | ---------------------- | -------- | ------------------------------------------------------------ | | --------------- | ---------------------- | -------- | ------------------------------------------------------------ |
@ -1232,7 +1230,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中
| packages[].editUrls (A) | 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css | Array\<String\> | 低代码引擎编辑器会加载这些 url | | packages[].editUrls (A) | 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css | Array\<String\> | 低代码引擎编辑器会加载这些 url |
| packages[].urls (AA) | 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css | Array\<String\> | 低代码引擎渲染模块会加载这些 url | | packages[].urls (AA) | 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css | Array\<String\> | 低代码引擎渲染模块会加载这些 url |
描述举例: 描述举例
```json ```json
{ {
@ -1253,7 +1251,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中
] ]
}, },
{ {
"title": "fusion组件库", "title": "fusion 组件库",
"package": "@alifd/next", "package": "@alifd/next",
"version": "1.24.18", "version": "1.24.18",
"urls": [ "urls": [
@ -1292,11 +1290,11 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中
} }
``` ```
##### 2.2.3.4 components A ##### 2.2.3.4 components (A)
定义所有组件的描述协议列表,组件描述协议遵循本规范章节 2.2.2 的定义; 定义所有组件的描述协议列表,组件描述协议遵循本规范章节 2.2.2 的定义;
##### 2.2.3.5 sort A ##### 2.2.3.5 sort (A)
定义组件列表分组 定义组件列表分组
@ -1330,7 +1328,7 @@ export interface RemoteComponentDescription {
} }
``` ```
## 3 物料规范-区块规范 ## 3 物料规范 - 区块规范
### 3.1 源码规范 ### 3.1 源码规范
@ -1386,14 +1384,14 @@ block/
"category": "form", "category": "form",
"screenshot": "https://unpkg.com/@icedesign/user-landing-block/screenshot.png", "screenshot": "https://unpkg.com/@icedesign/user-landing-block/screenshot.png",
"views": [{ // 区块视图,配置此项后会进入 fusion cool "views": [{ // 区块视图,配置此项后会进入 fusion cool
"title": "视图1标题", // 区块视图标题 "title": "视图 1 标题", // 区块视图标题
"props": { // 区块支持的 props "props": { // 区块支持的 props
"type": "primary" "type": "primary"
}, },
"screenshot": "build/views/block_view1.png", // 【编译自动填充】视图截图,会在 build 时自动生成 "screenshot": "build/views/block_view1.png", // 【编译自动填充】视图截图,会在 build 时自动生成
"html": "build/views/block_view1.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 "html": "build/views/block_view1.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成
},{ },{
"title": "视图2标题", // 区块视图标题 "title": "视图 2 标题", // 区块视图标题
"props": { // 区块支持的 props "props": { // 区块支持的 props
"type": "sencondary" "type": "sencondary"
}, },
@ -1417,7 +1415,7 @@ block/
| i18n | 国际化语料 | Object | | i18n | 国际化语料 | Object |
描述举例1 描述举例 1
```json ```json
{ {
@ -1425,7 +1423,7 @@ block/
"componentsMap": [{ }], "componentsMap": [{ }],
"componentsTree": [{ // 区块组件树,顶层由区块容器组件包裹; "componentsTree": [{ // 区块组件树,顶层由区块容器组件包裹;
"componentName": "Block", // 区块容器组件名 "componentName": "Block", // 区块容器组件名
"fileName": "block1", // 区块容器1 "fileName": "block1", // 区块容器 1
"props": {}, "props": {},
"css": "body {font-size: 12px;}", "css": "body {font-size: 12px;}",
"state": { "state": {
@ -1454,7 +1452,7 @@ block/
} }
``` ```
描述举例2 描述举例 2
```json ```json
{ {
@ -1527,13 +1525,13 @@ block/
│ │ └── app.js # 应用配置文件 │ │ └── app.js # 应用配置文件
│ ├── utils/ # 工具库 │ ├── utils/ # 工具库
│ │ └── index.js # 应用第三方扩展函数 │ │ └── index.js # 应用第三方扩展函数
│ ├── stores/ # [可选]全局状态管理 │ ├── stores/ # [可选] 全局状态管理
│ │ └── user.js │ │ └── user.js
│ ├── locales/ # [可选]国际化资源 │ ├── locales/ # [可选] 国际化资源
│ │ ├── en-US │ │ ├── en-US
│ │ └── zh-CN │ │ └── zh-CN
│ ├── global.scss # 全局样式 │ ├── global.scss # 全局样式
│ └── index.jsx # 应用入口脚本, 依赖 config/routes.js 的路由配置动态生成路由; │ └── index.jsx # 应用入口脚本依赖 config/routes.js 的路由配置动态生成路由;
├── webpack.config.js # 项目工程配置,包含插件配置及自定义 `webpack` 配置等 ├── webpack.config.js # 项目工程配置,包含插件配置及自定义 `webpack` 配置等
├── README.md ├── README.md
├── package.json ├── package.json
@ -1567,11 +1565,11 @@ ReactDOM.render(<App />, document.getElementById(pkg.config && pkg.config.target
(/src/config/app.js) (/src/config/app.js)
- 支持配置路由方式historyMode - 支持配置路由方式historyMode
- 支持2种路由方式 - 支持 2 种路由方式:
- 浏览器路由: browser - 浏览器路由browser
- 哈希路由:  hash - 哈希路由hash
- 支持透传路由产生的参数到所有组件的上下文 this 对象上 - 支持透传路由产生的参数到所有组件的上下文 this 对象上
- history 对象: this.history - history 对象this.history
- location 对象this.location - location 对象this.location
- 支持内置 query 参数的解析this.location.query - 支持内置 query 参数的解析this.location.query
- match 对象this.match - match 对象this.match
@ -1658,15 +1656,15 @@ a {
"category": "form", "category": "form",
"screenshot": "https://unpkg.com/@icedesign/user-landing-block/screenshot.png", "screenshot": "https://unpkg.com/@icedesign/user-landing-block/screenshot.png",
"views": [{ // 模板视图,配置此项后会进入 fusion cool "views": [{ // 模板视图,配置此项后会进入 fusion cool
"title": "视图1标题", // 模板视图标题 "title": "视图 1 标题", // 模板视图标题
"path": "#/dashboard/monitor", // 读取路由列表生成hash 路由必须加# "path": "#/dashboard/monitor", // 读取路由列表生成hash 路由必须加#
"screenshot": "build/views/page0.png", // 【编译自动填充】视图截图,会在 build 时自动生成 "screenshot": "build/views/page0.png", // 【编译自动填充】视图截图,会在 build 时自动生成
"html": "build/views/page0.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 "html": "build/views/page0.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成
},{ },{
"title": "视图2标题", // 区块视图标题 "title": "视图 2 标题", // 区块视图标题
"path": "#/dashboard/list", // 读取路由列表生成hash 路由必须加# "path": "#/dashboard/list", // 读取路由列表生成hash 路由必须加#
"screenshot": "build/views/page1.png", // 【编译自动填充】视图截图,会在 build 时自动生成 "screenshot": "build/views/page1.png", // 【编译自动填充】视图截图,会在 build 时自动生成
"html": "build/views/page1.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 "html": "build/views/page1.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成
}] }]
} }
} }

View File

@ -74,6 +74,10 @@ const config = {
}, },
// 语雀文档导出的图片,会进行 referrer 校验,这里设置关闭,不然加载不了语雀的图片 // 语雀文档导出的图片,会进行 referrer 校验,这里设置关闭,不然加载不了语雀的图片
metadata: [{ name: 'referrer', content: 'no-referrer' }], metadata: [{ name: 'referrer', content: 'no-referrer' }],
tableOfContents: {
minHeadingLevel: 2,
maxHeadingLevel: 5,
},
}), }),
themes: [ themes: [

View File

@ -1,6 +1,6 @@
{ {
"name": "@alilc/lowcode-engine-docs", "name": "@alilc/lowcode-engine-docs",
"version": "1.0.1", "version": "1.0.2",
"description": "低代码引擎版本化文档", "description": "低代码引擎版本化文档",
"license": "MIT", "license": "MIT",
"files": [ "files": [