[英]Send index from child component to the parent one to remove array item in v-for - VUE.JS 2
I am a little newbie using Vue JS, so i started with Vue 2. 我是一个使用Vue JS的小新手,所以我从Vue 2开始。
I need to remove an array item but the button that trigger that method is inside a template and the v-for is inside a parent template. 我需要删除一个数组项,但触发该方法的按钮位于模板内,而v-for位于父模板中。
This is my HTML: 这是我的HTML:
MAIN 主要
<div id="main">
<div class="panel-group" id="panelGrp">
<div class="row panelTopSpacing" v-for="panel in panels" is="panel-row" :panel.sync="panel" :general-fields="generalFields" :assistants="assistants" :companies="companies" :positions="positions"></div>
</div>
</div>
CHILD 儿童
//CHILD TEMPLATE
<template id="panelsTpl">
<div class="panel panel-success">
<div class="panel-heading">
{{panel.title}}
<a :class="panel.classObj.link" role="button" data-toggle="collapse" data-parent="#panelGrp" :href.sync="'#'+panel.id"></a>
<i :class="panel.infoIcon"></i>
</div>
<div :id.sync="panel.id" :class="panel.classObj.panel">
<div class="panel-body">
<div class="container-fluid" v-if="panel.id === 'genInfo'">
<div class="row">
<div v-for="genField in generalFields" is="general-field" :gen-field.sync="genField"></div>
</div>
</div>
<div class="container-fluid" v-else-if="panel.id === 'assistants'">
<div class="row">
<table class="table table-striped table-responsive table-hover">
<tr>
<th>Internal?</th>
<th>Can read?</th>
<th>Position</th>
<th>Name</th>
<th>Company</th>
<th width="50px"> </th>
</tr>
<tr>
<td><input type="checkbox"></td>
<td><input type="checkbox" ></td>
<td></td>
<td><input type="text" class="form-control"></td>
<td></td>
<td><a href="#" @click="addAssistant()"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></a></td>
</tr>
<tr v-for="(assistnt,index) in assistants" is="assistant-row" :assistant.sync="assistnt"></tr>
</table>
</div>
</div>
</div>
</div>
</div>
</template>
CHILD OF CHILD TEMPLATE 儿童模板儿童
<template id="asstntsTpl">
<tr v-if="! editing">
<td>{{ assistant.internal }}</td>
<td>{{ assistant.allowRead }}</td>
<td>{{ assistant.positionId | position }}</td>
<td>{{ assistant.name }}</td>
<td>{{ assistant.cmpnyId | company }}</td>
<td>
<a href="#" @click="edit()"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a>
<a href="#" @click="remove(index)"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
</td>
</tr>
<tr v-else>
<td><input type="checkbox" v-model="assistant.internal"></td>
<td><input type="checkbox" v-model="assistant.allowRead"></td>
<td><!--<select-position :position="positions" :id.sync="assistant.positionId"></select-position>--></td>
<td><input type="text" v-model="assistant.name" class="form-control"></td>
<td><!--<select-company :company="companies" :id.sync="assistant.cmpnyId"></select-company>--></td>
<td><a href="#" @click="update()"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></a></td>
</tr>
</template>
JS: JS:
var main = new Vue({
el: "#main",
data: {
valid: false,
new_assistant: {
id: "",
name: "",
internal: true,
cmpnyId: "",
positionId: "",
allowRead: false
},
panels: [
{id: "genInfo", title: "General Info", classObj: {panel: "panel-collapse collapse in", link: ""}, infoIcon: "fas fa-file-alt infoIcon pull-right"},
{id: "assistants", title: "Assistants", classObj: {panel: "panel-collapse collapse", link: "collapsed"}, infoIcon: "fas fa-users infoIcon pull-right"},
{id: "agrmtns", title: "Agreements", classObj: {panel: "panel-collapse collapse", link: "collapsed"}, infoIcon: "fas fa-file-signature infoIcon pull-right"}
]
assistants: [
{id: "1",
name: "Bob",
internal: true,
cmpnyId: "1",
positionId: "1",
allowRead: false},
{id: "2",
name: "John",
internal: true,
cmpnyId: "1",
positionId: "1",
allowRead: false}
],
companies: [
{id: "1", name: "cmpny1"},
{id: "2", name: "cmpny2"},
{id: "3", name: "cmpny3"}
],
positions: [
{id: "1", name: "Pos1"},
{id: "2", name: "Pos2"},
{id: "3", name: "Pos3"}
]
},
methods: {
addAssistant: function () {
this.assistants.push(this.new_assistant);
this.new_assistant = {
id: "",
name: "",
internal: true,
cmpny_id: "",
position_id: "",
allowRead: false};
}
}
Everthing is working fine at this moment, but when I try to delete a row from the table that is populated with assistants array, it deletes the first row however i clicked the trash icon of second row. Everthing此时工作正常,但是当我尝试从填充了助手数组的表中删除一行时,它会删除第一行,但是我单击了第二行的垃圾桶图标。
VUE COMPONENT : VUE组成部分 :
Vue.component("assistant-row", {
template: "#asstntsTpl",
props: ["nw-assistant", "assistant"],
data: function () {
return {
editing: false
};
},
methods: {
remove: function (index) {
this.$parent.assistants.splice(**index**, 1);
},
edit: function () {
this.editing = true;
},
update: function () {
this.editing = false;
}
}
});
Seems like splice is not working at all. 看起来像拼接根本不起作用。
PD::: I know how to use it in a simple scenario, like: PD :::我知道如何在一个简单的场景中使用它,例如:
<li v-for="cat,index in categories">
<button @click="remove(index)">Remove</button>
</li>
I made this little jsfiddle simulating something like above code: 我做了这个小jsfiddle模拟上面的代码:
https://jsfiddle.net/empiricalDev/eywraw8t/399050/ https://jsfiddle.net/empiricalDev/eywraw8t/399050/
Thanks in advance. 提前致谢。
Regards! 问候!
You could try to use this.$emit()
to emit an event to the parent component like this.$emit("delete",this.todo);
您可以尝试使用
this.$emit()
向父组件发出一个事件,如下this.$emit("delete",this.todo);
which has event
name as first parameter and this.todo
as a second one, in the parent component add @delete="removechild"
as follow : 其中
event
名称为第一个参数, this.todo
为第二个参数,在父组件中添加@delete="removechild"
如下:
<tod v-for="(todo, index) in todos" :todo="todo" @delete="removechild"></tod>
and implement your removechild
in the parent component as follow : 并在父组件中实现
removechild
,如下所示:
removechild(todo){
this.todos.splice(this.todos.indexOf(todo),1);
}
Note : 注意 :
if your prop
is an object like {id:1,name:"todo 1"}
you could filter your todos
array like this.todos= this.todos.filter((item)=>{return item.id!=todo.id});
如果你的
prop
类似于对象{id:1,name:"todo 1"}
您可以过滤你的todos
阵列一样this.todos= this.todos.filter((item)=>{return item.id!=todo.id});
Vue.component("tod",{ template:"#tpl", props:["todo"], methods: { remove: function() { this.$emit("delete",this.todo); } } }); new Vue({ el: '#app', data: { todos: ['Buy milk', 'Do exercises', 'Write a book', 'Plant a tree'] }, methods:{ removechild(todo){ this.todos= this.todos.filter((item)=>{return item!=todo}); } } })
body { background: #20262E; padding: 20px; font-family: Helvetica; } #app { background: #fff; border-radius: 4px; padding: 20px; transition: all 0.2s; } li { margin: 8px 0; } h2 { font-weight: bold; margin-bottom: 15px; } del { color: rgba(0, 0, 0, 0.3); }
<!DOCTYPE html> <html> <head> <meta name="description" content="Vue.delete"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.min.js"></script> </head> <body> <div id="app"> <ol> <tod v-for="(todo, index) in todos" :todo="todo" @delete="removechild"></tod> </ol> </div> <template id="tpl"> <li> {{todo}} <button @click="remove">×</button> </li> </template> </body> </html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.