Vue.js 从列表中删除元素总是删除 for 的最后一项
Vue.js removing element from list removes always the last item of the for
我已经检查了其他问题,并阅读了“in-place patch”功能,所以我尝试向 v-for 添加密钥但仍然没有成功,有人可以帮助我吗?
这是我当前的代码:
// THE COMPONENT
Vue.component('host-query', {
props : {
"queryvalue" : { type : Object, default : {} },
},
template : '<div class="input-group">' +
'<input class="form-control input-sm col-sm-2" v-bind:class="{ wrongInput : inputError }" v-bind:value="setInput(queryvalue)" @keyup="keyPressed" @input="updateInput($event.target.value)">' +
'<span class="input-group-btn">' +
'<button class="btn btn-sm btn-danger" @click="deleteQuery"> X </button> ' +
'</span>' +
'</div>',
data() {
return {
inputError : false,
keyPressTimeout : null,
inputValue : ''
}
},
methods : {
deleteQuery() {
this.$emit('delete-query');
},
setInput(objValue) {
if (!this.inputValue) {
this.inputValue = JSON.stringify(objValue);
}
return this.inputValue;
},
keyPressed() {
clearTimeout(this.keyPressTimeout);
this.keyPressTimeout = setTimeout(this.validateAndUpdateInput, 1000);
},
validateAndUpdateInput() {
let jsonValue = null;
try {
jsonValue = JSON.parse(this.inputValue);
if (Object.keys(jsonValue).length == 1) {
this.inputError = false;
this.inputValue = '';
this.$emit('input', jsonValue);
} else {
this.inputError = true;
}
} catch (e) {
this.inputError = true;
}
},
updateInput(value) {
this.inputValue = value;
}
}
});
// HERE IS THE HTML
<div class="box host-selector-query-container" v-for="(queryObj, hostQueryIndex) in bundle.hostSelector" v-bind:key="hostQueryIndex">
<host-query v-model="queryObj.query"
v-bind:queryvalue="queryObj.query"
v-bind:index="hostQueryIndex"
@delete-query="removeHostQuery(bundle, hostQueryIndex)">
</host-query>
</div>
// AND THE DELETE QUERY FUNCTION
removeHostQuery (bundle, index) {
bundle.hostSelector.splice(index, 1);
},
我在控制台记录了拼接前后数组的值,正确的元素正在被删除,但是在显示中显示错误,总是最后一个元素被删除,我错过了什么?谢谢!
因为key
。当您使用循环的索引作为 key
时,您告诉 Vue 您的元素由它们的索引标识。
当您删除数组中的一项时,您会将每个索引从删除点向上移动一个,这意味着只有一个索引从数组中消失:最后一个。
由于 Vue 是通过索引来识别元素的,因此具有最后一个索引的元素将被删除。
您应该使用一个属性作为键,该属性唯一 标识元素,而不是索引。
我已经检查了其他问题,并阅读了“in-place patch”功能,所以我尝试向 v-for 添加密钥但仍然没有成功,有人可以帮助我吗?
这是我当前的代码:
// THE COMPONENT
Vue.component('host-query', {
props : {
"queryvalue" : { type : Object, default : {} },
},
template : '<div class="input-group">' +
'<input class="form-control input-sm col-sm-2" v-bind:class="{ wrongInput : inputError }" v-bind:value="setInput(queryvalue)" @keyup="keyPressed" @input="updateInput($event.target.value)">' +
'<span class="input-group-btn">' +
'<button class="btn btn-sm btn-danger" @click="deleteQuery"> X </button> ' +
'</span>' +
'</div>',
data() {
return {
inputError : false,
keyPressTimeout : null,
inputValue : ''
}
},
methods : {
deleteQuery() {
this.$emit('delete-query');
},
setInput(objValue) {
if (!this.inputValue) {
this.inputValue = JSON.stringify(objValue);
}
return this.inputValue;
},
keyPressed() {
clearTimeout(this.keyPressTimeout);
this.keyPressTimeout = setTimeout(this.validateAndUpdateInput, 1000);
},
validateAndUpdateInput() {
let jsonValue = null;
try {
jsonValue = JSON.parse(this.inputValue);
if (Object.keys(jsonValue).length == 1) {
this.inputError = false;
this.inputValue = '';
this.$emit('input', jsonValue);
} else {
this.inputError = true;
}
} catch (e) {
this.inputError = true;
}
},
updateInput(value) {
this.inputValue = value;
}
}
});
// HERE IS THE HTML
<div class="box host-selector-query-container" v-for="(queryObj, hostQueryIndex) in bundle.hostSelector" v-bind:key="hostQueryIndex">
<host-query v-model="queryObj.query"
v-bind:queryvalue="queryObj.query"
v-bind:index="hostQueryIndex"
@delete-query="removeHostQuery(bundle, hostQueryIndex)">
</host-query>
</div>
// AND THE DELETE QUERY FUNCTION
removeHostQuery (bundle, index) {
bundle.hostSelector.splice(index, 1);
},
我在控制台记录了拼接前后数组的值,正确的元素正在被删除,但是在显示中显示错误,总是最后一个元素被删除,我错过了什么?谢谢!
因为key
。当您使用循环的索引作为 key
时,您告诉 Vue 您的元素由它们的索引标识。
当您删除数组中的一项时,您会将每个索引从删除点向上移动一个,这意味着只有一个索引从数组中消失:最后一个。
由于 Vue 是通过索引来识别元素的,因此具有最后一个索引的元素将被删除。
您应该使用一个属性作为键,该属性唯一 标识元素,而不是索引。