基于vue3实现从div文本列表中,拖拽复制到另一个div的tree的节点下,并且在这个节点下可以更换排序,不能把节点下的列表拖拽到外面的结点下
时间: 2024-02-01 14:15:13 浏览: 71
实现这个功能需要用到Vue3的拖拽、排序和组件通信等相关知识。
首先,我们需要在源div列表中绑定拖拽事件,将被拖拽的元素的数据存储到一个变量中。在目标div中绑定放置事件,当放置完成后将存储的数据插入到目标节点下的子节点中。
同时,我们需要对目标节点下的子节点进行排序操作。可以使用Vue3提供的v-for指令,将子节点渲染为一个列表,并绑定拖拽事件。在拖拽结束后,将重新排序后的子节点数据保存到目标节点的数据中。
最后,我们需要限制节点拖拽的范围,不能将节点拖拽到其它节点下。可以使用Vue3的自定义指令来实现这个功能。
下面是一个简单的实现代码示例:
```html
<template>
<div class="source" @dragstart="onDragStart">
<div v-for="item in sourceList" :key="item.id" draggable="true">{{ item.text }}</div>
</div>
<div class="target" @drop="onDrop" @dragover.prevent>
<tree-node v-for="item in targetList" :key="item.id" :data="item"></tree-node>
</div>
</template>
<script>
import { ref, computed, watch } from 'vue';
export default {
components: {
TreeNode: {
props: ['data'],
template: `
<div class="node" :class="{ active: isActive }" @dragenter="onDragEnter" @dragleave="onDragLeave" @drop="onDrop" @dragover.prevent>
{{ data.text }}
<div class="children">
<tree-node v-for="item in sortedChildren" :key="item.id" :data="item"></tree-node>
</div>
</div>
`,
setup(props) {
const isActive = ref(false);
const sortedChildren = computed(() => {
return props.data.children.sort((a, b) => a.order - b.order);
});
function onDragEnter() {
isActive.value = true;
}
function onDragLeave() {
isActive.value = false;
}
function onDrop(event) {
const data = JSON.parse(event.dataTransfer.getData('text/plain'));
if (!props.data.children.some(item => item.id === data.id)) {
props.data.children.push(data);
}
isActive.value = false;
}
return {
isActive,
sortedChildren,
onDragEnter,
onDragLeave,
onDrop,
};
},
},
},
setup() {
const sourceList = ref([
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' },
]);
const targetList = ref([
{
id: 4,
text: 'Node 1',
order: 1,
children: [
{ id: 5, text: 'Item 4', order: 1 },
{ id: 6, text: 'Item 5', order: 2 },
],
},
{
id: 7,
text: 'Node 2',
order: 2,
children: [
{ id: 8, text: 'Item 6', order: 1 },
{ id: 9, text: 'Item 7', order: 2 },
],
},
]);
function onDragStart(event) {
const id = parseInt(event.target.dataset.id);
const index = sourceList.value.findIndex(item => item.id === id);
event.dataTransfer.setData('text/plain', JSON.stringify(sourceList.value[index]));
}
watch(targetList, (newVal, oldVal) => {
if (newVal !== oldVal) {
newVal.forEach((item, index) => {
item.order = index + 1;
});
}
}, { deep: true });
return {
sourceList,
targetList,
onDragStart,
};
},
};
</script>
<style>
.node {
padding: 10px;
margin: 5px;
border: 1px solid #ccc;
}
.node.active {
background-color: #eee;
}
.children {
margin-left: 20px;
}
</style>
```
阅读全文