使用渲染模块
快速使用
渲染依赖于 schema 和 components。其中 schema 和 components 需要一一对应,schema 中使用到的组件都需要在 components 中进行声明,否则无法正常渲染。
简单示例
import ReactRenderer from '@alilc/lowcode-react-renderer';
import ReactDOM from 'react-dom';
import { Button } from '@alifd/next';
const schema = {
componentName: 'Page',
props: {},
children: [
{
componentName: 'Button',
props: {
type: 'primary',
style: {
color: '#2077ff'
},
},
children: '确定',
},
],
};
const components = {
Button,
};
ReactDOM.render((
<ReactRenderer
schema={schema}
components={components}
/>
), document.getElementById('root'));
- rax-renderer:npm 包替换为 @alilc/lowcode-rax-renderer
项目使用示例
设计器 demo:https://lowcode-engine.cn/demo
项目代码完整示例:https://github.com/alibaba/lowcode-demo
step 1:在设计器中获取组件列表
import { material, project } from '@alilc/lowcode-engine';
const packages = material.getAssets().packages
step 2:在设计器中获取当前配置页面的 schema
import { material, project } from '@alilc/lowcode-engine';
const schema = project.exportSchema();
step 3:以某种方式存储 schema 和 packages
这里用 localStorage 作为存储示例,真实项目中使用数据库或者其他存储方式。
window.localStorage.setItem(
'projectSchema',
JSON.stringify(project.exportSchema())
);
const packages = await filterPackages(material.getAssets().packages);
window.localStorage.setItem(
'packages',
JSON.stringify(packages)
);
step 4:预览时,获取存储的 schema 和 packages
const packages = JSON.parse(window.localStorage.getItem('packages') || '');
const projectSchema = JSON.parse(window.localStorage.getItem('projectSchema') || '');
const { componentsMap: componentsMapArray, componentsTree } = projectSchema;
step 5:通过整合 schema 和 packages 信息,进行渲染
import ReactDOM from 'react-dom';
import React, { useState } from 'react';
import { Loading } from '@alifd/next';
import { buildComponents, assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils';
import ReactRenderer from '@alilc/lowcode-react-renderer';
import { injectComponents } from '@alilc/lowcode-plugin-inject';
const SamplePreview = () => {
const [data, setData] = useState({});
async function init() {
// 渲染前置处理,初始化项目 schema 和资产包为渲染模块所需的 schema prop 和 components prop
const packages = JSON.parse(window.localStorage.getItem('packages') || '');
const projectSchema = JSON.parse(window.localStorage.getItem('projectSchema') || '');
const { componentsMap: componentsMapArray, componentsTree } = projectSchema;
const componentsMap: any = {};
componentsMapArray.forEach((component: any) => {
componentsMap[component.componentName] = component;
});
const schema = componentsTree[0];
const libraryMap = {};
const libraryAsset = [];
packages.forEach(({ package: _package, library, urls, renderUrls }) => {
libraryMap[_package] = library;
if (renderUrls) {
libraryAsset.push(renderUrls);
} else if (urls) {
libraryAsset.push(urls);
}
});
const vendors = [assetBundle(libraryAsset, AssetLevel.Library)];
const assetLoader = new AssetLoader();
await assetLoader.load(libraryAsset);
const components = await injectComponents(buildComponents(libraryMap, componentsMap));
setData({
schema,
components,
});
}
const { schema, components } = data;
if (!schema || !components) {
init();
return <Loading fullScreen />;
}
return (
<div className="lowcode-plugin-sample-preview">
<ReactRenderer
className="lowcode-plugin-sample-preview-content"
schema={schema}
components={components}
/>
</div>
);
};
ReactDOM.render(<SamplePreview />, document.getElementById('ice-container'));
API
参数 | 说明 | 类型 | 必选 |
schema | 符合搭建协议的数据 | Object | 是 |
components | 组件依赖的实例 | Object | 是 |
componentsMap | 组件的配置信息 | Object | 否 |
appHelper | 渲染模块全局上下文 | Object | 否 |
designMode | 设计模式,可选值:extend、border、preview | String | 否 |
suspended | 是否挂起 | Boolean | 否 |
onCompGetRef | 组件 ref 回调(schema, ref)=> {} | Function | 否 |
onCompGetCtx | 组件 ctx 更新回调 (schema, ctx) => {} | Function | 否 |
rendererName | 渲染类型,标识当前模块是以什么类型进行渲染的 | string | 否 |
customCreateElement | 自定义创建 element 的钩子 (Component, props, children) => {} | Function | 否 |
schema
搭建基础协议数据,渲染模块将基于 schema 中的内容进行实时渲染。
components
渲染模块渲染页面需要用到的组件依赖的实例,components
对象中的 Key 需要和搭建 schema 中的componentName
字段对应。
componentsMap
在生产环境下不需要设置。
配置规范参见《低代码引擎搭建协议规范》,主要在搭建场景中使用,用于提升用户搭建体验。
- 属性配置校验:用户可以配置组件特定属性的
propTypes
,在搭建场景中用户输入的属性值不满足propType
配置时,渲染模块会将当前属性设置为undefined
,避免组件抛错导致编辑器崩溃; isContainer
标记:当组件被设置为容器组件且当前容器组件内没有其他组件时,用户可以通过拖拽方式将组件直接添加到容器组件内部;parentRule
校验:当用户使用的组件未出现在组件配置的parentRule
组件内部时,渲染模块会使用visualDom
组件进行占位,避免组件抛错的同时在下钻编辑场景也能够不阻塞用户配置,典型的场景如Step.Item
、Table.Column
、Tab.Item
等等。
appHelper
appHelper 主要用于设置渲染模块的全局上下文,目前 appHelper 支持设置以下上下文:
utils
:全局公共函数constants
:全局常量location
:react-router 的location
实例history
:react-router 的history
实例
设置了 appHelper 以后,上下文会直接挂载到容器组件的 this 上,用户可以在搭建协议中的 function 及变量表达式场景使用上下文,具体使用方式如下所示:
schema:
export default {
"componentName": "Page",
"fileName": "test",
"props": {},
"children": [{
"componentName": "Div",
"props": {},
"children": [{
"componentName": "Text",
"props": {
"text": {
"type": "JSExpression",
"value": "this.location.pathname"
}
}
}, {
"componentName": "Button",
"props": {
"type": "primary",
"style": {
"marginLeft": 10
},
"onClick": {
"type": "JSExpression",
"value": "function onClick(e) { this.utils.xxx(this.constants.yyy);}"
}
},
"children": "click me"
}]
}]
}
import ReactRenderer from '@alilc/lowcode-react-renderer';
import ReactDOM from 'react-dom';
import { Button } from '@alifd/next';
import schema from './schema'
const components = {
Button,
};
ReactDOM.render((
<ReactRenderer
schema={schema}
components={components}
appHelper={{
utils: {
xxx: () => {}
}
}}
/>
), document.getElementById('root'));
designMode
在生产环境下不需要设置。
designMode 属性主要在搭建场景中使用,主要有以下作用:
- 当
designMode
改变时,触发当前 schema 中所有组件重新渲染 - 当
designMode
设置为extend
或border
时,渲染模块会为Dialog
、Overlay
等初始状态无 dom 渲染的组件外层包裹一层 div,使其在画布中能够展示边框供用户选中 - 当
designMode
有值时,容器组件每次 render 都会更新自定义方法的绑定
suspended
渲染模块是否挂起,当设置为 true
时,渲染模块最外层容器的 shouldComponentUpdate
将始终返回false,在下钻编辑或者多引擎渲染的场景会用到该参数。
onCompGetRef
组件 ref 的回调,在搭建场景下编排模块可以根据该回调获取组件实例并实现生命周期注入或者组件 DOM 操作等功能,回调函数主要包含两个参数:
schema
: 当前组件的 schema 模型结构ref
:当前组件的 ref 实例
onCompGetCtx
组件 ctx 更新的回调,在组件每次 render 渲染周期我们都会为组件构造新的上下文环境,因此该回调函数会在组件每次 render 过程中触发,主要包含两个参数:
schema
:当前组件的 schema 模型结构ctx
:当前组件的上下文信息,主要包含以下内容:page
:当前页面容器实例this
: 当前组件所属的容器组件实例item
/index
: 循环上下文(属性 key 可以根据 loopArgs 进行定制)form
: 表单上下文
rendererName
渲染类型,标识当前模块是以什么类型进行渲染的
LowCodeRenderer
: 低代码组件PageRenderer
: 页面
customCreateElement
自定义创建 element 的钩子,用于在渲染前后对组件进行一些处理,包括但不限于增加 props、删除部分 props。主要包含三个参数:
Component
:要渲染的组件props
:要渲染的组件的 propschildren
:要渲染的组件的子元素