目录
vm.$emit( eventName, […args] )
在上章的例子中,我们实现了数据的添加,本章将实现删除数据。
一、需求
在上章父子组件中,实现todolist删除功能。上章代码回顾。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue test</title>
<script src="static/js/vue.js"></script>
</head>
<body>
<div id="root">
<div>
<input v-model="note"/>
<button v-on:click="myClick">提交</button>
</div>
<ul>
<todo-item
v-for="(item,index) of list"
:key="index" :content="item">
</todo-item>
</ul>
</div>
<script>
Vue.component('todo-item',{
//接入一下名字叫 content 的外部属性
props: ['content'],
template: '<li @click="">{{content}}</li>',
methods: {
t1: function (){
alert('你单击了:'+this.content)
}
}
})
new Vue({
el: "#root",
data: {
note: '',
list: []
},
methods: {
myClick: function (){
this.list.push(this.note)
this.note=''
}
}
})
</script>
</body>
</html>
如下图所示:
点击已经添加的 a 则,a会删除
二、分析
2.1 js数组的删除方法
我们的数据保存在数组中,js中数据删除可以使用plice方法,语法格式为:
arr.splice(start, count, addElement1, addElement2, ...);
因为我们只删除一个,所以可以使用 arr.splice(<下标>,1)即可。
删除方法知道了,是totolist功能封装成子组件了。为了能删除,当点击子组件元素的时候,能把下标传给父组件,进行删除。所以父组件得把原来数组的下标传给子组件。我们给子组件添加多一个属性叫fatherIndex,把父组件数组中的index传给子组件的fatherIndex属性,所以代码变成:
<ul>
<todo-item
v-for="(item,index) of list"
:key="index" :content="item"
:father-index="index">
</todo-item>
</ul>
2.2 子组件向父组件传值
我们得到了索引号,当点击a或b的时候,我把只要把对应的index值返回给父组件,父组件进行删除即可。
这里使用到子组件向父组件传值的问题,要使用Vue的$emit方法
vm.$emit( eventName, […args] )
-
参数:
{string} 事件名
[...args] 参数
从上面的格式来看,我们还得绑定一个事件才行,那么我们可以自定义一个事件,可以使用v-on命令,格式为:v-on:<自定义事件名>=“<函数名>”,
我们先定义一个事件,我这里是delete,并定义调用父组件del函数,这里不能写在子组件,因为v-for数据来自父组件。这个也简单判断,因为子组件的data没有list,数据是来源于父组件输入的。
<ul>
<!-- 定义一个名为 delete 的事件,并调用del函数-->
<todo-item
v-for="(item,index) of list"
:key="index" :content="item"
:father-index="index"
@delete="del">
</todo-item>
</ul>
实现父组件的del函数删除功能,在父组件例子中添加:
methods: {
...,
del: function (index){
this.list.splice(index,1);
}
}
最后在子组件的函数中调用$emit()方法,即可
methods: {
t1: function (){
this.$emit("delete",this.fatherIndex);
}
}
这样基础上就OK了
三、实现代码
实现总代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue test</title>
<script src="static/js/vue.js"></script>
</head>
<body>
<div id="root">
<div>
<input v-model="note"/>
<button v-on:click="myClick">提交</button>
</div>
<ul>
<!-- 定义一个名为 delete 的事件,并调用del函数 -->
<todo-item
v-for="(item,index) of list"
:key="index" :content="item"
:father-index="index"
@delete="del">
</todo-item>
</ul>
</div>
<script>
Vue.component('todo-item',{
//接入一下名字叫 content 的外部属性
props: ['content','fatherIndex'],
template: '<li @click="t1">{{content}}</li>',
methods: {
t1: function (){
this.$emit("delete",this.fatherIndex);
}
}
})
new Vue({
el: "#root",
data: {
note: '',
list: []
},
methods: {
myClick: function (){
this.list.push(this.note)
this.note=''
},
del: function (index){
this.list.splice(index,1);
}
}
})
</script>
</body>
</html>
运行效果:
点一下b,发现删除了