UNPKG

@fesjs/fes-design

Version:
192 lines (189 loc) 4.43 kB
import { ref, computed, onUnmounted } from 'vue'; import getPrefixCls from '../_util/getPrefixCls'; const prefixCls = getPrefixCls('tree-node'); function allowDrop(node, dropPosition) { if (node.isLeaf === false) { return true; } if (node.children) { return true; } return dropPosition !== 'inside'; } var useDrag = _ref => { let { nodeList, emit, expandNode } = _ref; let dragNode; let overBeginTimeMap = {}; const dragOverInfo = ref(); let timer; const dragHighlightNode = computed(() => { if (!dragOverInfo.value) { return; } const node = dragOverInfo.value.node; const position = dragOverInfo.value.position; if (position === 'after' || position === 'before') { return node.parent; } return node; }); onUnmounted(() => { if (timer) { clearTimeout(timer); } }); function resetDragState() { dragNode = null; overBeginTimeMap = {}; dragOverInfo.value = null; } const handleDragstart = (value, event) => { const node = nodeList.get(value); if (!node.draggable) { // 阻止默认事件,默认事件会有拖拽效果 event.preventDefault(); return; } dragNode = node; emit('dragstart', { node, event }); }; const handleDragend = (value, event) => { resetDragState(); const node = nodeList.get(value); if (!node.draggable) { event.preventDefault(); return; } emit('dragend', { node, event }); }; function getTargetNode(value) { if (!dragNode) { return; } const node = nodeList.get(value); if (!node) { return; } if (node.indexPath.includes(dragNode.value)) { return; } return node; } const handleDragenter = (value, event) => { const node = getTargetNode(value); if (!node) { return; } emit('dragenter', { node, event }); }; const handleDragleave = (value, event) => { const node = getTargetNode(value); if (!node) { return; } emit('dragleave', { node, event }); }; const handleDragover = (value, event) => { event.preventDefault(); const node = getTargetNode(value); if (!node) { dragOverInfo.value = null; return; } emit('dragover', { node, event }); // 悬浮1s以上展开节点 if (!overBeginTimeMap[value]) { overBeginTimeMap[value] = Date.now(); } else { if (Date.now() - overBeginTimeMap[value] > 1000 && node.hasChildren && !node.isExpanded.value) { expandNode(value, event); } } const targetNodeEl = document.querySelector(`.${prefixCls}[data-value='${value}']`); // 悬浮节点大小位置信息 const { height: targetElOffsetHeight } = targetNodeEl.getBoundingClientRect(); let mousePosition; const targeEl = event.currentTarget; // 焦点节点大小位置信息 const { top: elClientTop } = targeEl.getBoundingClientRect(); const eventOffsetY = event.clientY - elClientTop; const allowDropInside = allowDrop(node, 'inside'); if (allowDropInside) { if (eventOffsetY <= 8) { mousePosition = 'before'; } else if (eventOffsetY >= targetElOffsetHeight - 8) { mousePosition = 'after'; } else { mousePosition = 'inside'; } } else { if (eventOffsetY <= targetElOffsetHeight / 2) { mousePosition = 'before'; } else { mousePosition = 'after'; } } dragOverInfo.value = { node, position: mousePosition }; // 300毫秒后没有后续则表示已经移出 if (timer) { clearTimeout(timer); } timer = setTimeout(() => { dragOverInfo.value = null; }, 300); }; const handleDrop = (value, event) => { const node = getTargetNode(value); if (!node) { return; } if (!dragOverInfo.value) { return; } emit('drop', { position: dragOverInfo.value.position, node: dragOverInfo.value.node, dragNode, originNode: dragOverInfo.value.node.origin, originDragNode: dragNode.origin, event }); }; return { handleDragstart, handleDragenter, handleDragover, handleDragleave, handleDragend, handleDrop, dragOverInfo, dragHighlightNode }; }; export { useDrag as default };