I want to create a drag and drop application using the Vue JS framework.
I'm pretty sure the problem is inside the oneDrop
function
onDrop(e, categoryId) {
const itemId = parseInt(e.dataTransfer.getData('itemId'))
this.categories.map(item => {
item.children = item.children.filter(child => {
if (child.id == itemId) {
child.categoryId = categoryId;
this.categories[categoryId].children.push(child);
}
return child
})
})
}
Of course, I understand that when dragging using the push
method, the old object remains and is not deleted, so I get this error, but how to deal with this problem? (Full code at the beginning of the question)
CodePudding user response:
You need to filter list from and add item to list to:
new Vue({
el: "#demo",
data() {
return {
categories: [
{id: 0, title: "This is parrent block", children: [{ id: 0, title: "AAA", categoryId: 0 }, { id: 1, title: "BBB", categoryId: 0 },],},
{id: 1, title: "This is parrent block", children: [{ id: 2, title: "CCC", categoryId: 1 }, { id: 3, title: "DDD", categoryId: 1 },],},
],
};
},
methods: {
onDrop(e, categoryId) {
const itemId = parseInt(e.dataTransfer.getData("itemId"));
const id = categoryId === 0 ? 1 : 0
const child = this.categories[id].children.find(c => c.id === itemId)
child.categoryId = categoryId;
this.removeFromList(id, itemId)
this.addToList(categoryId, child)
},
addToList(categoryId, child) {
this.categories[categoryId].children = [...this.categories[categoryId].children, child];
},
removeFromList(id, itemId) {
this.categories[id].children = this.categories[id].children.filter(c => c.id !== itemId);
},
onDragStart(e, item) {
e.dataTransfer.dropEffect = "move";
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.setData("itemId", item.id.toString());
},
},
})
.droppable {
padding: 15px;
border-radius: 5px;
background: #2c3e50;
margin-bottom: 10px;
}
.droppable h4 {
color: white;
}
.draggable {
background: white;
padding: 5px;
border-radius: 5px;
margin-bottom: 5px;
}
.draggable h5 {
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div
v-for="category in categories"
:key="category.id"
@drop="onDrop($event, category.id)"
@dragover.prevent
@dragenter.prevent
>
<h4>{{ category.title }}</h4>
<div >
<div
v-for="item in category.children.filter(
(x) => x.categoryId === category.id
)"
:key="item.id"
@dragstart="onDragStart($event, item)"
draggable="true"
>
<h5>{{ item.title }}</h5>
</div>
</div>
</div>
{{categories}}
</div>