我正在制作一个简单的待办事项列表来学习 Vue。
我按照这种方法从列表中添加/删除元素: Vue.js guide
当我从数组中删除一个元素时,我希望该元素消失,然后它下面的其他元素占据它的空间。但在我的例子中,元素向上移动,然后列表的最后一个元素(已“复制”到上一个位置)被删除。
问题:元素已正确删除,但转换错误。
重现问题:单击其中一项“删除”,然后查看列表末尾。
JSFiddle: link
HTML:
<div id="todoList">
<h1>todos </h1>
<input type="text" v-model="newItemText" class="new-todo" autofocus placeholder="What needs to be done?" @keyup.enter="addTodo">
<ul>
<transition-group name="list" >
<li v-for="(data, index) in todoList" v-bind:key="index">
{{data.text}}
<span class="remove-btn" v-on:click="removeItem(index)"> remove </span>
</li>
</transition-group>
</ul>
CSS:
<style>
.list-enter-active,
.list-leave-active {
transition: all 1s;
}
.list-enter,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
JS:
var app = new Vue({
el: "#todoList",
data: {
delete: '',
newItemText: '',
todoList: [
{text: '0'},
{text: '1'},
{text: '2'},
{text: '3'},
{text: '4'},
{text: '5'},
{text: '6'},
{text: '7'}
]
},
methods: {
addTodo: function(){
/* this.todoList.reverse(); */
if(this.newItemText != ''){
this.todoList.push({text: this.newItemText});
/* this.todoList.splice(0,0,{text: this.newItemText}); */
}
this.newItemText = '';
/* this.todoList.reverse(); */
},
removeItem: function(index) {
console.log(index);
this.todoList.splice(index, 1);
}
}
})
最佳答案
问题在于您选择的 key
。
Vue 使用 key
来确定从一个渲染到下一个渲染的哪些 VNode 是等效的。当您使用 index
时,它会为数组条目配对错误的节点,并且当没有找到最终节点的伙伴时,它将删除该节点。
所以最初你有键为 0 到 7 的节点。然后你删除索引 4 处的数组项。但是当 Vue 更新渲染时,它看不到 4 已被删除。它只看到键为 0 到 6 的节点。据它所知,键为 7 的节点已被删除。
要进行快速实验,请尝试使用 :key="data.text"
。您会看到它现在可以工作,但 text
并不是 key
的最佳选择,因为它不一定是唯一的。您可能应该向数组条目添加某种唯一的 id,以便可以使用它。
关于javascript - 为什么在 Vue 中从数组中删除元素时会在最后一个索引处发生转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59347631/