Skip to content

Commit 0910b25

Browse files
committed
1.5.2
1 parent dd759d9 commit 0910b25

File tree

4 files changed

+107
-68
lines changed

4 files changed

+107
-68
lines changed

docs/demos/tree/Drag.vue

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,17 @@ function onDragstart() {
5454
}
5555
5656
function onDragEnd(data: any) {
57-
console.log('onDragend', data);
5857
if (data) {
59-
const { node, prevNode, parentNode } = data;
60-
console.log('node', node);
61-
console.log('prevNode', prevNode);
62-
console.log('parentNode', parentNode);
58+
console.log('drag success', data);
59+
// const { node, prevNode, parentNode } = data;
60+
// console.log('drag node', node);
61+
// console.log('target prevNode', prevNode);
62+
// console.log('target parentNode', parentNode);
63+
} else {
64+
console.warn('drag fail: Invalid');
6365
}
6466
}
6567
66-
function onBeforeDrag(data: any) {
67-
console.log('onDragMove', data);
68-
if (data.placement === 'center' && data.node.data.id === 3) {
69-
return false;
70-
}
71-
return true;
72-
}
73-
7468
const draggable = ref(true);
7569
7670
// setTimeout(() => {
@@ -96,18 +90,18 @@ const expandedKeys = ref<number[]>([1, 100, 102]);
9690
v-model:expandedKeys="expandedKeys"
9791
:list="list"
9892
:fieldNames="customFieldNames"
99-
:indent="28"
93+
:indent="16"
10094
:iconSize="14"
10195
:filter-method="filterMethod"
10296
:itemGap="4"
10397
:draggable="draggable"
104-
:beforeDrag="onBeforeDrag"
10598
@dragstart="onDragstart"
10699
@dragend="onDragEnd"
107100
dragOnly
108101
dragGhostClass="drag-ghost-class"
109102
dragClass="drag-class"
110103
expandOnClickNode
104+
default-expand-all
111105
>
112106
<template #empty>
113107
<div style="padding: 16px">暂无数据</div>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-virt-list",
3-
"version": "1.5.2",
3+
"version": "1.5.3",
44
"description": "Tiny & Virtual scroll list & Huge amount data & High performance (support vue2.x&vue3.x)",
55
"author": "keno-lee",
66
"license": "MIT",

src/VirtGrid.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const VirtGrid = defineComponent({
2424
const gridList: Ref<{ _id: number; children: any[] }[]> = shallowRef([]);
2525

2626
function updateList() {
27+
if (props.gridItems === 0) return;
2728
// reset gridList
2829
const list = [];
2930
for (let i = 0; i < props.list.length; i += props.gridItems) {

src/components/tree/useDrag.ts

Lines changed: 96 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export const useDrag = ({
3737
let startY = 0;
3838
let initialX = 10;
3939
let initialY = 10;
40+
// 鼠标位置
41+
let mouseX = 0;
42+
let mouseY = 0;
4043
// 是否是一个有效的拖拽
4144
let dragEffect = false;
4245
// 拖拽线前后元素的最小层级,用来生成层级分段
@@ -86,6 +89,7 @@ export const useDrag = ({
8689

8790
// 找到目标元素 virt-tree-item
8891
let scrollElementRect: DOMRect | undefined = undefined;
92+
let clientElementRect: DOMRect | undefined = undefined;
8993

9094
const dragBox = document.createElement('div');
9195
dragBox.classList.add('virt-tree-drag-box');
@@ -108,23 +112,29 @@ export const useDrag = ({
108112
event.preventDefault();
109113
event.stopPropagation();
110114

115+
const clientElement = virtListRef.value?.$el;
116+
clientElementRect = clientElement?.getBoundingClientRect();
117+
scrollElement = getScrollParentElement(clientElement);
118+
scrollElementRect = scrollElement?.getBoundingClientRect();
119+
// console.log('scrollElement', scrollElement);
120+
121+
scrollElement?.addEventListener('scroll', onScroll);
111122
document.addEventListener('mousemove', onMousemove);
112123
document.addEventListener('mouseup', onMouseup);
113124
document.addEventListener('keydown', onKeydown);
114125
}
115126

127+
function onScroll() {
128+
if (dragging.value) {
129+
dragProcess();
130+
}
131+
}
132+
116133
function dragstart() {
117134
if (!sourceTreeItem) return;
118-
// 拿到treeNode后生成一个一样的元素用来拖拽
119-
const clientElement = virtListRef.value?.$el;
120-
scrollElement = getScrollParentElement(clientElement);
121-
scrollElementRect = scrollElement?.getBoundingClientRect();
122-
// console.log('scrollElement', scrollElement);
123-
124135
// 找到目标元素的virt-tree-node,判断是否展开状态,如果是,则定时1s后折叠
125136
// 数据&交互处理
126137
const nodeKey = sourceTreeItem?.dataset?.id ?? '';
127-
// if (treeInfo && nodeKey) {
128138
sourceNode = getTreeNode(nodeKey);
129139
if (!sourceNode) return;
130140

@@ -161,29 +171,64 @@ export const useDrag = ({
161171

162172
return cloneTreeItem;
163173
}
164-
function onMousemove(event: MouseEvent) {
165-
if (!cloneTreeItem) {
166-
dragstart();
167-
}
168-
if (!cloneTreeItem) return;
169174

170-
dragging.value = true;
175+
// 自动滚动
176+
function autoScroll() {
177+
if (scrollElement !== null && scrollElementRect !== undefined) {
178+
// 每次先清除旧定时器
179+
if (autoScrollTimer) {
180+
clearInterval(autoScrollTimer);
181+
autoScrollTimer = null;
182+
}
183+
// 判断是否在可视区域
184+
if (clientElementRect) {
185+
if (
186+
mouseX < clientElementRect.left ||
187+
mouseX > clientElementRect.right ||
188+
mouseY < clientElementRect.top ||
189+
mouseY > clientElementRect.bottom
190+
) {
191+
return;
192+
}
193+
}
194+
// 4等分
195+
const equalPart = scrollElementRect.height / 4;
196+
const multiple = 20;
197+
if (
198+
scrollElementRect.top < mouseY &&
199+
mouseY < scrollElementRect.top + equalPart
200+
) {
201+
const relative =
202+
(1 - (mouseY - scrollElementRect.top) / equalPart) * multiple;
203+
if (!autoScrollTimer) {
204+
autoScrollTimer = setInterval(() => {
205+
scrollElement!.scrollTop -= relative;
206+
}, 10);
207+
}
208+
} else if (
209+
scrollElementRect.top + equalPart * 3 < mouseY &&
210+
mouseY < scrollElementRect.bottom
211+
) {
212+
const relative =
213+
((mouseY - (scrollElementRect.top + equalPart * 3)) / equalPart) *
214+
multiple;
215+
if (!autoScrollTimer) {
216+
autoScrollTimer = setInterval(() => {
217+
scrollElement!.scrollTop += relative;
218+
}, 10);
219+
}
220+
}
221+
}
222+
}
171223

172-
const clientX = event.clientX;
173-
const clientY = event.clientY;
174-
const dx = clientX - startX;
175-
const dy = clientY - startY;
176-
cloneTreeItem.style.left = `${initialX + dx}px`;
177-
cloneTreeItem.style.top = `${initialY + dy}px`;
178-
const clientElement = virtListRef.value?.$el;
179-
const clientElementRect = clientElement?.getBoundingClientRect();
224+
function dragProcess() {
225+
// 判断是否在可视区域,不在则移除
180226
if (clientElementRect) {
181-
// 不在可视区域,移除
182227
if (
183-
clientX < clientElementRect.left ||
184-
clientX > clientElementRect.right ||
185-
clientY < clientElementRect.top ||
186-
clientY > clientElementRect.bottom
228+
mouseX < clientElementRect.left ||
229+
mouseX > clientElementRect.right ||
230+
mouseY < clientElementRect.top ||
231+
mouseY > clientElementRect.bottom
187232
) {
188233
// 移除 line
189234
if (hasStyleTreeItem?.contains(dragLine)) {
@@ -199,32 +244,10 @@ export const useDrag = ({
199244
}
200245
}
201246

202-
if (scrollElement && scrollElementRect) {
203-
// 自动滚动
204-
if (clientY > scrollElementRect.bottom) {
205-
if (!autoScrollTimer) {
206-
autoScrollTimer = setInterval(() => {
207-
scrollElement!.scrollTop += 2;
208-
}, 10);
209-
}
210-
} else if (clientY < scrollElementRect.top) {
211-
if (!autoScrollTimer) {
212-
autoScrollTimer = setInterval(() => {
213-
scrollElement!.scrollTop -= 2;
214-
}, 10);
215-
}
216-
} else {
217-
if (autoScrollTimer) {
218-
clearInterval(autoScrollTimer);
219-
autoScrollTimer = null;
220-
}
221-
}
222-
}
223-
224-
const hoverElement = document.elementFromPoint(clientX, clientY);
247+
// 获取hover元素
248+
const hoverElement = document.elementFromPoint(mouseX, mouseY);
225249
if (!hoverElement) return;
226250
hoverTreeItem = findAncestorWithClass(hoverElement, 'virt-tree-item');
227-
228251
if (!hoverTreeItem) {
229252
return;
230253
}
@@ -252,7 +275,6 @@ export const useDrag = ({
252275

253276
const elementTop = hoverTreeItemRect.top;
254277
const elementHeight = hoverTreeItemRect.height;
255-
const mouseY = event.clientY;
256278
// 鼠标相对于元素顶部的距离
257279
const relativeY = mouseY - elementTop;
258280
// 计算鼠标相对于元素高度的比例
@@ -408,7 +430,7 @@ export const useDrag = ({
408430

409431
if (placement !== 'center') {
410432
// 需要减去第一个indent
411-
const relativeX = clientX - hoverTreeItemRect.left - props.indent;
433+
const relativeX = mouseX - hoverTreeItemRect.left - props.indent;
412434
targetLevel = Math.ceil(relativeX / props.indent);
413435
if (targetLevel <= minLevel) targetLevel = minLevel;
414436
if (targetLevel >= maxLevel) targetLevel = maxLevel;
@@ -425,6 +447,27 @@ export const useDrag = ({
425447
}
426448
}
427449
}
450+
451+
function onMousemove(event: any) {
452+
if (!cloneTreeItem) {
453+
dragstart();
454+
}
455+
if (!cloneTreeItem) return;
456+
457+
dragging.value = true;
458+
459+
mouseX = event.clientX;
460+
mouseY = event.clientY;
461+
const dx = mouseX - startX;
462+
const dy = mouseY - startY;
463+
cloneTreeItem.style.left = `${initialX + dx}px`;
464+
cloneTreeItem.style.top = `${initialY + dy}px`;
465+
466+
autoScroll();
467+
468+
dragProcess();
469+
}
470+
428471
function onMouseup() {
429472
if (dragging.value) {
430473
// 延迟一下,不然click仍然会被触发
@@ -521,6 +564,7 @@ export const useDrag = ({
521564
sourceTreeItem = null;
522565
}
523566

567+
scrollElement?.removeEventListener('scroll', onScroll);
524568
document.removeEventListener('mousemove', onMousemove);
525569
document.removeEventListener('mouseup', onMouseup);
526570
}

0 commit comments

Comments
 (0)