问题描述
我有 array
个元素,但我想显示它并提供 Draggable 功能 (SortableJS) 但只是其中的一部分 array
.
为此,我使用了原始数据数组中的计算属性并将数组拆分为两个数组,我使用这些计算数组制作了一个列表,但是当我拖动并尝试重新排序拖动列表时,似乎有索引有问题,就像下面的例子,如果你尝试拖动第一个列表,它不会重新排序,但第二个会。
那么我该如何解决这个问题?
new Vue({
el: '#app',components: { draggable: window.vuedraggable },data: () => {
return {
numbers: [1,2,3,4,5,6]
}
},computed: {
evens() {
return this.numbers.filter(number => number % 2 === 0);
},odds() {
return this.numbers.filter(number => number % 2 === 1);
}
}
})
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue.draggable/2.20.0/vuedraggable.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<div id="app">
<div style="display: flex;">
<ul style="width: 50%">
<draggable v-model="numbers"
draggable="li">
<transition-group type="transition">
<template v-for="(number,index) in evens">
<li :key="index">{{ number }}</li>
</template>
</transition-group>
</draggable>
</ul>
<ul>
<template v-for="number in odds">
<li>{{ number }}</li>
</template>
</ul>
</div>
</div>
解决方法
问题是 draggable
的 v-model
(即 numbers
)和在 draggable
(即 evens
)中呈现的元素是两个不同的数据集。当您通过拖动 evens
的 3 个项目重新排序时,draggable
正在重新排序 numbers
中的前 3 个项目,因为这些项目在两个数据集中具有相同的索引。
确保保留列表顺序的一种解决方法是呈现 numbers
的完整列表,但仅呈现 v-show
的偶数:
<draggable v-model="numbers">
<template v-for="(number,index) in numbers">
<li v-show="number % 2 === 0" :key="number">{{ number }}</li>
</template>
</draggable>
请注意,当呈现的列表可以重新排序时,不要使用 index
作为 key
,因为它在移动的项目之间不会是唯一的,从而导致呈现问题(无意中重用元素)。我在上面使用了 number
,因为它在这种情况下是独一无二的。
new Vue({
el: '#app',components: { draggable: window.vuedraggable },data: () => {
return {
numbers: [1,2,3,4,5,6]
}
},computed: {
odds() {
return this.numbers.filter(number => number % 2 === 1);
}
}
})
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0/vuedraggable.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<div id="app">
<div style="display: flex;">
<ul style="width: 50%">
<draggable v-model="numbers"
draggable="li">
<transition-group type="transition">
<template v-for="(number,index) in numbers">
<li v-show="number % 2 === 0" :key="number">{{ number }}</li>
</template>
</transition-group>
</draggable>
</ul>
<ul>
<template v-for="number in odds">
<li>{{ number }}</li>
</template>
</ul>
</div>
<pre>numbers: {{numbers}}</pre>
</div>