赞
踩
github:https://github.com/li-car-fei/react-visual-design
参考低代码实现:
https://github.com/quarkcms/quark-ui
https://github.com/react-visual-design/react-visual-design
图显示组件:
https://github.com/crubier/react-graph-vis
edit
界面需要完成信息的传递工作,因此需要将组件数据注册在这里,组件操作所有相关函数都写在这里,以便通信之后完成数据的改写操作/visual-page/checked-comp
完成/mobile_components
完成页面渲染,对应的数据操作都window.parent.postMessage
传递到上层,上层完成对应数据的修改操作/mobile_components
封装好的传入data
进行渲染/mobile_components
预先写好的schema.json
配合formily
进行配置,表单组件根据新建的属性与配置完成渲染由于使用Iframe进行信息的传递,因此所有操作方法和数据可以都放在上层主页面中,将一个通过switch case
的列举函数传入子展示组件则可以完成所有操作:
const handleEditItemClick = ({ id, compDefaultData }) => {
if (id !== activeCompId) {
const matchComp = find(selectedList, { id })
matchComp.data = matchComp.data || compDefaultData
propFormIns = createForm()
propFormIns.setValues(_.cloneDeep(matchComp.data), 'overwrite')
// return this.setState() before
SetActiveCompId(id)
setSelectedList([...selectedList])
}
}
const handleDrop = ({ index, name }) => {
const id = v4()
setSelectedList([...(selectedList.splice(index, 0, { name, id }))])
}
const onReceiveMessage = e => {
try {
if (e.data.toString() !== '[object Object]') {
const data = JSON.parse(e.data)
switch (data.func) {
case 'handleDrop':
handleDrop(data.params)
break;
case 'handleEditItemClick':
handleEditItemClick(data.params)
break;
case 'handleOperateItem':
handleOperateItem(data.params)
break;
default:
break
}
}
} catch (err) {
console.error(err)
}
}
通过JsonSchema格式的数据进行配置,而通过一个遍历算法将配置转换为对应的组件,即可完成;
如下的配置:
export default {
'mobile_demo': {
body: [
{
component: 'NavBar',
data: {"title": "页面标题", "mode": "light"}
},
{
component: 'Image',
data: {"src": "", "link": "https://github.com/react-visual-design/react-visual-design"}
},
{
component: 'RichText',
data: { "content": "富文本编辑器" }
},
{
component: 'none_comp',
data: '11111111'
}
]
}
}
经过匹配算法与展示页面的简单map()
:
// 匹配算法
import * as VisualDesignComponents from '@/mobile_components'
export const componentRender = (body: any, data, callback) => {
if (body === null || body === undefined) {
return null;
}
if (typeof body === 'string' || typeof body === 'number') {
return body;
}
const components = body.map((item: any) => {
if (VisualDesignComponents[item.component]) {
const Comp = VisualDesignComponents[item.component]
return {Comp, data: item.data}
}
return { Comp: 'none_comp', data: item.data }
});
return components
}
// 展示页面map
function Render(props: any) {
const components = componentRender(props.body, props.data, props.callback)
return (
(typeof components === 'string') ? (
<span dangerouslySetInnerHTML={{ __html: components }} />
) : (
map(components, (item, index) => {
if(item.Comp === 'none_comp'){
return (<div key={ `index-null` } style={{ 'padding': '12px 0', 'textAlign': 'center', 'background': 'lightgray' }}>
该组件不存在: { item.data}
</div>)
}
const Comp = item.Comp;
return (<Comp data={item.data} key={ `index-${ index}` }></Comp>)
})
)
)
}
渲染结果:
此页面原理与可拖拽低代码编辑页面相似,将图数据及其操作函数放在上层页面,而将实时数据与switch case
操作函数传到子展示组件
支持增加,删除,连接以及信息编辑操作,后续会继续扩展
基于sketch2code模型,将模型输出的dsl解析,融入此项目
例子简单,仅跑通作为学习用
欢迎指正与讨论
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。