在上一次的父组件和子组件通信的内容中已经介绍了如何实现父传子,接下来小编将和大家一起探讨在父子组件通信中如何实现子传父。
一、使用场景
子组件向父组件传递数据,一般发生在类似table栏的原理,如果不太清楚table栏原理的小伙伴可以参考下面小编的讲解分析,如果已经明白table栏原理的小伙伴可以直接跳过这块内容。让我们先来看下面的图:
① table栏原理
table主要分成标题区和内容区。当用户点击‘智能先锋’的小标题,下面的内容区就会显示与智能先锋相关的内容;当用户点击“居家优品”的小标题,下面的内容区就会与显示居家优品相关的内容,这就是table栏原理
② 子组件传递数据到父组件
按照组件化的思想,table栏的标题区为一个组件,内容区为一个组件。内容区的子组件的数据都是来自父组件的。当用户点击了标题为“家用电器”的子组件,我们希望内容区仅仅展示家用电器的内容,这个时候的父组件要知道用户点击了“家用电器”的子组件才能将家用电器的内容传递到内容区。
具体步骤如下:
书写父子组件的基本构造-->子组件自定义事件 --> 父组件捕获事件 --> 父组件对捕获的事件进行处理
二、实现步骤
为便于理解,本次案例的模型的下图:
1. 书写父子组件的基本构造
<body>
<!-- 父组件的模板 -->
<div class="warp">
<cnp></cnp>
</div>
<!-- 子组件的模板 -->
<template id="btn">
<div>
<button v-for='item in title'>{{item.name}}</button>
</div>
</template>
<script>
// 子组件注册
const cnp = {
template:'#btn',
data(){
return {
title:[
{id:'one',name:'热门推荐'},
{id:'two',name:'家用电器'},
{id:'three',name:'手机数码'},
{id:'four',name:'居家优品'}
]
}
}
}
var vm = new Vue({
el:'.warp',
components:{
cnp
}
})
</script>
</body>
① 子组件的数据
前面已经提到过,子组件不能操作父组件或者Vue实例中的数据,所以用自己的data函数存放,返回值是对象类型。在对象内声明title变量,类型是数组类型,数组内的元素又是一个对象【因为一个元素可能包含很多信息,所以元素用对象来存储】
② 子组件的模板
模板中使用了四个bottom,通过v-for指令来遍历子组件中的title.name数据并显示在按钮中。效果图如下:
2.子组件自定义事件
子组件的自定义事件时为了让子组件内部知道用户操作了哪个组件,因此要用事件监听用户的操作,并且对用户的操作进行处理。比如:
//绑定事件来监听用户的操作
<button v-for='item in title' @click="btnclick(item)">
{{item.name}}
</button>
//在子组件内部对用户操作进行处理
const cnp = {
template:'#btn',
data(){
return {
title:[
{id:'one',name:'热门推荐'},
{id:'two',name:'家用电器'},
{id:'three',name:'手机数码'},
{id:'four',name:'居家优品'}
]
}
},
methods:{
btnclick(item){
console.log(item)
}
}
}
在本例子中,从以下两点来理解:
① 子组件绑定事件:通过点击事件来监听用户操作了哪个标题,并且希望用户点击这个标题的时候把该标题的所有信息都传递到自己的组件内容,所以为button绑定btnclick事件并且传递参数item
② 子组件对事件的处理:当为button绑定了btnclick事件后,在子组件内部就需要对该事件处理。在这里,当用户点击了热门推荐,就在控制台中打印这个标题的所有信息,效果如下:
3.父组件捕获事件
父组件要根据被点击的子组件去请求该子组件的数据,这个过程通过自定义事件实现。简单的说就是将子组件获取的item传递给父组件。具体步骤可以分成下面三步:
① 子组件通过 "this.$emit(自定义事件名,传递的数据)" 发射事件
② 父组件 "v-on或者@" 捕获事件
③ 父组件对事件进行处理
代码如下:
<body>
<div class="warp" >
<!-- ②父组件捕获事件 -->
<cnp @itemclick='cnpclick'></cnp>
</div>
<template id="btn">
<div>
<button v-for='item in title' @click="btnclick(item)">
{{item.name}}
</button>
</div>
</template>
<script>
const cnp = {
template:'#btn',
data(){
return {
title:[
{id:'one',name:'热门推荐'},
{id:'two',name:'家用电器'},
{id:'three',name:'手机数码'},
{id:'four',name:'居家优品'}
]
}
},
methods:{
btnclick(item){
//① 子组件发射事件给父组件
this.$emit('itemclick',item)
}
}
}
var vm = new Vue({
el:'.warp',
components:{
cnp
},
methods:{
// ③父组件对事件进行处理
cnpclick(item){
console.log(item)
}
}
})
</script>
</body>
代码的分析如下:
① 子组件发射事件--this.$emit('itemclick',item):我们知道,对于事件的处理都在methods方法内部。所以在这个例子中,对用户点击事件btnclick的处理就是向父组件发射名字为itemclick的事件并且传递参数item。
② 父组件捕获事件--<cnp @itemclick='cnpclick'></cnp>:当子组件向父组件发射itemclick事件后,父组件通过v-on指令或者@来捕获子组件发射的itemclick事件并对事件的处理放在方法cnpclick中
③ 父组件捕获事件后的处理--cnpclick(item):父组件对事件的处理放在了cnpclick方法中,因此在父组件内部的methods方法内部才有了cnpclick(item)函数。效果图如下:
当点击子组件的“热门推荐”,父组件就会打印“热门推荐”的信息
以上就是小编今天为大家分享的父组件和子组件通信中的子组件向父组件传递数据,总结起来就是:子组件发射事件,父组件捕获事件后并进行处理。