vue3中使用vuedraggable实现拖拽el-tree数据分组功能

2024-03-01 0 299

看效果:

可以实现单个拖拽、双击添加、按住ctrl键实现多个添加,或者按住shift键实现范围添加,添加到框中的数据,还能拖拽排序

vue3中使用vuedraggable实现拖拽el-tree数据分组功能

先安装 vuedraggable

这是他的官网vue.draggable中文文档 – itxst.com

npm i vuedraggable -S

直接粘贴代码即可:

index.vue

<template>
<div class=\”w-full h-full\”>
<!– 页面拖拽组件 –>
<div class=\”leftPart\”>
<ElTree
class=\”w100%\”
:data=\”$.treeData\”
ref=\”treeTableListRef\”
:props=\”$.defaultProps\”
highlight-current
:expand-on-click-node=\”false\”
key=\”id\”
:default-expand-all=\”true\”
@node-click=\”(data, node) => $.tableFieldsNodeClick(data, node, treeTableListRef)\”
>
<template #default=\”{ data }\”>
<Draggable
:list=\”[data]\”
ghost-class=\”ghost\”
chosen-class=\”chosenClass\”
animation=\”300\”
@start=\”onStart\”
@end=\”onEnd\”
group=\”group1\”
v-tooltip=\”`Tips:按住Ctrl或Shift进行批量选择`\”
>
<template #item=\”{ element }\”>
<div @dblclick=\”dbAddData(element)\” style=\”user-select: none\” class=\”item\”>
{{ element.name }}
</div>
</template>
</Draggable>
</template>
</ElTree>
</div>
<!– 右侧内容 –>
<div class=\”rightPart\”>
<div class=\”flex\”>
<div
@mouseover=\”divMouseOver\”
@mouseleave=\”divMouselease\”
class=\”w-full rightContent\”
style=\”border: 1px solid #ccc\”
>
<Draggable
:list=\”state.list\”
ghost-class=\”ghost\”
group=\”group1\”
chosen-class=\”chosenClass\”
animation=\”300\”
@start=\”onStart\”
@end=\”onEnd\”
@add=\”addData\”
class=\”w-full dragArea\”
>
<template #item=\”{ element }\”>
<div class=\”item\”>
{{ element.name }}
</div>
</template>
</Draggable>
</div>
</div>
</div>
</div>
</template>
<script setup lang=\”ts\”>
import Draggable from \”vuedraggable\”;
import { useData } from \”./hooks/drag\”;
const treeTableListRef = ref();
let { $data: $ } = useData();
const state = reactive<any>({
//需要拖拽的数据,拖拽后数据的顺序也会变化
list: [],
});
//拖拽开始的事件
const onStart = () => {
console.log(\”开始拖拽\”);
};
const divMouseOver = (e: any) => {};
const divMouselease = (e: any) => {};
//拖拽结束的事件
const onEnd = () => {
console.log(\”结束拖拽\”);
};
// 双击添加
const dbAddData = (data: any) => {
let i = state.list.findIndex((a: any) => a.id == data.id);
if (data.children) return; //父级节点不添加
if (i == -1) state.list.push(data);
};
// 批量添加
const addData = () => {
// 拿到所有nodes节点数组
const nodes = treeTableListRef.value.store._getAllNodes();
nodes.map((a: any) => {
if ($.selectNodes.includes(a.id)) {
state.list.push(a.data);
}
// 排除父级,只添加子级
state.list = state.list.filter((a: any) => !a.children);
// 去重
state.list = […new Set(state.list)];
});
};
onMounted(() => {});
onBeforeMount(() => {
window.addEventListener(\”keydown\”, handleKeyDown);
window.addEventListener(\”keyup\”, handleKeyUp);
});
// 按下为true
const handleKeyDown = (event: any) => {
// 代表按下的是ctrl键
if (event.key == \”Control\”) {
$.ctrlKeyPressed = true;
}
// 代表按下的是shift键
if (event.key == \”Shift\”) {
$.shiftKeyPressed = true;
}
};
// 释放为false
const handleKeyUp = (event: any) => {
// 代表按下的是ctrl键
if (event.key == \”Control\”) {
$.ctrlKeyPressed = false;
}
// 代表按下的是shift键
if (event.key == \”Shift\”) {
$.shiftKeyPressed = false;
}
};
</script>
<style scoped lang=\”scss\”>
.leftPart {
width: 20%;
height: 100%;
float: left;
border-right: 1px dashed #ccc;
}
.rightPart {
padding: 20px;
width: 60%;
height: 100%;
float: left;
}
.list_drap {
min-width: 120px;
max-height: 86px;
min-height: 22px;
overflow-y: auto;
height: auto;
}
.rightContent {
border-radius: 4px;
min-height: 30px;
display: flex;
}
.dragArea {
padding: 10px 5px;
flex-grow: 1;
.item {
float: left;
min-width: 50px;
display: inline;
margin: 0 3px 2px 3px;
background-color: rgb(235, 241, 255);
color: #3370ff;
font-size: 12px;
cursor: all-scroll;
user-select: none;
height: 20px;
line-height: 20px;
padding-left: 9px;
padding-right: 9px;
background: #ececfd;
color: #333333;
font-size: 12px;
}
}
</style>

drag.ts

export function useData() {
const $data: any = reactive({
ctrlKeyPressed: false,
shiftKeyPressed: false,
shiftKeyFelid: [],
defaultProps: {
children: \”children\”,
label: \”name\”,
},
treeData: [
{
name: \”一级1\”,
id: 1,
children: [
{
name: \”二级1\”,
id: 2,
children: [
{
name: \”三级1\”,
id: 2,
},
{
name: \”三级2\”,
id: 4,
},
{
name: \”三级3\”,
id: 5,
},
{
name: \”三级4\”,
id: 6,
},
{
name: \”三级5\”,
id: 7,
},
],
},
{
name: \”二级2\”,
id: 8,
},
{
name: \”二级3\”,
id: 9,
},
{
name: \”二级4\”,
id: 10,
},
{
name: \”二级5\”,
id: 11,
},
],
},
{
name: \”一级2\”,
id: 12,
children: [
{
name: \”二级1\”,
id: 13,
},
{
name: \”二级2\”,
id: 14,
},
{
name: \”二级3\”,
id: 15,
},
{
name: \”二级4\”,
id: 16,
},
{
name: \”二级5\”,
id: 17,
},
],
},
],
selectNodes: [],
treeTableListRef: null,
});
// 节点选中事件
$data.tableFieldsNodeClick = (nodeData: any, node: any, treeTableListRef: any) => {
const nodes = treeTableListRef.store._getAllNodes(); //所有node节点
const ishas = $data.selectNodes.includes(node.id);
// 递归遍历节点数组进行ID存放
function addSelectId(arr: any) {
for (const item of arr) {
$data.selectNodes.push(item.id);
if (Array.isArray(item.childNodes) && item.childNodes.length) {
addSelectId(item.childNodes);
}
}
}
// 递归遍历删除节点id
function delSelectId(arr: any) {
for (const item of arr) {
const index = $data.selectNodes.findIndex((x: any) => x == item.id);
$data.selectNodes.splice(index, 1);
if (Array.isArray(item.children) && item.children.length) {
delSelectId(item.children);
}
}
}
// 按住了ctrl键,可以进行单个多选
if ($data.ctrlKeyPressed) {
// 如果为true代表当前选中的节点已存在
if (ishas) {
// 查找当前选中的节点的索引
const index = $data.selectNodes.findIndex((x: any) => x == node.id);
// 删除父节点
$data.selectNodes.splice(index, 1);
// 删除子节点
if (Array.isArray(node.childNodes) && node.childNodes.length) {
delSelectId(node.childNodes);
}
} else {
// 否则当前选中的节点不存在,就加入到已选节点数组序列
$data.selectNodes.push(node.id);
// 防止选中的是父节点,就需要递归将子节点加入
if (Array.isArray(node.childNodes) && node.childNodes.length) {
addSelectId(node.childNodes);
}
}
node.isCurrent = !node.isCurrent;
// 按下了shift键,可以进行范围多选
} else if ($data.shiftKeyPressed) {
// 先清空
$data.selectNodes = [];
// 将当前节点放入
$data.selectNodes.push(node.id);
$data.shiftKeyFelid.push(node.id);
if ($data.shiftKeyFelid.length > 1) {
// 首索引
const sIndex = nodes.findIndex((x: any) => x.id == $data.shiftKeyFelid[0]);
// 尾索引
const eIndex = nodes.findIndex((x: any) => x.id == $data.shiftKeyFelid[$data.shiftKeyFelid.length – 1]);
// 根据首尾索引,存入中间节点
const s = sIndex < eIndex ? sIndex : eIndex; //取小值当开头索引
const e = sIndex < eIndex ? eIndex : sIndex; //取大值当结尾索引
for (let i = s; i < e; i++) {
$data.selectNodes.push(nodes[i].id);
}
}
} else {
// 否则就是单机选择
$data.shiftKeyFelid = [];
$data.selectNodes = [];
$data.selectNodes = [node.id];
}
// 下面是对已选中的节点,进行高亮展示
// 通过控制elementui中节点上的isCurrent属性
// isCurrent为true是高亮,否则取消高亮
for (const item of nodes) {
if ($data.selectNodes.includes(item.id)) {
item.isCurrent = true;
} else {
item.isCurrent = false;
}
}
};
return {
$data: $data,
};
}

到此这篇关于vue3中使用vuedraggable实现拖拽el-tree数据进分组的文章就介绍到这了,更多相关vue draggable拖拽分组内容请搜索悠久资源网以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源网!

您可能感兴趣的文章:

  • Vue3中使用vuedraggable拖拽实战教程
  • vue draggable组件实现拖拽及点击无效问题的解决
  • Vue利用draggable实现多选拖拽效果
  • 使用element+vuedraggable实现图片上传拖拽排序
  • vue使用vuedraggable实现嵌套多层拖拽排序功能
  • vue拖拽组件vuedraggable使用说明详解
  • 使用vuedraggable实现从左向右拖拽功能
  • vue3使用vuedraggable实现拖拽功能
  • vuedraggable实现拖拽功能

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 JavaScript vue3中使用vuedraggable实现拖拽el-tree数据分组功能 https://www.u-9.cn/biancheng/javascript/181844.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务