Я хочу создать приложение для перетаскивания с использованием платформы Vue JS. Вот пример моего полного кода.
Проблема в свойствах id
внутри массивов children
.
Например, когда я перетаскиваю объект с именем «ААА» в другое место, у меня все работает нормально, но когда я перетаскиваю его обратно, я получаю ошибку типа - Обнаружены повторяющиеся ключи: «0». Это может вызвать ошибку обновления.
Я почти уверен, что проблема внутри функции oneDrop
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
})
})
}
Я конечно понимаю, что при перетаскивании методом push
старый объект остается и не удаляется, поэтому получаю эту ошибку, но как бороться с этой проблемой? (Полный код в начале вопроса)
Вам нужно отфильтровать список и добавить элемент в список:
new Vue({
el: "#demo",
data() {
return {
categories: [
{id: 0, title: "This is parent block", children: [{ id: 0, title: "AAA", categoryId: 0 }, { id: 1, title: "BBB", categoryId: 0 },],},
{id: 1, title: "This is parent 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)"
class = "droppable"
@dragover.prevent
@dragenter.prevent
>
<h4>{{ category.title }}</h4>
<div class = "child">
<div
v-for = "item in category.children.filter(
(x) => x.categoryId === category.id
)"
:key = "item.id"
@dragstart = "onDragStart($event, item)"
class = "draggable"
draggable = "true"
>
<h5>{{ item.title }}</h5>
</div>
</div>
</div>
{{categories}}
</div>
Больше приходит со стороны
:key
здесь (вv-for
).