一、父子组件的通信
概念:子组件是不能引用父组件或者Vue实例的数据的。但是在开发中,往往一些数据确实需要从上层传递到下层,比如在一个页面中,我们从服务器请求到了很多的数据,其中一部分数据并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示,这个时候并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)。
二、父子组件间的通信方法
1、父组件传给子组件:通过props(properties:属性)向子组件传递数据。
props基本用法:
在组件中,使用选项props来声明需要从父级接收到的数据。props的值有两种方式:(一般使用对象方式)
(1)方式一:字符串数组,数组中的字符串就是传递时的名称。
(2)方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。
案例:通过props把父组件中movies的内容传给子组件
<body>
<div id="app">
<cpn :cmovies="movies"></cpn>
</div>
<!--使用template标签分离组件模板-->
<template id="cpn">
<div>
<ul>
<li v-for="item in cmovies">{{item}}</li>
</ul>
</div>
</template>
<script>
//父组件传给子组件:props
const cpnC = {
template:'#cpn',
data() {
return {
}
},
//1、数组写法(任选一个方式)
props:["cmovies"],
//2、对象写法:类型限制
props:{
cmovies:Array, //要求以数组的方式传递
//3、对象写法:提供默认值以及必传值
cmovies:{
type:Array,//类型是对象或者数组时,默认值必须是一个函数
default() { //default为在没有传值的情况下设置的默认值
return []
},
required:true //表示必须要传cmovies这个值,不传会报错
}
}
}
//根组件(根组件也是父组件)
const app = new Vue({
el:"#app",
data:{
movies:["海贼王","海尔兄弟"]
},
components:{
cpn:cpnC
}
})
</script>
</body>
注意:在真实的开发中,Vue实例和子组件的通信和父组件和子组件的通信过程是一样的。(Vue实例就是父组件,也可以称为根组件)
2、子组件传给父组件:通过自定义事件向父组件发送信息.
当子组件需要向父组件传递数据时,就要用到自定义事件了,我们之前学习的v-on不仅可以用于监听DOM事件,还可以用于组件间的自定义事件。
自定义事件的流程:
(1)在子组件中,通过$emit()来触发事件;
(2)在父组件中,通过v-on来监听子组件事件。
案例:通过自定义事件把子组件中categories的内容传给父组件
<body>
<!--父组件模板-->
<div id="app">
<!--父组件接收事件(监听事件并在父组件里处理事件)-->
<cpn @itemclick="cpnClick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<script>
//子组件
const cpnC = {
template:'#cpn',
data() {
return {
categories:[
{id:"aa",name:"热门推荐"},
{id:"bb",name:"手机数码"},
{id:"cc",name:"电脑办公"}
]
}
},
methods:{
btnClick(item) {
//子组件发出事件:自定义事件,itemClick为事件的名称,item为传递的事件
this.$emit("itemclick",item)
}
}
}
//父组件
const app = new Vue({
el:"#app",
data:{
},
components:{
cpn:cpnC
},
methods:{
cpnClick(item) {
console.log("cpnClick",item);
}
}
})
</script>
</body>