react拖拽react-beautiful-dnd一維數(shù)組二維數(shù)組拖拽功能
寫在前邊,二維數(shù)組可以拖拽,但是不可以編輯+拖拽,如果想要實(shí)現(xiàn)編輯+拖拽,還是需要轉(zhuǎn)換成一維數(shù)組。原因是因?yàn)椴寮墓俜揭?guī)定,在拖拽過程中不可以編輯Droppable層的Props。

相關(guān)地址:
中文文檔地址
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ù)組內(nèi)容
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: '前置點(diǎn)位1',
value: '1',
disabled: false,
},
{
label: '前置點(diǎn)位2',
value: '2',
disabled: false,
},
{
label: '前置點(diǎn)位3',
value: '3',
disabled: false,
},
],
},
{
label: '溫度',
value: 'templete',
},
]);
案列
案例是通過級聯(lián)的組件選擇條件,新增條件時,前端重新定義數(shù)據(jù)格式,將二維的結(jié)構(gòu)改成一維數(shù)組的結(jié)構(gòu)。遍歷填充內(nèi)容時,是在Droppable的下一級,所以可以修改內(nèi)容。
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 = [];
// 第三層關(guān)系選中兩個時的判斷
if (ids && ids.length > 1) {
// 二維數(shù)組結(jié)構(gòu)成一維數(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('前置條件重復(fù),請刪除!');
} 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('前置條件重復(fù),請刪除!');
} 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);
};
// 校驗(yàn)輸入框內(nèi)容
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="請輸入內(nèi)容"
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);
到此這篇關(guān)于react拖拽react-beautiful-dnd,一維數(shù)組,二維數(shù)組的文章就介紹到這了,更多相關(guān)react拖拽react-beautiful-dnd,一維數(shù)組,二維數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例
下面小編就為大家?guī)硪黄猺eact native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
React中重新實(shí)現(xiàn)強(qiáng)制實(shí)施表單的流程步驟
這篇文章主要介紹了React中重新實(shí)現(xiàn)強(qiáng)制實(shí)施表單的流程步驟,就像設(shè)計人員一樣,在添加邏輯之前,您需要為不同的狀態(tài)“模擬”或創(chuàng)建“模擬”,例如,這里只是表單的視覺部分的模擬,文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-05-05
react-native中路由頁面的跳轉(zhuǎn)與傳參的實(shí)例詳解
這篇文章主要介紹了react-native中路由頁面的跳轉(zhuǎn)與傳參,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08
React工作流程及Error Boundaries實(shí)現(xiàn)過程講解
這篇文章主要介紹了React工作流程及Error Boundaries實(shí)現(xiàn)過程講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-02-02
React使用Context與router實(shí)現(xiàn)權(quán)限路由詳細(xì)介紹
這篇文章主要介紹了React使用Context與router實(shí)現(xiàn)權(quán)限路由的詳細(xì)過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01

