在学习vue中,往往会碰到父子组件之间的通信问题,用一张图来简单解释下父子之间如何通信
由图可以知道 父组件传递参数给子组件 子组件通过props接收参数
父子通信
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<script src="./base/vue.js"></script>
<body>
<div id="app">
<father></father>
</div>
<template id="father">
<div>
<p>这是father组件!---> {{pMsg}}</p><!-- 这里pMsg是驼峰命名,这里显示是父组件的data数据 -->
<!-- 子组件在父组件中调用 -->
<son :p-msg="pMsg"></son>
</div>
</template>
</body>
<script>
Vue.component("father",{
template:"#father",
data:function(){
return {
pMsg:"hello father"
}
},
// 在父组件中定义子组件
components:{
son:{
template:"<div>这是son子组件... {{pMsg}}</div>",
props:["pMsg"] //接受父组件传递来的属性
}
}
})
let vm = new Vue({
el: '#app',
data:{
msg:"hello app!"
}
})
</script>
</html>
- 在使用子组件标签的时候,使用v-bind绑定一个属性,属性名我们就起p-msg,属性值是父组件要传递给子组件的pMsg
- 在子组件中使用props数组接收一下父组件传递过来的属性
- 在子组件中可以直接使用p-msg了,显示的值就是父组件中的pMsg的值
在这我们要思考一个问题 : 为什么组件中的data必须是一个函数返回对象的形式?
解析:
- 目的是让每一个实例可以维护一份被返回对象的独立的拷贝 (每个组件使用到的数据地址不一样)
- 内部必须要返回一个对象的写法,这样就可以保证每个组件里面用到的数据对象都是唯一的。
- 组件之间的作用域是相互独立的,组件的数据默认只能组件的模板里面使用。
子父通信
现在我们来讨论子父之间的通信
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<script src="./base/vue.js"></script>
<body>
<div id="app">
<father></father>
</div>
<template id="father">
<div>
<p>这是父组件</p>
<p>这是我儿子要和我说的话 ===> {{pMsg}}</p>
<hr>
<!--在调用子组件的时候,需要给其自身绑定一个自定义事件 change-->
<son @change="changeMsg"></son>
</div>
</template>
<template id="son">
<div>
<p>这是子组件 {{msg}}</p>
<p><button @click="say">我要对父亲说的话!</button></p>
</div>
</template>
</body>
<script>
Vue.component("father",{
template:"#father",
data(){
return {
pMsg:""
}
},
methods:{
changeMsg(msg){
this.pMsg = msg
}
}
})
Vue.component("son",{
template:"#son",
props:["change"],
data(){
return {
msg:"今天很舒服"
}
},
methods:{
say(){
//需要触发其自身绑定的change方法 <son @change="changeMsg"></son>
this.$emit("change",this.msg)
}
}
})
new Vue({
el:"#app"
})
</script>
</html>
浏览器显示:
点击之后:
解析一下主要代码:
(1)父组件给子组件传递一个change函数 子组件props接收函数
(2)子组件自身定义一个say方法 点击触发say方法
(3)say方法被调用再根据this.$emit派发change方法,并且吧this.msg当做参数传递过去
(4)change方法被调用就调用了父组件上的changeMsg方法,changeMsg方法接收一个子组件传来的参数,并且赋值给自身的pMsg
这就完成了子父之间的通信
总结:
子传父的关键在于 e m i t 注 册 的 方 法 , 还 有 第 二 个 值 是 要 传 递 的 数 据 , 我 们 可 以 想 象 成 emit注册的方法,还有第二个值是要传递的数据,我们可以想象成 emit注册的方法,还有第二个值是要传递的数据,我们可以想象成emit是派发出去一个方法,并携带数据,在父组件使用子组件的时候,利用v-on绑定一个事件,事件名是$emit派发的方法,事件函数是父组件本身的方法,在父组件的methods中接收传递过来的数据即可