antd designable平臺的組件拖拽功能實現(xiàn)代碼
平臺:designable設(shè)計器
github:designable
1 背景
由于業(yè)務(wù)需求,我們需要實現(xiàn)designable平臺的一個簡易版的組件拖拽功能。
- 拖拽區(qū)域
- 渲染組件列表,包括組件的名稱和icon
- 組件可以拖動
- 放置區(qū)域
- 拖動后的組件可以放置,并且放置區(qū)域的組件依舊存在
- 放置區(qū)域的組件可以正確渲染相應(yīng)樣式,使用formily的schema json渲染
- 放置區(qū)域的組件可以上下移動排序,同時可以進(jìn)行刪除和編輯操作
2 技術(shù)棧
antd
formily:表單引擎,可以根據(jù)schema json直接渲染表單
react-beautiful-dnd:常用于列表的拖拽,支持排序
react-dnd:拖拽和放置功能,比如上面截圖的組件拖拽
3 組件拖拽和放置
3.1 類型定義
右側(cè)組件類型:id唯一標(biāo)識,scheme存放渲染表單的json文件
export interface ComponentConfig { id?: string; // 唯一標(biāo)識,隨機(jī)生成,且不可更改 key: string; // 表單字段key,用戶可以更改 title: string; // 拖拽區(qū)域的文案,不可更改 component_type: ComponentType; // RN側(cè)的組件標(biāo)識,不可更改 schema: ISchema; } export enum ComponentType { TextInputRow = 'TextInputRow', // 文本輸入框 DateInputRow = 'DateInputRow', // 時間選擇器 CheckBox = 'CheckBox', }
右側(cè)組件列表:
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側(cè)的組件名稱,必須要保持一致 }, }, { 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實現(xiàn)拖拽能力的構(gòu)子
- 請求參數(shù):
- type: 指定元素的類型,只有 類型相同的元素 才能進(jìn)行drop操作
- item: 元素在拖拽過程中,描述該對象的數(shù)據(jù)??梢栽趗seDrop中的drop接收到該數(shù)據(jù)
- collect: 返回一個描述狀態(tài)的普通對象,然后返回以注入到組件中。它接收兩個參數(shù),一個DragTargetMonitor實例和拖拽元素描述信息item
- 返回參數(shù):
- 第一個返回值:是一個對象 表示關(guān)聯(lián)在拖拽過程中的變量,需要在傳入useDrag的規(guī)范方法的collect屬性中進(jìn)行映射綁定, 比如:isDraging, canDrag等
- 第二個返回值: 代表拖拽元素的ref
- 第三個返回值: 代表拖拽元素拖拽后實際操作到的dom
// 用于包裹每一個可以拖拽的組件 export const WrapComponent = (props: DndComponentDndItem) => { const [, drag] = useDrag(() => ({ type: ItemTypes.CARD, item: props.config, // collect中可以監(jiān)控drag狀態(tài)變更,并把狀態(tài)暴露給組件 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 放置
- 請求參數(shù):
- type: 指定元素的類型,只有 類型相同的元素 才能進(jìn)行drop操作
- item: 元素在拖拽過程中,描述該對象的數(shù)據(jù)。可以在useDrop中的drop接收到該數(shù)據(jù)
- collect: 返回一個描述狀態(tài)的普通對象,然后返回以注入到組件中。它接收兩個參數(shù),一個DragTargetMonitor實例和拖拽元素描述信息item
- 返回參數(shù):
- 第一個返回值:是一個對象 表示關(guān)聯(lián)在拖拽過程中的變量,需要在傳入useDrag的規(guī)范方法的collect屬性中進(jìn)行映射綁定, 比如:isDraging, canDrag等
- 第二個返回值: 代表拖拽元素的ref
- 第三個返回值: 代表拖拽元素拖拽后實際操作到的dom
到此這篇關(guān)于antd designable平臺的組件拖拽功能的文章就介紹到這了,更多相關(guān)antd designable組件拖拽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中隨機(jī)數(shù)方法?Math.random()
這篇文章主要介紹了JavaScript中隨機(jī)數(shù)方法?Math.random(),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06JavaScript中的函數(shù)申明、函數(shù)表達(dá)式、箭頭函數(shù)
js中的函數(shù)可以通過幾種方式創(chuàng)建,具體創(chuàng)建方法通過實例代碼給大家介紹的非常詳細(xì),文中通過例子給大家介紹了函數(shù)聲明和表達(dá)式之間的差別,感興趣的朋友跟隨小編一起看看吧2019-12-12Bootstrap基本組件學(xué)習(xí)筆記之分頁(12)
這篇文章主要為大家詳細(xì)介紹了Bootstrap基本組件學(xué)習(xí)筆記之分頁,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12