vue是一个轻量级的渐进式框架,对于它的一些特性和优点在此不做阐述,本篇文章主要来学习一下Vue子父组件通信的问题。
gitHub地址:整个案例的Demo
首先先定义一下,相对本案例来说App.vue是父组件, Child.vue是子组件。
一、父组件向子组件传值
1、创建子组件,在src/components文件夹下新建一个Child.vue
2、Child.vue中创建props,然后创建一个名为message的属性
<template>
<div>
<h2>child子组件部分</h2>
<p>{{message}}</p>
</div>
</template>
<script>
export default {
props:['message']
}
</script>
3、在App.vue中注册Child组件,并在template中加入child标签,标签中添加message属性并赋值
<template>
<div id="app">
<child message="hello"></child>
</div>
</template>
<script>
import child from './components/Child.vue'
export default {
name: 'App',
components:{
child
}
}
</script
4、保存修改的文件,查看浏览器
5、我们依然可以对message的值进行v-bind动态绑定
<template>
<div id="app">
<child v-bind:message="parentMsg"></child>
</div>
</template>
<script>
import child from './components/Child.vue'
export default {
name: 'App',
data(){
return{
parentMsg:"hello,hello"
}
},
components:{
child
}
}
</script>
此时浏览器中显示:
结果:父组件向子组件传值成功!!!
总结一下:
- 子组件在props中创建一个属性,用以接受父组件传过来的值
- 父组件中注册子组件
- 在子组件标签中添加子组件props中创建的属性
- 把需要传给子组件的值赋给该属性
二、子组件向父组件传值
1、在子组件中创建一个按钮,给按钮一个点击事件
<template>
<div>
<h2>child子组件部分</h2>
<p>{{message}}</p>
<button v-on:click="sendMsgToParent">向父组件传值</button>
</div>
</template>
<script>
export default {
props:['message'],
methods:{
sendMsgToParent:function () {
}
}
}
</script>
2、在响应该点击事件的函数中使用$emit来触发一个自定义事件,并传递一个参数
<template>
<div>
<h2>child子组件部分</h2>
<p>{{message}}</p>
<button v-on:click="sendMsgToParent">向父组件传值</button>
</div>
</template>
<script>
export default {
props:['message'],
methods:{
sendMsgToParent:function () {
this.$emit("listenToChildEvent","this message is from child")
}
}
}
</script>
3、在父组件中的子标签中监听该自定义事件并添加一个响应该事件的处理方法
<template>
<div id="app">
<child v-bind:message="parentMsg" v-on:listenToChildEvent="showMsgFromChild"></child>
</div>
</template>
<script>
import child from './components/Child.vue'
export default {
name: 'App',
data(){
return{
parentMsg:"hello,hello"
}
},
methods:{
showMsgFromChild:function (data) {
console.log(data);
}
},
components:{
child
}
}
</script>
4、保存修改的文件,在浏览器中点击按钮
结果:子组件向父组件传值成功!!!
总结一下:
- 子组件中需要以某种方式例如点击事件的方法来触发一个自定义事件
- 将需要传的值作为$emit的第二个参数,该值将作为实参传给响应自定义事件的方法
- 在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听
在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是中间介质,子向父的介质是自定义事件,父向子的介质是props中的属性。抓准这两点对于父子通信就好理解了。
三、兄弟组件传值
1、兄弟之间传递数据需要借助于事件车,通过事件车的方式传递数据。
2、创建一个Vue的实例,让各个兄弟共用同一个事件机制。
3、传递数据方,通过一个事件触发bus.$emit(方法名,传递的数据)。
4、接收数据方,通过mounted(){}bus.$on(方法名,function(接收数据的参数){用该组件的数据接收传递过来的数据}),此时函数中的this已经发生了改变,可以使用箭头函数。
实例如下:
我们可以创建一个单独的js文件eventVue.js,内容如下
import Vue from 'vue'
export default new Vue
假如父组件如下:
<template>
<div id="app">
<componentsA></componentsA>
<componentsB></componentsB>
</div>
</template>
<script>
import componentsA from './components/componentsA.vue'
import componentsB from './components/componentsB.vue'
export default {
name: 'App',
components:{
componentsA,
componentsB
}
}
</script>
子组件A如下举例:
<template>
<div>
<button @click="abtn">A按钮</button>
</div>
</template>
<script>
import bus from '../assets/eventBus'
export default {
name:'componentsA',
data(){
return{
msg:'我是组件A'
}
},
methods:{
abtn:function(){
bus.$emit("myFun",this.msg) //$emit这个方法会触发一个事件
}
}
}
</script>
子组件B如下举例:
<template>
<div>
<div>{{btext}}</div>
</div>
</template>
<script>
import bus from '../assets/eventBus'
export default {
name:'componentsB',
data () {
return {
'btext':"我是B组件内容"
}
},
created:function(){
this.bbtn();
},
methods:{
bbtn:function(){
bus.$on("myFun",(message)=>{ //这里最好用箭头函数,不然this指向有问题
this.btext = message
})
}
}
}
</script>
这样在子组件A里面点击函数就可以改变兄弟组件B里面的值了。