如需转载请评论或简信,并注明出处,未经允许不得转载
前言
上一节中我们将ToDoList小工具拆分成了父组件和子组件,我们可以通过v-bind
向子组件中传递数据。那么我们的子组件要如何向父组件传递数据呢?这节中我们通过一个小需求来简单认识Vue中的组件间通信
目录
了解需求
这是上节中我们最终的代码,包含了父组件app
和子组件TodoItem
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="onSubmitClick">提交</button>
<todo-item v-bind:content="item"
v-for="item in list">
</todo-item>
</div>
<script>
var TodoItem = {
props: ['content'],
template: '<li>{{content}}</li>>'
}
var app = new Vue({
el: '#app',
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods: {
onSubmitClick: function () {
this.list.push(this.inputValue)
this.inputValue = ""
}
}
})
</script>
</body>
</html>
运行后,我们提交一个ToDoList,结果如下
现在我们希望我们点击列表中的某一项时,就删除这一项
分析需求
我们知道Vue是基于MVVM模式设计的,所以删除列表中的某一个item只需要删除对应的数据即可。我们需要响应子组件的点击事件,记录被点击的组件的index
,删除父组件data
中的list
中的对应数据
实现步骤
添加列表item的点击事件
var TodoItem = {
props: ['content'],
template: '<li v-on:click="handleItemClick">{{content}}</li>>',
methods: {
handleItemClick: function () {
}
}
}
向外触发事件
var TodoItem = {
props: ['content'],
template: '<li v-on:click="handleItemClick">{{content}}</li>>',
methods: {
handleItemClick: function () {
this.$emit("delete")
}
}
}
我们通过$emit
向外触发一个删除事件,在<todo-item/>
中可以这么使用
<todo-item v-bind:content="item"
v-for="item in list"
v-on:delete="handleItemDelete">
</todo-item>
之后可以在父组件的methods
中声明这个方法
methods: {
...
handleItemDelete: function () {
}
}
传递index数据
我们可以继续使用v-bind
来给TodoItem传递数据
<todo-item v-bind:content="item"
v-bind:index="index"
v-for="(item,index) in list"
v-on:delete="handleItemDelete">
</todo-item>
在子组件中拿到index
后,向父组件传递
var TodoItem = {
props: ['content', "index"],
template: '<li v-on:click="handleItemClick">{{content}}</li>>',
methods: {
handleItemClick: function () {
this.$emit("delete", this.index)
}
}
}
在父组件的handleItemDelete
方法中就可以拿到index
methods: {
...
handleItemDelete: function (index) {
}
}
其他
为了代码更加简洁,写起来效率更高, v-bind:
可以直接写成:
,v-on:
可以直接写成@
完整版
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button @click="onSubmitClick">提交</button>
<todo-item :content="item"
:index="index"
v-for="(item,index) in list"
@delete="handleItemDelete">
</todo-item>
</div>
<script>
var TodoItem = {
props: ['content', "index"],
template: '<li @click="handleItemClick">{{content}}</li>>',
methods: {
handleItemClick: function () {
this.$emit("delete", this.index)
}
}
}
var app = new Vue({
el: '#app',
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods: {
onSubmitClick: function () {
this.list.push(this.inputValue)
this.inputValue = ""
},
handleItemDelete: function (index) {
this.list.splice(index, 1)
}
}
})
</script>
</body>
</html>
总结
本文主要讲了一个非常基础的组件间通信案例,通过$emit
由子组件向父组件发送事件(@delete
),还可以通过这个方法向父组件传递一些数据(index
)
this.$emit("delete", this.index)
网友评论