我有一个列表,我正在使用for循环来遍历它。结构如下所示:
salesLists: {
1: [ [], [], [] ]
2: [ [], [] ]
}
和html:
<div v-for="(saleLists, index) in salesLists">
<my-comp v-for="(item, i) in saleLists" :key="i" :index="parseInt(i)+1"></my-comp>
</div>
现在,我正在尝试从salesLists[1]
数组中删除项目。我有一个按钮和@click="removeForm"
:
removeForm(e) {
var index = parseInt(e.target.getAttribute('data-index')) - 1 // = 2
var client = e.target.getAttribute('data-client') // = 1
//Vue.delete(this.salesLists[client], index);
this.salesLists[client].splice(index, 1)
this.$forceUpdate()
}
然而,它删除了它,因为我没有指定任何键,它只是空数组(我假设),它不是从DOM中删除正确的元素。它删除了2的索引,但由于它是v-for
循环遍历项目,并且count减少了,它只删除了最后一项。
克服此问题的正确方法是什么? :/
这是一个小提琴:https://jsfiddle.net/8rvfz40n/ 尝试为每个输入字段写入不同的值并删除中间的值,您将看到它将删除最后一个
答案 0 :(得分:4)
<div v-for="(saleLists, index) in salesLists"> <my-comp v-for="(item, i) in saleLists" :key="i" :index="parseInt(i)+1"></my-comp> </div>
使用索引作为键是问题,当您从中间删除项目时,丢失的索引是最后一个。
就我而言,我找到的解决方案是添加一个独特的&#34; Hash&#34;对于项目,如ID,但如果项目是新闻,则ID为空。
我使用的哈希是一个时间戳:
Hash: new Date().getTime()
然后:
<div v-for="(saleLists, index) in salesLists">
<my-comp v-for="(item, i) in saleLists" :key="item.Hash" :index="parseInt(i)+1"></my-comp>
</div>
答案 1 :(得分:1)
这个让我觉得很多人绊倒了。
我在vue论坛上写了一个回答 在https://forum.vuejs.org/t/solved-array-of-components-wrong-after-element-remove/11866/3
所以问题是这个
你有一个数组[rec1,rec2,rec3]
该数组的键是0,1,2
如果删除索引为1的项目,则会得到一个值为[rec1的数组], rec3],但键是[0,1],因为数组不跳过 删除后的索引。一旦你在模板中绘制它, 由于您没有定义键,因此组件看到的更改是 键或索引2丢失,这是最后一项,所以它 删除它。
要解决这个问题,您需要找到一种不同的方法来确保您定位目标项目
https://jsfiddle.net/8rvfz40n/2/
在您的情况下,使用项list
而不是索引i
将删除预期的项目
<div id="app">
<div v-for="lists in xLists">
<my-comp v-for="(list, i) in lists" :list="list"></my-comp>
</div>
</div>
我应该提到另一个选择是以某种方式将唯一键存储在数组中,但正如您可以想象的那样,这可能更难维护
答案 2 :(得分:0)
您的问题实际上非常简单:您在第一个循环中丢失了xLists
中对象键的引用。如果您存储对象键并将其作为道具传递,您将保留该引用:
<div v-for="(saleLists, index) in salesLists">
<!-- index will refer to the object key -->
<my-comp v-for="(item, i) in saleLists" :key="i" :index="i+1" :sales-list-index=":index"></my-comp>
</div>
您可以简单地检索prop salesListIndex
并将其用作指向对象中正确嵌套数组的键。目前尚不清楚实际示例中的组件是如何编写的,而是参考您的小提琴(我使用了字母键,以便您可以判断它是对象键还是数组键,但实现方式如此)是完全相同的):
Vue.component('my-comp', {
props: ['index', 'value', 'listKey'],
template: `
<div>
<p>xListsKey: {{ listKey }}, index: {{ index }}</p>
<input :value="value" />
<button :data-index="index" @click="remove">del </button>
</div>
`,
methods: {
remove(e) {
var index = e.target.getAttribute('data-index');
this.$parent.xLists[this.listKey].splice(index, 1)
}
}
})
new Vue({
el: '#app',
data: {
xLists: {
'aa': [
['lorem'],
['ipsum'],
['dolor']
],
'bb': [
['foo'],
['bar']
]
}
}
})
&#13;
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div v-for="(lists, listKey) in xLists" :key="listKey">
<my-comp v-for="(list, i) in lists" :key="i" :index="i" :value="list" :list-key="listKey"></my-comp>
</div>
</div>
&#13;