react拖拽react-beautiful-dnd一維數(shù)組二維數(shù)組拖拽功能
寫在前邊,二維數(shù)組可以拖拽,但是不可以編輯+拖拽,如果想要實現(xiàn)編輯+拖拽,還是需要轉換成一維數(shù)組。原因是因為插件的官方規(guī)定,在拖拽過程中不可以編輯Droppable層的Props。
相關地址:
中文文檔地址
react-beautiful-dnd - 《react-beautiful-dnd 中文文檔幫助手冊教程》 - 極客文檔 (geekdaxue.co)
git源碼
GitHub - chinanf-boy/react-beautiful-dnd-zh: ????翻譯: react-beautiful-dnd 文檔 ?? 更新 ?
使用
安裝
# yarn yarn add react-beautiful-dnd # npm npm install react-beautiful-dnd --save
引入
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
引用
<DraggableList data={listDemo}></DraggableList>
一維數(shù)組使用
傳參data是一維數(shù)組
import React, { useEffect, useState } from 'react'; import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; interface Props { data: any[]; } const DraggableList: React.FC<Props> = ({ data }) => { const [sortList, setSortList] = useState([]); const getItems = () => { const arr = Array.from({ length: 10 }, (v, k) => k).map((k) => ({ id: `item-${k}`, content: `item ${k}`, })); setSortList(arr); }; useEffect(() => { getItems(); }, []); const grid = 8; const getItemStyle = (isDragging, draggableStyle) => ({ // some basic styles to make the items look a bit nicer userSelect: 'none', padding: grid * 2, margin: `0 ${grid}px 0 0`, // change background colour if dragging background: isDragging ? 'lightgreen' : 'grey', // styles we need to apply on draggables ...draggableStyle, }); const getListStyle = (isDraggingOver: any) => ({ background: isDraggingOver ? 'lightblue' : 'lightgrey', display: 'flex', padding: grid, overflow: 'auto', }); const onDragEnd = (result) => { if (!result.destination) { return; } console.log('end', sortList, result); const res = sortList.filter((item) => item); // 更改引用地址 console.log('移動前res', res); const [removed] = res.splice(result.source.index, 1); console.log('刪除???', removed); res.splice(result.destination.index, 0, removed); console.log('添加后', res); setSortList(res); }; console.log('data', data); /** * Draggable組件可以拖動并拖放到其Droppables上. 一個Draggable必須始終包含在一個Droppable. * 它是 可能重新排序Draggable在其Droppable家中或移動到另一個Droppable. * 一個Draggable必須包含在一個Droppable. * */ return ( <DragDropContext onDragEnd={onDragEnd}> <Droppable droppableId="droppable" direction="horizontal"> {(provided, snapshot) => ( <div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)} {...provided.droppableProps}> {sortList.map((item, index) => ( <Draggable key={item.id} draggableId={item.id} index={index}> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)} > {item.content} </div> )} </Draggable> ))} {provided.placeholder} </div> )} </Droppable> </DragDropContext> ); }; export default DraggableList;
二維數(shù)組的使用
import React, { useEffect, useState } from 'react'; import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; interface Props { data: any[]; } const DraggableList: React.FC<Props> = ({ data = [] }) => { const [sortList, setSortList] = useState(data); const grid = 8; const getItemStyle = (isDragging, draggableStyle) => ({ // some basic styles to make the items look a bit nicer userSelect: 'none', padding: grid * 2, margin: `0 ${grid}px 0 0`, // change background colour if dragging background: isDragging ? 'lightgreen' : 'grey', // styles we need to apply on draggables ...draggableStyle, }); const getListStyle = (isDraggingOver) => ({ background: isDraggingOver ? 'lightblue' : 'lightgrey', display: 'flex', padding: grid, overflow: 'auto', }); const onDragEnd = (result) => { if (!result.destination) { return; } console.log('end', sortList, result); const res = sortList.filter((item) => item); //修改引用地址 console.log('res', res); const [removed] = res.splice(result.source.index, 1); console.log('刪除???', removed); res.splice(result.destination.index, 0, removed); console.log('添加后', res); setSortList(res); }; useEffect(() => { setSortList(data); }, [data]); console.log('data', data); return ( <DragDropContext onDragEnd={onDragEnd}> {sortList.map((item, index) => { return ( <Droppable droppableId={'droppable' + index} key={index} direction="vertical"> {(provided, snapshot) => ( <div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)} {...provided.droppableProps}> {/*{data.map((item, index) => (*/} <Draggable key={item[0].value} draggableId={item[0].value} index={index}> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)} > {66666 + item[0].label} </div> )} </Draggable> {/*))}*/} {provided.placeholder} </div> )} </Droppable> ); })} </DragDropContext> ); }; export default DraggableList;
組件傳值的數(shù)組內容
const [options, setOptions] = useState([ { label: '延時時間', value: 'delayTime', children: [ { label: '時', value: 'hour', disabled: false, }, { label: '分', value: 'minute', disabled: false, }, { label: '秒', value: 'second', disabled: false, }, ], }, { label: '限制類型', value: 'limitType', children: [ { label: '前置點位1', value: '1', disabled: false, }, { label: '前置點位2', value: '2', disabled: false, }, { label: '前置點位3', value: '3', disabled: false, }, ], }, { label: '溫度', value: 'templete', }, ]);
案列
案例是通過級聯(lián)的組件選擇條件,新增條件時,前端重新定義數(shù)據(jù)格式,將二維的結構改成一維數(shù)組的結構。遍歷填充內容時,是在Droppable的下一級,所以可以修改內容。
const onDispatchValue = (res: any) => { dispatch({ type: `${MODEL_NAME}/save`, payload: { proTypeList: res, }, }); }; // 新增、刪除前置條件 const [inputFlag, setInputFlag] = useState(false); const [listDemo, setListDemo] = useState([]); const changeCondition = (ids, option) => { let arr2 = []; // 第三層關系選中兩個時的判斷 if (ids && ids.length > 1) { // 二維數(shù)組結構成一維數(shù)組,方便去重 arr2 = ids.reduce((a, b) => { return a.concat(b); }); const arr3 = Array.from(new Set(arr2)); if (arr2.length !== arr3.length) { setRepeatFlag(true); return message.warning('前置條件重復,請刪除!'); } else { setRepeatFlag(false); } } // 沒有子級或者全選的判斷 ids.map((item, index) => { if (item.length === 1 && option[index][0].value === item[0] && option[index][0]?.children?.length > 0) { setRepeatFlag(true); return message.warning('前置條件重復,請刪除!'); } else { setRepeatFlag(false); } }); const arr = option.map((item) => { let obj = { typeName: '', // 類型名稱 typeValue: '', // 類型id unitName: '', // 單位名稱 unitValue: '', // 單位id value: '', // 值 }; item.map((i, index) => { if (item.length === 1) { obj.typeName = i.label; obj.typeValue = i.value; } if (item.length === 2) { if (index === 1) { obj.unitName = i.label; obj.unitValue = i.value; } else { obj.typeName = i.label; obj.typeValue = i.value; } } }); return obj; }); setListDemo(arr); // 保存定義好的數(shù)據(jù),用于組件之間傳值 onDispatchValue(arr); };
// 父組件引用 <DraggableList data={proTypeList}></DraggableList>
// 子組件 import { ConnectState } from '@/typing/connect'; import { connect } from '@@/exports'; import { Input } from 'antd'; import React, { useEffect, useState } from 'react'; import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import { Dispatch } from 'umi'; interface Props { data: any[]; dispatch: Dispatch; } const MODEL_NAME = 'mainConfig'; const DraggableList: React.FC<Props> = ({ data = [], dispatch }) => { const [sortList, setSortList] = useState(data); // 拖拽時的樣式 const getListStyle = () => ({ overflow: 'auto', width: '100%', }); // 拖拽后的樣式 const getItemStyle = (isDragging, draggableStyle) => ({ // some basic styles to make the items look a bit nicer width: '100%', userSelect: 'none', ...draggableStyle, }); const onDragEnd = (result) => { if (!result.destination) { return; } const res = sortList.filter((item) => item); //修改引用地址 const [removed] = res.splice(result.source.index, 1); res.splice(result.destination.index, 0, removed); // console.log('添加后', res); setSortList(res); dispatch({ type: `${MODEL_NAME}/save`, payload: { proTypeList: res, }, }); console.log('拖拽后', res); }; // 校驗輸入框內容 const regInputValue = (e: any, index: number) => { // 輸入框聚焦時 const arr = data.filter((item) => item); arr[index].value = e.target.value; console.log('arr', arr); setSortList(arr); dispatch({ type: `${MODEL_NAME}/save`, payload: { proTypeList: arr, }, }); }; useEffect(() => { setSortList(data); }, [data]); // console.log('彈窗起落data', data); /** * Draggable組件可以拖動并拖放到其Droppables上. 一個Draggable必須始終包含在一個Droppable. * 它是 可能重新排序Draggable在其Droppable家中或移動到另一個Droppable. * 一個Draggable必須包含在一個Droppable. * */ return ( <DragDropContext onDragEnd={onDragEnd}> <Droppable droppableId="droppable" direction="horizontal"> {(provided, snapshot) => ( <div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)} {...provided.droppableProps}> {data.map((item, index) => ( <Draggable key={item.typeValue} draggableId={item.typeValue} index={index}> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)} > <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-start', textAlign: 'center' }}> <div style={{ width: '33%', backgroundColor: '#f2f2f2', padding: '8px 0' }}>條件名稱</div> <div style={{ width: '33%', backgroundColor: '#f2f2f2', padding: '8px 0' }}>條件值</div> <div style={{ width: '33%', backgroundColor: '#f2f2f2', padding: '8px 0' }}>單位名稱</div> </div> <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-start', padding: '6px', textAlign: 'center', marginBottom: 16, }} > <div style={{ width: '33%', padding: '8px 0' }}>{item.typeName}</div> <div style={{ width: '33%', padding: '8px 0' }}> <Input placeholder="請輸入內容" onChange={(e) => { regInputValue(e, index); }} /> </div> <div style={{ width: '33%', padding: '8px 0' }}>{item.unitName}</div> </div> </div> )} </Draggable> ))} {provided.placeholder} </div> )} </Droppable> </DragDropContext> ); }; export default connect(({ mainConfig }: ConnectState) => ({ mainConfig , }))(DraggableList);
到此這篇關于react拖拽react-beautiful-dnd,一維數(shù)組,二維數(shù)組的文章就介紹到這了,更多相關react拖拽react-beautiful-dnd,一維數(shù)組,二維數(shù)組內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
react native實現(xiàn)往服務器上傳網絡圖片的實例
下面小編就為大家?guī)硪黄猺eact native實現(xiàn)往服務器上傳網絡圖片的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08React工作流程及Error Boundaries實現(xiàn)過程講解
這篇文章主要介紹了React工作流程及Error Boundaries實現(xiàn)過程講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-02-02React使用Context與router實現(xiàn)權限路由詳細介紹
這篇文章主要介紹了React使用Context與router實現(xiàn)權限路由的詳細過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-01-01