Files
workspace/code/g3soft-libs/docs/examples/tree/draggable.vue
T
2026-10-08 22:38:34 +08:00

74 lines
2.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
// draggable:拖到行的上/下 25% 是「前/后插入」,中间是「放入内部」
// drop 事件里自己重排数据(组件不直接改 treeData)
import { ref } from 'vue'
import { G3Message, G3Tree, type TreeNodeData } from '@g3soft/ui'
const treeData = ref<TreeNodeData[]>([
{ key: '1', title: '第一项' },
{ key: '2', title: '第二项' },
{
key: '3',
title: '第三项(可拖入)',
children: [{ key: '3-1', title: '子项' }],
},
])
function findNode(nodes: TreeNodeData[], key: string): TreeNodeData | null {
for (const node of nodes) {
if (String(node.key) === key) return node
const found = node.children ? findNode(node.children, key) : null
if (found) return found
}
return null
}
function removeNode(nodes: TreeNodeData[], key: string): TreeNodeData | null {
const index = nodes.findIndex((node) => String(node.key) === key)
if (index >= 0) return nodes.splice(index, 1)[0]
for (const node of nodes) {
if (node.children) {
const removed = removeNode(node.children, key)
if (removed) return removed
}
}
return null
}
function onDrop(info: { dragKey: string | number; dropKey: string | number; dropPosition: string }) {
const dragKey = String(info.dragKey)
const dropKey = String(info.dropKey)
const data = treeData.value
const moved = removeNode(data, dragKey)
if (!moved) return
if (info.dropPosition === 'inside') {
const target = findNode(data, dropKey)
if (target) {
target.children = [...(target.children ?? []), moved]
G3Message.success(`已移动到「${target.title}」内部`)
}
} else {
const insert = (nodes: TreeNodeData[]): boolean => {
const index = nodes.findIndex((node) => String(node.key) === dropKey)
if (index >= 0) {
nodes.splice(info.dropPosition === 'before' ? index : index + 1, 0, moved)
return true
}
return nodes.some((node) => (node.children ? insert(node.children) : false))
}
insert(data)
G3Message.success(`已${info.dropPosition === 'before' ? '前移' : '后移'}到「${dropKey}」`)
}
treeData.value = [...data]
}
</script>
<template>
<div style="max-width: 320px">
<G3Tree :tree-data="treeData" draggable default-expand-all block-node @drop="onDrop" />
<p style="margin: 8px 0 0; font-size: 12px; color: #6b7280">拖拽任意节点试试(子节点不能拖进自己的子树)</p>
</div>
</template>