父到子组件的通信
子组件是不能引用父组件或者vue实例的数据的。但是在开发中,往往一些数据确实需要从上层传递到下层,比如在一个页面中,我们从服务器请求到了很多的数据。其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。这个时候,我们并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)
如何进行父子组件之间的通信呢?
①通过props向子组件传递数据
②通过事件向父组件发送消息
<body>
<div id="app">
<!-- 在组件中需要绑定子父组件的信息 -->
<!-- 注意这里的驼峰命名法不适用,需要改成- -->
<cpn :cmovies="movies" :cmessage="message"></cpn>
<cpn :cmovies="movies"></cpn>
<!-- 显示aaaa -->
<cpn :cmessage="message"></cpn>
</div>
</body>
<!-- //模板 -->
<template id="cpn">
<!-- 注意这里需要根元素 -->
<div>
<ul>
<li v-for="item in cmovies">{{item}}
</li>
</ul>
<h2>{{cmessage}}</h2>
</div>
</template>
<!-- 子父组件通过props传递数据 -->
<script src="../js/vue.js"></script>
<script>
// 注册组件的信息
const cpn = {
template:'#cpn', //与模板进行绑定
//一、通过数组父向子传递数据,少用
// props:['cmovies','cmessage'],
//二、通过对象父向子传递数据
props:{
//1 少用
// cmovies:Array,
// cmessage:String,
//2.对象形式多用
cmovies:{
type:Array,
//如果类型是数组或者对象,默认值必须是一个函数,否则报错
default(){
return []
},
// required:true,
//required 为true 组件必须v-bind传值 不然就会报错
},
cmessage:{
type:String,
default:'aaaaa',
// required:true,
//required 为true 组件必须v-bind传值 不然就会报错
}
},
data(){
return {}
},
methods:{}
}
// 创建vue实例,将组件信息注册放入
const app = new Vue({
el:'#app',
data:{
movies:['111','222','333'],
message:'你好'
},
components:{
'cpn':cpn
}
})
</script>
经过演示,发现子组件中,默认无法访问到父组件中的data上的数据和 methods 中的方法
子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的
组件中的所有 props 中的数据,都是通过父组件传递给子组件的
子到父组件的通信
props用于父组件向子组件传递数据,还有一种比较常见的子组件传递数据或事件到父组件中。
这时我们需要使用自定义事件来完成。
当子组件需要向父组件传递数据时就要用到自定义事件了。我们之前学习的v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件。
流程:①在子组件中用**$emit()来触发事件 ②在父组件中,通过v-on来监听**子组件事件
<!-- 父组件模板 -->
<body>
<div id="app">
<!-- 监听子组件发射的事件 -->
<!-- 监听的事件是子组件在$emit中设置的事件名称 -->
<cpn @itemclick="cpnclick"></cpn>
</div>
</body>
<!-- 子组件模板 -->
<template id="cpn">
<!-- 注意这里需要根元素 -->
<div>
<button v-for="item in categories" @click='btnclick(item)'>{{item.name}}</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template:'#cpn',
data(){
return {
categories:[
{id:'aaa',name:'热门推荐'},
{id:'bbb',name:'手机数码'},
{id:'ccc',name:'家用家电'},
{id:'ddd',name:'电脑办公'},
]
}
},
methods:{
btnclick(item){
//子组件发射(包含点击事件名称和想传入的数据/对象本身)
this.$emit('itemclick',item)
}
}
}
const app = new Vue({
el:'#app',
data:{
},
components:{
'cpn':cpn
},
methods:{
cpnclick(item){ //传入子组件给的数据
console.log(item.name);//可以利用子组件的数据了
}
}
})
</script>