10000 feat: add drag · Create-Peace/light-vue-tree@83e5f68 · GitHub
[go: up one dir, main page]

Skip to content

Commit 83e5f68

Browse files
committed
feat: add drag
1 parent be9c8eb commit 83e5f68

File tree

4 files changed

+149
-45
lines changed

4 files changed

+149
-45
lines changed

src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Tree :tree-data="demeData"
44
show-checkbox
55
hasHalfelEction
6-
checkStrictly
6+
draggable
77
@on-checkbox-change="handleChangeCheckBox"
88
@on-checked-item="handleChangeItem">
99
<!-- <template v-slot="{node}">

src/components/Tree.js

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,4 @@
1-
// import { construct } from "core-js/fn/reflect"
2-
3-
const TREE_DATA = { selected: false, partialSelected: false, expanded: false };
4-
class TreeData {
5-
constructor(data) {
6-
this.data = { ...TREE_DATA, ...data };
7-
this.children = [];
8-
}
9-
setParent(node) {
10-
this.parent = node;
11-
}
12-
addChild(node) {
13-
this.children.push(node);
14-
node.setParent(this);
15-
}
16-
isSelected() {
17-
return this?.data?.selected ?? false;
18-
}
19-
isExpanded() {
20-
return this?.data?.expanded ?? false;
21-
}
22-
isPartialSelected() {
23-
return this?.data?.partialSelected ?? false;
24-
}
25-
// TODO 这里两个方法需要合并一下
26-
isAllChildrenSelected() {
27-
// eslint-disable-next-line no-debugger
28-
// debugger
29-
return this.children.every((child) => child.isSelected());
30-
}
31-
hasChildrenPartialSelected() {
32-
return this.children.some(
33-
(child) => child.isSelected() || child.isPartialSelected()
34-
);
35-
}
36-
}
1+
import TreeData from './TreeData'
372

383
const generateNode = (data, props) => {
394
const { children, ...rest } = data;
@@ -191,7 +156,12 @@ export default {
191156
this.refreshDown(child);
192157
});
193158
},
159+
handleDrop(event) {
160+
event.stopPropagation()
161+
},
194162
dragStart(event, treeNode) {
163+
console.log('dratstart')
164+
event.stopPropagation()
195165
if (
196166
typeof this.allowDrag === "function" &&
197167
!this.allowDrag(treeNode.node)
@@ -209,10 +179,12 @@ export default {
209179
} catch (e) {
210180
console.error(e);
211181
}
212-
this.draggingNode = treeNode;
182+
this.dragInfo.draggingNode = treeNode;
183+
console.log('this.dragInfo.draggingNode', this.dragInfo.draggingNode)
213184
this.$emit("node-drag-start", treeNode.node, event);
214185
},
215186
dragOver(event) {
187+
event.stopPropagation()
216188
const dragInfo = this.dragInfo;
217189
const dropNode = findNearestComponent(event.target, "TreeNode");
218190
const oldDropNode = dragInfo.dropNode;
@@ -251,6 +223,7 @@ export default {
251223
if (dropPrev || dropInner || dropNext) {
252224
dragInfo.dropNode = dropNode;
253225
}
226+
console.log('dropNode', dropNode)
254227
// TODO 这里的逻辑需要实现
255228
if (dropNode.node.nextSibling === draggingNode.node) {
256229
dropNext = false;
@@ -303,7 +276,7 @@ export default {
303276
}
304277

305278
const iconPosition = dropNode.$el
306-
.querySelector("sh__expand-icon")
279+
.querySelector(".sh__expand-icon")
307280
.getBoundingClientRect();
308281
const dropIndicator = this.$refs.dropIndicator;
309282
if (dropType === "before") {
@@ -327,6 +300,7 @@ export default {
327300
this.$emit("node-drag-over", draggingNode.node, dropNode.node, event);
328301
},
329302
dragEnd(event) {
303+
event.stopPropagation()
330304
const dragInfo = this.dragInfo;
331305
const { draggingNode, dropType, dropNode } = dragInfo;
332306
event.preventDefault();
@@ -344,9 +318,9 @@ export default {
344318
} else if (dropType === "inner") {
345319
dropNode.node.insertChild(draggingNodeCopy);
346320
}
347-
if (dropType !== "none") {
321+
// if (dropType !== "none") {
348322
// this.store.registerNode(draggingNodeCopy);
349-
}
323+
// }
350324

351325
removeClass(dropNode.$el, "is-drop-inner");
352326

@@ -384,6 +358,10 @@ export default {
384358
{this.root?.children?.map((node, index) => {
385359
return <TreeNode key={node?.data?.name ?? index} node={node} />;
386360
})}
361+
<div
362+
style={{display: this.dragInfo.showDropIndicator? 'none' : 'block'}}
363+
class="el-tree__drop-indicator"
364+
ref="dropIndicator"></div>
387365
</div>
388366
);
389367
},

src/components/TreeData.js

Lines changed: 112 additions & 0 deletions
B41A
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const TREE_DATA = { selected: false, partialSelected: false, expanded: false };
2+
export default class TreeData {
3+
constructor(data) {
4+
this.data = { ...TREE_DATA, ...data };
5+
this.children = [];
6+
}
7+
setParent(node) {
8+
this.parent = node;
9+
}
10+
addChild(node) {
11+
this.children.push(node);
12+
node.setParent(this);
13+
}
14+
isSelected() {
15+
return this?.data?.selected ?? false;
16+
}
17+
isExpanded() {
18+
return this?.data?.expanded ?? false;
19+
}
20+
isPartialSelected() {
21+
return this?.data?.partialSelected ?? false;
22+
}
23+
// TODO 这里两个方法需要合并一下
24+
isAllChildrenSelected() {
25+
// eslint-disable-next-line no-debugger
26+
// debugger
27+
return this.children.every((child) => child.isSelected());
28+
}
29+
hasChildrenPartialSelected() {
30+
return this.children.some(
31+
(child) => child.isSelected() || child.isPartialSelected()
32+
)
33+
}
34+
contains(target, deep = true) {
35+
const walk = function(parent) {
36+
const children = parent.children || [];
37+
let result = false;
38+
for (let i = 0, j = children.length; i < j; i++) {
39+
const child = children[i];
40+
if (child === target || (deep && walk(child))) {
41+
result = true;
42+
break;
43+
}
44+
}
45+
return result;
46+
};
47+
return walk(this);
48+
}
49+
get nextSibling() {
50+
const parent = this.parent;
51+
if (parent) {
52+
const index = parent.children.indexOf(this);
53+
if (index > -1) {
54+
return parent.children[index + 1];
55+
}
56+
}
57+
return null;
58+
}
59+
60+
get previousSibling() {
61+
const parent = this.parent;
62+
if (parent) {
63+
const index = parent.children.indexOf(this);
64+
if (index > -1) {
65+
return index > 0 ? parent.children[index - 1] : null;
66+
}
67+
}
68+
return null;
69+
}
70+
71+
insertBefore(child, ref) {
72+
let index;
73+
if (ref) {
74+
index = this.children.indexOf(ref);
75+
}
76+
this.insertChild(child, index);
77+
}
78+
79+
insertAfter(child, ref) {
80+
let index;
81+
if (ref) {
82+
index = this.children.indexOf(ref);
83+
if (index !== -1) index += 1;
84+
}
85+
this.insertChild(child, index);
86+
}
87+
88+
removeChild(child) {
89+
const dataIndex = this.children.indexOf(child)
90+
if (dataIndex > -1) {
91+
child.parent = null;
92+
this.children.splice(dataIndex, 1);
93+
}
94+
}
95+
96+
remove() {
97+
const parent = this.parent;
98+
if (parent) {
99+
parent.removeChild(this);
100+
}
101+
}
102+
103+
insertChild(child, index) {
104+
105+
if (typeof index === 'undefined' || index < 0) {
106+
this.children.push(child);
107+
} else {
108+
this.children.splice(index, 0, child);
109+
}
110+
}
111+
112+
}

src/components/TreeNode.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ export default {
5050
},
5151
nodeView (node, level) {
5252
const {name, selected, disabled, partialSelected, expanded} = node?.data ?? {}
53-
const { renderTreeNode, $scopedSlots: { default: defaultSlot }} = this.tree
53+
const { renderTreeNode, $scopedSlots: { default: defaultSlot } } = this.tree
5454

55-
return (name && <div style={`margin-left: ${level * 10}px; margin-bottom: 6px; display: inline-block;`}>
56-
{node.children && node.children.length? <span class={['icon', expanded ? 'rotate180-enter icon-expand' : 'rotate180-leave icon-unexpand']} onClick={() => this.toggleFold(node)} style="padding: 1px; background: #eee; cursor: pointer"></span> : null}
55+
return (name && <div
56+
style={`margin-left: ${level * 10}px; margin-bottom: 6px; display: inline-block;`}
57+
>
58+
{node.children && node.children.length? <span class={['icon', 'sh__expand-icon', expanded ? 'rotate180-enter icon-expand' : 'rotate180-leave icon-unexpand']} onClick={() => this.toggleFold(node)} style="padding: 1px; background: #eee; cursor: pointer"></span> : null}
5759
{ partialSelected && `-`}
5860
{this.tree.showCheckbox && <input type='checkbox' disabled={disabled} checked={selected} onClick={() => this.selectToggle(node)} />}
5961
{ renderTreeNode ? renderTreeNode(node) : defaultSlot? defaultSlot({node}): <span>{name}</span> }
@@ -65,13 +67,25 @@ export default {
6567
this.tree.refreshExpandedDown(node)
6668
}
6769
},
70+
handleDragStart(e, treeNode) {
71+
console.log('treeNode', treeNode)
72+
}
6873

6974
},
7075

7176
render () {
7277
const { node, level } = this
7378
const currentNode = this.nodeView(node, level)
74-
return (<div>
79+
const { draggable, dragStart, dragOver, dragEnd, handleDrop} = this.tree
80+
// console.log(dragStart)
81+
82+
return (<div
83+
draggable={draggable}
84+
onDragstart={(e) => dragStart(e, this)}
85+
onDragover={(e) => dragOver(e, this)}
86+
onDragend={(e) => dragEnd(e, this)}
87+
onDrop={handleDrop}
88+
>
7589
{currentNode}
7690
{
7791
node?.data?.expanded && node.children?.map(subNode => {

0 commit comments

Comments
 (0)
0