看效果:
可以实现单个拖拽、双击添加、按住ctrl键实现多个添加,或者按住shift键实现范围添加,添加到框中的数据,还能拖拽排序
先安装 vuedraggable
这是他的官网 vue.draggable中文文档 – itxst.com
1 | npm i vuedraggable -S |
直接粘贴代码即可:
index.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | <div class = "w-full h-full" > <div class = "leftPart" > $.tableFieldsNodeClick(data, node, treeTableListRef) " > <div class=" item "> {{ element.name }} </div> </div> <div class=" rightPart "> <div class=" flex "> <div class=" w-full rightContent " style=" border: 1px solid #ccc"> <div class ="item "> {{ element.name }} </div> </div> </div> </div> </div> import Draggable from " vuedraggable "; import { useData } from " ./hooks/drag "; const treeTableListRef = ref(); let { $data: $ } = useData(); const state = reactive({ //需要拖拽的数据,拖拽后数据的顺序也会变化 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 ; } }; .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; } } |
drag.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | 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 |
到此这篇关于vue3中使用vuedraggable实现拖拽el-tree数据进分组的文章就介绍到这了,更多相关vue draggable拖拽分组内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!