阿里低代码引擎物料库开发文档
注意:该引擎提供的****cli ,未对windows系统做兼容,如是windows系统请先安装wsl环境,见章节window下搭建物料库环境
项目的启动
下载物料库模板,安装依赖,运行
npm run lowcode:dev
启动物料库调试。如果是在windows系统,请安装wsl,以保证项目正常启动。(见Windows下使用开发低代码引擎)。
运行上面代码后,会在根目录生成lowcode文件夹,里面会包含每个组件的低代码描述。
但是从源码解析出来的低代码描述让用户直接使用是不够精细的,因为源码包含的信息不够,它没办法完全包含配置项的交互,所以要根据用户习惯对配置项进行设计,然后人工地去开发调试直接的低代码描述
打开浏览器(默认地址localhost:3333)
模板中默认有两个按钮组件,分别为class方法编写和函数式方法编写,可根据默认组件的写法,自定义新的组件。
新增自定义组件
在src/components新增自定义组件,并在src/index.tsx中导出,然后再次执行
npm run lowcode:dev
在根目录 lowcode/ 目录自动生成新增组件的低代码描述(meta.ts)。
新建自定义组件GrtDiv
在components下新增grt-div目录,并新建grt-div.tsx和index.tsx,并导出(注意:只需要将新建的组件在src/index.tsx中导出即可,无需像示例中新建grt-div/index.tsx文件将其导出)
//grt-div.tsx
import * as React from 'react';
import { createElement } from 'react';
export interface GrtDivProps {
value?:"默认div值"
}
const GrtDiv: React.FC<GrtDivProps> = function GrtDiv({value}) {
return (
<>
<div>{value}</div>
</>
);
};
export default GrtDiv;
//index.tsx
import GrtDiv from './grt-div';
export type { GrtDivProps } from './grt-div';
export default GrtDiv;
在src/index.tsx中导出GrtDiv
//新增
export type { GrtDivProps } from './components/grt-div'
export { default as GrtDiv } from './components/grt-div'
然后再执行
npm run lowcode:dev
在 lowcode/ 目录自动生成新增组件的低代码描述(meta.ts)。
在浏览器中可以看到GrtDiv组件已出现在列表中,
修改GrtDiv的描述文件(meta.ts)
默认生成的组件,功能单一,需要我们手动修改meta.ts文件,来满足不同需求
下面是meta中常用的属性,用户可根据实际需要进行对应的配置
打开浏览器
在生成组件时,我们主要配置configure/props中的属性,来控制属性面板。其他属性见章节meta.ts属性详细配置。
不使用TSX开发组件
该组件库开发模板默认是使用ts生成的,对于不熟悉ts语法的开发人员,如需开发组件,请参照以下文档
新增GrtJsx组件
在src/components新增grt-div文件夹,新增jsx后缀文件index.jsx。并在src/index.tsx中导出。
// grt-jsx/index.jsx
import React from "react";
export const GrtJsx = function(){
return <div>我是jsx组件</div>
}
//在src/index.tsx 中将其导出
export { GrtJsx } from './components/grt-jsx'
随后在lowcode文件夹中新建grt-jsx文件夹,并新建meta.ts文件
其中meta.ts文件如下,这是一份基础的meta文件,保证该组件生成到组件库中,如需要个性化配置,请参照meta.ts属性配置
//lowcode/grt-jsx/meta.ts
import { ComponentMetadata, Snippet } from '@alilc/lowcode-types';
const GrtDivMeta: ComponentMetadata = {
"componentName": 'GrtJsx',//此处以及一下所有GrtJsxTem要替换成自己的组件名称
"title": "这是一个基础的jsx组件",//组件中文名称
"description": "这是jsx组件的基础meta描述",
"devMode": "proCode",//组件研发模式
"npm": {
"package": "grt-material",
"version": "0.1.0",//保持版本一致
"exportName": "GrtJsx",//替换成自己的组件名称
"main": "src/index.tsx",
"destructuring": true,
"subName": ""
},
"group": "自定义组件",
"category": "容器组件",
"priority": 1,
};
const snippets: Snippet[] = [
{
"title": "GrtJsx",//替换成自己的组件名称
"schema": {
"componentName": "GrtJsx",//替换成自己的组件名称
"props": {}
}
}
];
export default {
...GrtDivMeta,
snippets
};
随后,再重新运行
npm run lowcode:dev
打开浏览器,可以看到jsx组件添加成功
在demo中使用自定义组件
组件开发成功之后,如何在项目中使用?请参照以下文档
发布组件
新建的组件需要发布到npm上,才能在项目中使用,在项目根目录下运行npm publish发布组件
找到demo项目中如图文件夹,
根据配置和文档得知组件的配置在assets.json中设置,打开assets.json
可以看到文件一共分为四部分,返回我们的物料库项目,在执行npm publish后会先执行build命令,打开build/lowcode/assets.prod.json,可以看到packages的相关信息
将相关的字段复制到demo项目中assets.json当中,如packages
同样在components处,也把需要添加的内容复制过去:
在浏览器可以看到自定义组件已经被添加
\
meta.ts属性详细配置
组件的属性配置主要是在meta中实现的,下面是对一些常用配置的介绍
基础信息
| 字段 | 字段描述 | 字段类型 | 允许空 |
|---|---|---|---|
| componentName | 组件名称 | String | 否 |
| title | 组件中文名称 | String | 否 |
| description | 组件描述 | String | 是 |
| docUrl | 组件文档链接 | String | 否 |
| screenshot | 组件快照 | String | 否 |
| icon | 组件的小图标 | String (URL) | 是 |
| tags | 组件标签 | String | 是 |
| keywards | 组件关键词,用于搜索联想 | String | 是 |
| devMode | 组件研发模式 | String (procode,lowcode) | 是 |
| npm | npm 源引入完整描述对象 | Object | 否 |
| npm.package | 源码组件库名 | String | 否 |
| npm.exportName | 源码组件名称 | String | 否 |
| npm.subName | 子组件名 | String | 否 |
| npm.destructuring | 解构 | Bool | 否 |
| npm.main | 组件路径 | String | 否 |
| npm.version | 源码组件版本号 | String | 否 |
| snippets | 内容为组件不同状态下的低代码 schema (可以有多个),用户从组件面板拖入组件到设计器时会向页面 schema 中插入 snippets 中定义的组件低代码 schema | Object[] | 否 |
| group | 用于描述当前组件位于组件面板的哪个 tab | String | 否 |
| category | 用于描述组件位于组件面板同一 tab 的哪个区域 | String | 否 |
| priority | 用于描述组件在同一 category 中的排序 | String | 否 |
组件属性信息props
| 字段 | 字段描述 | 字段类型 | 允许空 |
|---|---|---|---|
| name | 属性名称 | String | 否 |
| propType | 属性类型 | String/Object | 否 |
| description | 属性描述 | String | 是 |
| defaultValue | 属性默认值 | Any | 是 |
propType 类型参考 PropTypes,存在基本类型和复合类型,描述如下:
基本类型
| propType 值 | 类型描述 | 参考 PropTypes 类型 |
|---|---|---|
| 'array' | 数组类型 | PropTypes.array |
| 'bool' | 布尔类型 | PropTypes.bool |
| 'func' | 函数类型 | PropTypes.func |
| 'number' | 数字类型 | PropTypes.number |
| 'object' | 对象类型 | PropTypes.object |
| 'string' | 字符串类型 | PropTypes.string |
| 'node' | 节点类型 | PropTypes.node |
| 'element' | 元素类型 | PropTypes.element |
| 'any' | 任意值类型 | PropTypes.any |
| { type: 'xxx', isRequired: true } | 指定类型,且是必要属性 | PropTypes.xxxx.isRequired |
复合类型
| propType 值 | 类型描述 | PropTypes 类型 |
|---|---|---|
| { type: 'oneOf', value: ['a', 'b', 'c', '...'] } | 枚举值类型 | PropTypes.oneOf(...) |
| { type: 'oneOfType', value: ['string', 'number', { type: 'array', isRequired: true }] } | 指定类型中的一种,支持递归描述 | PropTypes.oneOfType(...) |
| { type: 'arrayOf', value: 'number' } | 指定统一成员值类型的数组类型 | PropTypes.arrayOf(...) |
| { type: 'objectOf', value: 'string' } | 指定统一对象属性值类型的对象类型 | PropTypes.objectOf(...) |
| { type: 'shape', value: [{ name: 'color', propType: 'string' }, { name: 'fontSize', propType: { type: 'number', isRequied: true } }] } | 指定对象的部分属性名和值类型的对象类型 | PropTypes.shape(...) |
| { type: 'exact', value: [{ name: 'name', propType: 'string' }, { name: 'quantity', propType: 'number' }] } | 严格指定对象全部属性名和值类型的对象类型 | PropTypes.exact(...) |
编辑体验增强 configure
推荐用于优化搭建产品的编辑体验,定制编辑能力的配置信息,通过能力抽象分类,主要包含如下几个维度的配置项:
| 字段 | 字段描述 | 字段类型 | 备注 |
|---|---|---|---|
| props (A) | 属性面板配置 | Array | 用于属性面板能力描述 |
| component(A) | 组件能力配置 | Object | 与组件相关的能力、约束、行为等描述,有些信息可从组件视图实例上直接获取 |
| supports (AA) | 通用扩展配置能力支持性 | Object | 用于通用扩展面板能力描述 |
| advanced (AAA) | 高级特性配置 | Object | 用户可以在这些配置通过引擎上下文控制组件在设计器中的表现,例如自动初始化组件的子组件、截获组件的操作事件进行个性化处理等 |
| 【已废弃】experimental (AAA) | 将引擎的一些实验性特性放在这个配置里 | Object | 用户可以提前体验这些特性 |
属性面板配置 props
props 数组下对象字段描述:
| 字段 | 字段描述 | 字段类型 | 备注 | |||||
|---|---|---|---|---|---|---|---|---|
| type | 指定类型 | Enum | 可选值为 'field' | 'group' ,默认为 'field' | ||||
| display | 指定类型 | Enum | 可选值为 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry' ,默认为 'inline' |
| title | 分类标题 | 属性标题 | String | |||||
| items | 分类下的属性列表 | Array | type = 'group' 生效 | |||||
| name | 属性名 | String | type = 'field' 生效 | |||||
| defaultValue | 默认值 | Any(视字段类型而定) | type = 'field' 生效 | |||||
| supportVariable | 是否支持配置变量 | Boolean | type = 'field' 生效 | |||||
| condition | 配置当前 prop 是否展示 | (target: SettingTarget) => boolean; | - | |||||
| setter | 单个控件(setter)描述,搭建基础协议组件的描述对象,支持 JSExpression / JSFunction / JSSlot | String | Object | Function | type = 'field' 生效 | |||
| extraProps | 其他配置属性(不做流通要求) | Object | 其他配置 | |||||
| extraProps.getValue | setter 渲染时被调用,setter 会根据该函数的返回值设置 setter 当前值 | Function | (target: SettingTarget, value: any) => any; | |||||
| extraProps.setValue | setter 内容修改时调用,开发者可在该函数内部修改节点 schema 或者进行其他操作 | Function | (target: SettingTarget, value: any) => void; |
根据属性值类型 propType,确定对应控件类型 (setter) ,详见 lowcode-engine.cn/docV2/grfyl…
预置setter列表详见
lowcode-engine.cn/docV2/grfyl…
组件能力配置 component
与组件相关的能力、约束、行为等描述,有些信息可从组件视图实例上直接获取,包含如下字段:
| 字段 | 用途 | 类型 | |
|---|---|---|---|
| isContainer(A) | 是否容器组件 | Boolean | |
| isModal(A) | 组件是否带浮层,浮层组件拖入设计器时会遮挡画布区域,此时应当辅助一些交互以防止阻挡 | Boolean | |
| descriptor(A) | 组件树描述信息 | String | |
| nestingRule(A) | 嵌套控制:防止错误的节点嵌套,比如 a 嵌套 a, FormField 只能在 Form 容器下,Column 只能在 Table 下等 | Object | |
| nestingRule.childWhitelist | 子节点类型白名单 | String | Function |
| nestingRule.parentWhitelist | 父节点类型白名单 | String | Function |
| nestingRule.descendantBlacklist | 后裔节点类型黑名单 | String | Function |
| nestingRule.ancestorWhitelist | 祖父节点类型白名单 | String | Function |
| isNullNode(AAA) | 是否存在渲染的根节点 | Boolean | |
| isLayout(AAA) | 是否是layout布局组件 | Boolean | |
| rootSelector(AAA) | 组件选中框的 cssSelector | String | |
| disableBehaviors(AAA) | 用于屏蔽在设计器中选中组件时提供的操作项,默认操作项有 copy、move、remove | String[] | |
| actions(AAA) | 用于详细配置上述操作项的内容 | Object | |
| isMinimalRenderUnit | 是否是最小渲染单元,最小渲染单元下的组件渲染和更新都从单元的根节点开始渲染和更新。如果嵌套了多层最小渲染单元,渲染会从最外层的最小渲染单元开始渲染。 | Boolean |
该段文档运行后只有disableBehaviors生效,其他功能未看看出效果,可能是组件太简单。后续补上
高级功能配置 advanced (AAA)
组件在低代码引擎设计器中的事件回调和 hooks 等高级功能配置,包含如下字段:
| 字段 | 用途 | 类型 | 备注 |
|---|---|---|---|
| initialChildren | 组件拖入“设计器”时根据此配置自动生成 children 节点 schema | NodeData[]/Function NodeData[] | ((target: SettingTarget) => NodeData[]); |
| getResizingHandlers | 用于配置设计器中组件 resize 操作工具的样式和内容 | Function | (currentNode: any) => Array<{ type: 'N' |
| callbacks | 配置 callbacks 可捕获引擎抛出的一些事件,例如 onNodeAdd、onResize 等 | Callback | - |
| callbacks.onNodeAdd | 在容器中拖入组件时触发的事件回调 | Function | (e: MouseEvent, currentNode: any) => any |
| callbacks.onNodeRemove | 在容器中删除组件时触发的事件回调 | Function | (e: MouseEvent, currentNode: any) => any |
| callbacks.onResize | 调整容器尺寸时触发的事件回调,常常与 getResizingHandlers搭配使用 | Function | 详见 Types 定义 |
| callbacks.onResizeStart | 调整容器尺寸开始时触发的事件回调,常常与 getResizingHandlers搭配使用 | Function | 详见 Types 定义 |
| callbacks.onResizeEnd | 调整容器尺寸结束时触发的事件回调,常常与 getResizingHandlers搭配使用 | Function | 详见 Types 定义 |
| callbacks.onSubtreeModified | 容器节点结构树发生变化时触发的回调 | Function | (currentNode: any, options: any) => void; |
| callbacks.onMouseDownHook | 鼠标按下操作回调 | Function | (e: MouseEvent, currentNode: any) => any; |
| callbacks.onClickHook | 鼠标单击操作回调 | Function | (e: MouseEvent, currentNode: any) => any; |
| callbacks.onDblClickHook | 鼠标双击操作回调 | Function | (e: MouseEvent, currentNode: any) => any; |
| callbacks.onMoveHook | 节点被拖动回调 | Function | (currentNode: any) => boolean; |
| callbacks.onHoverHook | 节点被 hover 回调 | Function | (currentNode: any) => boolean; |
| callbacks.onChildMoveHook | 容器节点的子节点被拖动回调 | Function | (childNode: any, currentNode: any) => boolean; |
基础meta配置项
以下是基础的meta配置项,
import { ComponentMetadata, Snippet } from '@alilc/lowcode-types';
const GrtDivMeta: ComponentMetadata = {
"componentName": "GrtDiv",//组件名称
"title": "组件中文名称",//组件中文名称
"description": "组件描述",//组件描述
"docUrl": "www.baidu.com",//组件文档链接
"screenshot": "组件快照",//组件快照
"icon": "组件图标",//组件图标
"tags": "组件标签",//组件标签
"kerwords": "组件关键词,用于搜索联想",//组件关键词,用于搜索联想
"devMode": "proCode",//组件研发模式
"npm": {//npm源引入完整描述对象
"package": "grt-material-demo",//源码组件库名
"version": "0.1.0",//源码组件版本号
"exportName": "GrtDiv",//源码组件名称
"main": "src/index.tsx",//组件路径
"destructuring": true,//解构
"subName": ""//子组件名
},
// "snippets":[],//内容为组件不同状态下的低代码 schema (可以有多个),用户从组件面板拖入组件到设计器时会向页面 schema 中插入 snippets 中定义的组件低代码 schema
"group": "新分组",//用于描述当前组件位于组件面板的哪个 tab
"category": "容器组件",//用于描述组件位于组件面板同一 tab 的哪个区域
"priority": 1,//用于描述组件在同一 category 中的排序
"props": [
{
"name": "value",//属性名称
"propType": "string",//属性类型
"description": "组件属性描述",//属性描述---默认为name值,此例即value
"defaultValue": "默认值"//属性默认值
}
],
"configure": {
"props": [
{
"type": "field",//指定类型,可选值为 `'field' | 'group'` ,默认为 'field'
"display": "inline",//可选值为 `'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry'` ,默认为 'inline'
"title": "分类标题",//分类标题
// // "items": "",//分类下的属性列表,type = 'group' 生效
"name": "value",//属性名 type = 'field' 生效
"defaultValue": "configure下默认值",//默认值, type = 'field' 生效
"supportVariable": true,// 是否支持配置变量,type = 'field' 生效
"condition": () => { return true },//配置当前 prop 是否展示
"setter": "StringSetter",//单个控件(setter)描述,搭建基础协议组件的描述对象,支持 JSExpression / JSFunction / JSSlot type = 'field' 生效
// "extraProps": {//其他配置属性(不做流通要求)
// "getValue": (target, value: any) => { console.log(target) },//setter 渲染时被调用,setter 会根据该函数的返回值设置 setter 当前值
// "setValue": (target, value: any) => { console.log(target) },//setter 内容修改时调用,开发者可在该函数内部修改节点 schema 或者进行其他操作
// },
},
],
"component": {
"isContainer": true,//是否容器组件----需要在tsx中写入chilren属性
"isModal": false,//组件是否带浮层,浮层组件拖入设计器时会遮挡画布区域,此时应当辅助一些交互以防止阻挡
"descriptor": "组件树描述信息",//组件树描述信息
"nestingRule": {//嵌套控制:防止错误的节点嵌套,比如 a 嵌套 a, FormField 只能在 Form 容器下,Column 只能在 Table 下等
// "childWhitelist": ['SelectOption'],//子节点类型白名单
// "parentWhitelist": ["Select", "Table"],//父节点类型白名单
"descendantBlacklist": "",//后裔节点类型黑名单
"ancestorWhitelist": ""//祖父节点类型白名单
},
"isNullNode": true,//是否存在渲染的根节点
// "isLayout": false,//是否是layout布局组件
"rootSelector": "",//组件选中框的 cssSelector
"disableBehaviors": ["copy"],//用于屏蔽在设计器中选中组件时提供的操作项,默认操作项有 copy、move、remove String[]
"actions": {//用于详细配置上述操作项的内容
"name": "copy", // string;
"content": "+", // string | ReactNode | ActionContentObject;
"items": [], // ComponentAction[];
"condition": 'always', // boolean | ((currentNode: any) => boolean) | 'always';
"important": true // boolean;
},
"isMinimalRenderUnit": false//是否是最小渲染单元,最小渲染单元下的组件渲染和更新都从单元的根节点开始渲染和更新。如果嵌套了多层最小渲染单元,渲染会从最外层的最小渲染单元开始渲染。
},
"supports": {//支持的事件枚举
"events": ["onClick", "onChange", "onTest"],//支持事件列表
"loop": true,//支持循环设置
"condition": true,//支持条件设置
"style": true//支持样式设置
},
"advanced": {
// "initialChildren": () => {
// return 'link'
// },//组件拖入“设计器”时根据此配置自动生成 children 节点 schema
"getResizingHandlers": () => {
return ["E"];
},//用于配置设计器中组件 resize 操作工具的样式和内容
"callbacks": {//配置 callbacks 可捕获引擎抛出的一些事件,例如 onNodeAdd、onResize 等
"onNodeAdd": (e, currentNode) => {//在容器中拖入组件时触发的事件回调
console.log(e, currentNode)
},
"onNodeRemove": (e, currentNode) => {//在容器中删除组件时触发的事件回调
console.log(e, currentNode)
},
"onResize": (e, currentNode) => {//调整容器尺寸时触发的事件回调,常常与 getResizingHandlers搭配使用
console.log(e, currentNode)
},
"onResizeStart": (e, currentNode) => {//调整容器尺寸开始时触发的事件回调,常常与 getResizingHandlers搭配使用
console.log(e, currentNode)
},
"onResizeEnd": (e, currentNode) => {//调整容器尺寸结束时触发的事件回调,常常与 getResizingHandlers搭配使用
console.log(e, currentNode)
},
"onSubtreeModified": (e, currentNode) => {//容器节点结构树发生变化时触发的回调
console.log(e, currentNode)
},
"onMouseDownHook": (e, currentNode) => {//鼠标按下操作回调
console.log(e, currentNode)
},
// "onClickHook": (e, currentNode) => {//鼠标单击操作回调
// console.log(e, currentNode)
// },
"onDblClickHook": (e, currentNode) => {//鼠标双击操作回调
console.log(e, currentNode)
},
"onMoveHook": (e, currentNode) => {//节点被拖动回调
console.log(e, currentNode)
},
"onHoverHook": (e, currentNode) => {//节点被 hover 回调
console.log(e, currentNode)
},
"onChildMoveHook": (e, currentNode) => {//容器节点的子节点被拖动回调
console.log(e, currentNode)
},
},//
},
}
};
const snippets: Snippet[] = [
{
"title": "GrtDiv",
"screenshot": "",
"schema": {
"componentName": "GrtDiv",
"props": {}
}
}
];
export default {
...GrtDivMeta,
snippets
};
\
window下搭建物料库环境
引擎提供的cli未对windows进行适配,所以在windows上开发需要单独配置,配置方法如下两种
修改插件源码:
详见 mp.weixin.qq.com/s/lVVzYF5dd…
搭建WSL环境
除了修改源码的方式还可以在windows上搭建wsl环境来开发物料库,具体步骤如下
1、 安装wsl,docs.microsoft.com/zh-cn/windo…
2、 打开linux窗口,安装node环境。推荐使用nvm安装node,安装nvm ,运行如下命令
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
有可能因为速度慢,安装不上,可以配置host
host 185.199.111.133 raw.githubusercontent.com
通过nvm文档安装node
nvm install 14.17.0
运行nvm list 查看当前node版本List,通过nvm use 14.17.0 ,切换到指定版本