react 拖拽组件 自由拖拽,垂直水平拖拽
react拖拽组件
推荐几个不错的开源拖拽组件以及使用方法
- 第一个拖拽组件 antd的Tree组件
这个拖拽组件经常用于层级关系的拖拽组件 可以动态的
增删改 (排序,添加子层级~父层级,修改等)
.
import React, { useEffect, useState } from "react"
import { Tree, message } from 'antd'; //导入antd 的Tree组件
export default function App() {
const [data, setData] = useState([])
useEffect(() => {
if (data.length === 0) {
//初始化数据
setData([{ title: "组1", key: 1 },
{ title: "组2", key: 2, children: [{ title: "子组1", key: 6 }, { title: "子组2", key: 7 }, { title: "子组3", key: 9 }] },
{ title: "组3", key: 3 },
{ title: "组4", key: 4 }])
}
}, [data])
//完成拖拽
const onDrop = info => {
/**
* 这里是判断 拖拽之后的动作是否允许存在跨级拖拽交换位置等等...
* 若需要判断可以取消注释
*/
// let nodePosArr = info.node.pos.split('-')
// let dropPosArr = info.dragNode.pos.split('-')
// if (dropPosArr.length === nodePosArr.length && nodePosArr[1] !== dropPosArr[1]) return message.error("不可拖入其他类别")
// if (nodePosArr.length !== dropPosArr.length) return message.error("列表禁止跨级拖拽")
// if (!info.dropToGap) return message.error("同级列表只能互换顺序")
const dropKey = info.node.props.eventKey;
const dragKey = info.dragNode.props.eventKey;
const dropPos = info.node.props.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
const loop = (data, key, callback) => {
for (let i = 0; i < data.length; i++) {
if (data[i].key === key) {
return callback(data[i], i, data);
}
if (data[i].children) {
loop(data[i].children, key, callback);
}
}
};
const changeData = [...data];
// Find dragObject
let dragObj;
loop(changeData, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
if (!info.dropToGap) {
// Drop on the content
loop(data, dropKey, item => {
item.children = item.children || [];
// where to insert 示例添加到尾部,可以是随意位置
item.children.push(dragObj);
});
} else if (
(info.node.props.children || []).length > 0 && // Has children
info.node.props.expanded && // Is expanded
dropPosition === 1 // On the bottom gap
) {
loop(data, dropKey, item => {
item.children = item.children || [];
// where to insert 示例添加到头部,可以是随意位置
item.children.unshift(dragObj);
});
} else {
let ar;
let i;
loop(data, dropKey, (item, index, arr) => {
ar = arr;
i = index;
});
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
}
//changeData就是拖拽结束后改变的数据格式, 需要在这里重新赋值 即可显示最新拖拽之后的结果
setData(changeData)
};
/**
*
* @param {Array} selectedKeys 选中的key 数组存放,单多选
* @param {Node} e 被选择中的node信息,可以拿到 数据源, 层级关系等...
*/
//完成选择
const onSelect = (selectedKeys, e) => {
console.log(selectedKeys, e);
}
return <>
<Tree
draggable //是否可以拖拽
blockNode //是否节点占据一行
showLine // 是否展示连接线
treeData={data} //数据源 格式 Array 每项的数据格式Object { key:..., title:...,... }
onDrop={onDrop} //拖拽结束后触发的回调函数
onSelect={onSelect} // 选中某一级的回调函数
/>
</>
}
- 第二个拖放组件 react-beautiful-dnd
这个拖拽组件用于列表拖拽,只可以
水平,垂直
拖拽.拖拽的UI非常不错, 可以动态增删列表
import React, { useEffect, useState } from "react"
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
//每一项的样式
const getItemStyle = () => ({
background: "white",
height: 50,
border: "1px solid red",
width: "100%",
margin: "0 0 20px 0"
})
// 重新记录数组顺序
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
//删除并记录 删除元素
const [removed] = result.splice(startIndex, 1);
//将原来的元素添加进数组
result.splice(endIndex, 0, removed);
return result;
};
export default function App() {
const [data, setData] = useState([])
useEffect(() => {
if (data.length === 0) {
//初始化数据
const newData = Array.from({ length: 5 }, (item, index) => ({ key: "key" + index, content: "item" + index }))
setData(newData)
}
}, [data])
//拖拽结束
const onDragEnd = (result) => {
if (!result.destination) {
return;
}
//获取拖拽后的数据 重新赋值
const newData = reorder(data, result.source.index, result.destination.index)
setData(newData)
}
return <DragDropContext onDragEnd={onDragEnd}>
{/* direction代表拖拽方向 默认垂直方向 水平方向:horizontal */}
<Droppable droppableId="droppable">
{(provided, snapshot) => (
//这里是拖拽容器 在这里设置容器的宽高等等...
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={{
width: 800,
padding: 10
}}
>
{/* 这里放置所需要拖拽的组件,必须要被 Draggable 包裹 */}
{
data.map((item, index) => (
<Draggable
index={index}
key={item.key}
draggableId={item.key}
>
{(provided, snapshot) => (
//在这里写你的拖拽组件的样式 dom 等等...
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{ ...getItemStyle(), ...provided.draggableProps.style }}
>
{item.content}
</div>
)}
</Draggable>
))
}
{/* 这个不能少 */}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
}
- 第三个拖拽组件 react-draggable-tags
一个轻量级的拖拽排序组件。该组件封装了一系列拖拽功能,可以灵活使用,也未提供任何样式,完全由你来控制(不一定是“tag”,你可以放入任意组件来拖拽排序)。支持移动端。
import React, { useEffect, useState } from "react";
import { DraggableArea } from 'react-draggable-tags';
export default function App() {
const [data, setData] = useState([])
useEffect(() => {
if (data.length === 0) {
setData([
{ id: 1, content: 'apple' }, { id: 2, content: 'olive' }, { id: 3, content: 'banana' },
{ id: 4, content: 'lemon' }, { id: 5, content: 'orange' }, { id: 6, content: 'grape' },
{ id: 7, content: 'strawberry' }, { id: 8, content: 'cherry' }, { id: 9, content: 'peach' }
])
}
}, [data])
//拖拽结束后触发的函数,返回已经改变的data
const onChange = (tags) => {
console.log(tags);
}
//渲染每项
const itemRender = ({ tag, index }) => {
return <div className="tag">
{tag.content}
</div>
}
return <div className="Simple">
<DraggableArea
tags={data}
render={itemRender}
onChange={onChange}
/>
</div>
}
react 拖拽组件 自由拖拽,垂直水平拖拽的更多相关文章
- 强大的拖拽组件:React DnD 的使用
强大的拖拽组件:React DnD 的使用 react.js 10.6k 次阅读 · 读完需要 25 分钟 17 文章首发我的个人blog : 原文链接 学习 React DnD 的最初原因是阅读 ...
- React组件:拖拽布局Dragact v0.1.6 发布
仓库地址:Dragact爽滑的拖拽组件 大家好,新年已经过去,大家又投入了繁忙的工作当中,由于我在国外,因此压根儿没有休息... 少说废话,上周一周的时间里,我陆陆续续的为Dragact组件进行了一系 ...
- React拖拽组件Dragact V0.1.7:教你优化React组件性能与手感
仓库地址:Dragact手感丝滑的拖拽布局组件 预览地址:支持手机端噢- 上回我们说到,Dragact组件已经进行了一系列的性能优化,然而面对大量数据的时候,依旧比较吃力,让我们来看看,优化之前的Dr ...
- vue自由拖拽、缩放组件
github地址:https://github.com/kirillmurashov/vue-drag-resize 安装: npm i -s vue-drag-resize 使用: <temp ...
- 再谈React.js实现原生js拖拽效果
前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...
- React Editor 应用编辑器(1) - 拖拽功能剖析
这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...
- Vue-Grid-Layout分享一款好用的可拖拽组件
在使用Grafana的过程中,发现Grafana关于视图页面中每一个面板都可拖拽,可随意放大放小,体验非常棒,F12看了Grafana的代码,看打包后的代码很像react,进一步css,看到有grid ...
- Vue.Draggable:基于 Sortable.js 的 Vue 拖拽组件使用中遇到的问题
Sortable.js 介绍 https://segmentfault.com/a/1190000008209715 项目中遇到的问题: A - 我需要在项目的拖拽组件中,使用背景 1 - 想到的第一 ...
- jquery插件-自由拖拽
最近工作不是很忙,学习之余想整理一些代码出来,首先想到的就是是js拖拽. 两年前去某公司面试的时候,曾经被问过这个问题,如何在页面上拖放元素,尽管现在看起来很简单,但当时的我半点思路都没有,面试想当然 ...
- vue拖拽组件开发
vue拖拽组件开发 创建临时vue项目 先查看node和npm版本,怎么安装就不多多bb了 再安装vue-cli npm install vue-cli -g //全局安装 vue-cli 检测是否安 ...
随机推荐
- uniapp清除指定key缓存
清除缓存 onLaunch: function () { console.log('App Launch') const preservedKeys = ['ishowFixPre', 'readTi ...
- mogodb的使用语句(命令)大全
官网学习网址:https://docs.mongodb.com/ mongo库表操作语句实际操作过程 1: mongo入门命令 1.1: show dbs 查看当前的数据库 1.2 use datab ...
- Kubernetes 数据存储:从理论到实践的全面指南
本文深入解析 Kubernetes (K8S) 数据存储机制,探讨其架构.管理策略及最佳实践.文章详细介绍了 K8S 数据存储的基础.架构组成.存储卷管理技巧,并通过具体案例阐述如何高效.安全地管理数 ...
- 京东面试:SpringBoot同时可以处理多少请求?
Spring Boot 作为 Java 开发中必备的框架,它为开发者提供了高效且易用的开发工具,所以和它相关的面试题自然也很重要,咱们今天就来看这道经典的面试题:SpringBoot同时可以处理多少个 ...
- JVM Sandbox入门详解
一. 概述 在日常开发中,经常会接触到面向AOP编程的思想,我们通常会使用Spring AOP来做统一的权限认证.异常捕获返回.日志记录等工作.之所以使用Spring AOP来实现上述功能,是因为这些 ...
- Prism IoC 依赖注入
现有2个项目,SinglePageApp是基于Prism创建的WPF项目,框架使用的是Prism.DryIoc,SinglePageApp.Services是C#类库,包含多种服务,下面通过使用Pri ...
- 挨个配置资源组太麻烦?ROS伪参数一步搞定!
介绍 伪参数 伪参数是资源编排服务ROS的编排引擎提供的固定参数,即在编写模板时可以使用的一系列预定义的参数,它们为模板提供了资源部署过程中的环境和执行上下文信息. 更多伪参数介绍请查看:ROS伪参数 ...
- Android启动过程-万字长文(Android14)
在计算机启动过程和Linux内核Kernel启动过程介绍了计算机启动和内核加载,本篇文章主要介绍Android系统是如何启动的. 一.Android启动流程 Android系统的启动流程与Linux接 ...
- 面试官:说说Netty的核心组件?
Netty 核心组件是指 Netty 在执行过程中所涉及到的重要概念,这些核心组件共同组成了 Netty 框架,使 Netty 框架能够正常的运行. Netty 核心组件包含以下内容: 启动器 Boo ...
- 【论文笔记】R-CNN系列之论文理解
[深度学习]总目录 RCNN全称region with CNN features,即用CNN提取出Region Proposals中的featues.RCNN系列论文(R-CNN,Fast R-CNN ...