表单设计器整体思路
1、从数据局出发
2、从表单出发
3、拖动布局
grid布局还是flex布局实现呢?grid布局整体上更明快,flex方便一步步推进,2种方式也许都实现一遍,进行比对后再下结论。
前端形成模板后 怎么保存
保存整个模板?还是把结构分解描述为一个个字段保存到数据库?
从表单出发的页面设计器

数据可以和表单元素绑定:

(元数据来源:)
既然需要和数据元素绑定,必须有一套元数据描述体系作为支撑。
元数据描述怎么来:
1、手工维护(不动态生成数据库table)
2、反射取得数据库表信息(能维护吗)
拖动到右边画布的动作?
通过行、列解决整体布局的问题
可能涉及如下操作dom方法?
1、html5 antd
2、react 操作dom
3、js 操作dom
4、es6 操作dom
5、react jquery 混用(最好不这样)
用flex布局,Row的主轴设成列 Col的主轴设置成行?
行列交叉进行
整个布局为,左边设置工具栏,中间是画布,右边是属性栏目
整个动态布局背后是个树形结构,render方法,即使根据这个结构形成
全页面采取flex布局,层层嵌套(行、列交互嵌套)
每一个元素都是flex: 行元素必然放在列元素当中
列元素 必然放到行元素当中
每个元素都是flex元素 flex display
row 元素
- flex-direction: column
column 元素:
flex-direction: row
初始化的时候,只能放row,画布director 方向为column

(整个布局为,左边设置工具栏,中间是画布,右边是属性栏目)
初始化的时候,只留一个div,这个div不可删除
<Button type="primary" shape="circle"
style={
{display: node.id=="1"? "none": "" }}
size="smaill" onClick={()=>removeNode(_id)}>
D
</Button>
工具栏:
工具栏布局后期可能需要改进,按grid 或者flex进行修正?
<div style={ tool_area }>
<PageHeader
className="site-page-header"
title="工具"
/>
<div style={textAlign}>
<IconFont id="rowIcon" type="icon-rows" onDragStart={onDrop} draggable="true"></IconFont>
</div>
<div style={textAlign}>
<IconFont id="colIcon" type="icon-column" onDragStart={onDrop} draggable="true"></IconFont>
</div>
<div style={textAlign}>
<IconFont id="input" type="icon-input"></IconFont>
</div>
<div style={textAlign}>
<IconFont id="input1" type="icon-input1"></IconFont>
</div>
</div>
拖放工具栏的图标,放在目标元素上的时候:
const drop=(event)=>
{
let _id=event.currentTarget.id
// 根据id找到树种的节点
//给这个节点赋予新的子节点
let newLayoutTree = deepCopy(layoutTree);
let n=queryNode(newLayoutTree,_id);
if(n==null || n==undefined){
return;
}
if(n.layoutType==null || n.layoutType==undefined){
return;
}
if(!(n.layoutType==1 || n.layoutType==2)){
return;
}
let newNode=null;
let _nodeId = newGuid();
if(n.layoutType==1){
newNode = new LayoutTreeNode(_nodeId,_nodeId,n.id,_nodeId,2,1,[]); //布局树
}else if(n.layoutType==2){
newNode = new LayoutTreeNode(_nodeId,_nodeId,n.id,_nodeId,1,1,[]); //布局树
}
n.children.push({...newNode});
//设置
console.log(newLayoutTree)
setLayoutTree(newLayoutTree);
stopBubbling(event)
}
这里需要注意的是,必须对原来的存放在state中的数据。进行deep copy,否则,render的时候,感知不到数据的变化。删除元素的时候,也面临似的问题,同样需要deep copy。
完整代码如下:
//动态表单设计器
import React, {useState} from 'react';
import {Button, Form, Input, message, PageHeader} from 'antd';
import {createFromIconfontCN} from '@ant-design/icons';
const ROW_TYPE=1; //行类型
const COL_TYPE=2; //列类型
//export default class Dynamic_Form_Designer2 extends Component {
export default function Dynamic_Form_Designer2(prop) {
const [form] = Form.useForm();
/**flexGrow :flex grow 值**/
const getRowLayoutStyle=(flexGrow)=>{
return {flex: flexGrow+" 1 auto",
// border: "1px solid #cccccc",
paddingTop:"1em",paddingLeft:"0.3em",paddingRight:"1em",paddingBottom:"1em",
margin:"0.5em",backgroundColor:"RGB(172,216,230)",boxSizing: "border-box",
display:"flex",
flexDirection:"row"
}
}
const getColLayoutStyle=(flexGrow)=>{
return {

本文介绍了一款采用flex布局的表单设计器实现思路,着重探讨了如何通过拖拽元素完成表单设计,并介绍了表单元素与数据绑定的方法。文章还讨论了布局树的构建与更新、表单模板的保存方式以及与元数据的交互。
最低0.47元/天 解锁文章
778

被折叠的 条评论
为什么被折叠?



