antd designable平台的组件拖拽功能实现代码
作者:a堅強的泡沫
这篇文章主要介绍了antd designable平台的组件拖拽功能实现代码,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
平台:designable设计器
github:designable
1 背景
由于业务需求,我们需要实现designable平台的一个简易版的组件拖拽功能。
- 拖拽区域
- 渲染组件列表,包括组件的名称和icon
- 组件可以拖动
- 放置区域
- 拖动后的组件可以放置,并且放置区域的组件依旧存在
- 放置区域的组件可以正确渲染相应样式,使用formily的schema json渲染
- 放置区域的组件可以上下移动排序,同时可以进行删除和编辑操作
2 技术栈
antd
formily:表单引擎,可以根据schema json直接渲染表单
react-beautiful-dnd:常用于列表的拖拽,支持排序
react-dnd:拖拽和放置功能,比如上面截图的组件拖拽
3 组件拖拽和放置
3.1 类型定义
右侧组件类型:id唯一标识,scheme存放渲染表单的json文件
export interface ComponentConfig { id?: string; // 唯一标识,随机生成,且不可更改 key: string; // 表单字段key,用户可以更改 title: string; // 拖拽区域的文案,不可更改 component_type: ComponentType; // RN侧的组件标识,不可更改 schema: ISchema; } export enum ComponentType { TextInputRow = 'TextInputRow', // 文本输入框 DateInputRow = 'DateInputRow', // 时间选择器 CheckBox = 'CheckBox', }
右侧组件列表:
export const ComponentConfigs: ComponentConfig[] = [ { key: ComponentType.TextInputRow, schema: { title: ComponentType.TextInputRow, type: 'string', 'x-component': 'Input', 'x-decorator': 'FormItem', 'x-rn-component': ComponentType.TextInputRow, // RN侧的组件名称,必须要保持一致 }, }, { key: ComponentType.DateInputRow, schema: { title: ComponentType.DateInputRow, type: 'string', 'x-component': 'DatePicker', 'x-decorator': 'FormItem', 'x-rn-component': ComponentType.DateInputRow, }, }, { key: ComponentType.CheckBox, schema: { title: ComponentType.CheckBox, type: 'string', 'x-component': 'Checkbox', 'x-decorator': 'FormItem', 'x-rn-component': ComponentType.CheckBox, }, }, ].map((i) => ({ ...i, title: i.key, component_type: i.key }));
3.2 拖拽
useDrag
:让DOM实现拖拽能力的构子
- 请求参数:
- type: 指定元素的类型,只有 类型相同的元素 才能进行drop操作
- item: 元素在拖拽过程中,描述该对象的数据。可以在useDrop中的drop接收到该数据
- collect: 返回一个描述状态的普通对象,然后返回以注入到组件中。它接收两个参数,一个DragTargetMonitor实例和拖拽元素描述信息item
- 返回参数:
- 第一个返回值:是一个对象 表示关联在拖拽过程中的变量,需要在传入useDrag的规范方法的collect属性中进行映射绑定, 比如:isDraging, canDrag等
- 第二个返回值: 代表拖拽元素的ref
- 第三个返回值: 代表拖拽元素拖拽后实际操作到的dom
// 用于包裹每一个可以拖拽的组件 export const WrapComponent = (props: DndComponentDndItem) => { const [, drag] = useDrag(() => ({ type: ItemTypes.CARD, item: props.config, // collect中可以监控drag状态变更,并把状态暴露给组件 collect: (monitor) => ({ isDragging: !!monitor.isDragging() }), })); return ( <div style={{ width: 100, // todo: 卡片无法居中 cursor: 'move', height: 50, display: 'flex', justifyContent: 'center', alignItems: 'center', backgroundColor: 'white', borderRadius: 4, }} ref={drag} // dom元素实例 > {props.children} </div> ); };
3.3 放置
- 请求参数:
- type: 指定元素的类型,只有 类型相同的元素 才能进行drop操作
- item: 元素在拖拽过程中,描述该对象的数据。可以在useDrop中的drop接收到该数据
- collect: 返回一个描述状态的普通对象,然后返回以注入到组件中。它接收两个参数,一个DragTargetMonitor实例和拖拽元素描述信息item
- 返回参数:
- 第一个返回值:是一个对象 表示关联在拖拽过程中的变量,需要在传入useDrag的规范方法的collect属性中进行映射绑定, 比如:isDraging, canDrag等
- 第二个返回值: 代表拖拽元素的ref
- 第三个返回值: 代表拖拽元素拖拽后实际操作到的dom
到此这篇关于antd designable平台的组件拖拽功能的文章就介绍到这了,更多相关antd designable组件拖拽内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!