react 低代码图编辑探索

主要实现

  1. 基于react可拖拽低代码实现
  2. 基于图展示组件的图编辑实现
  3. 基于JsonSchema的低代码展示实现

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

低代码可拖拽流程实现原理

react 低代码图编辑探索_第1张图片

  • edit界面需要完成信息的传递工作,因此需要将组件数据注册在这里,组件操作所有相关函数都写在这里,以便通信之后完成数据的改写操作
  • 中间的显示通过Iframe完成,而Iframe组件只负责新建iframe并完成信息的传递,实际页面显示是通过路由定向到/visual-page/checked-comp完成
  • 对应的页面则依靠Drop与/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的低代码展示实现

通过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>)
  
      })
    )
  )
}

渲染结果:
react 低代码图编辑探索_第2张图片

基于图展示组件的图编辑实现

此页面原理与可拖拽低代码编辑页面相似,将图数据及其操作函数放在上层页面,而将实时数据与switch case操作函数传到子展示组件

react 低代码图编辑探索_第3张图片
支持增加,删除,连接以及信息编辑操作,后续会继续扩展

结束

欢迎指正与讨论

你可能感兴趣的:(前端知识记录,react.js,前端,javascript,umi,数据结构)