在小型项目当中,如果不考虑
VueX
,组件之间的通信该如何处理,接下来我们创建parents
childA
childB
三个组件演示如何传递与接收
parents组件
:
<template>
<div>
<childA/>
<childB/>
</div>
</template>
<script>
export default {
components: {
childA: () => import('@/components/childA'),
childB: () => import('@/components/childB'),
},
}
</script>
childA组件
:
<template>
<div>
<h2>Hello,我是ChildA组件</h2>
</div>
</template>
<script>
export default {
}
</script>
childB组件
:
<template>
<div>
<h2>Hello,我是ChildB组件</h2>
</div>
</template>
<script>
export default {
}
</script>
运行效果如下
1.父组件传递子组件,子组件接收父组件
这里我想
parents
组件给ChildA
组件传一个Hi , ChildA! 我是你爸爸!
,
parents
组件给ChildB
组件传一个Hi , ChildB! 我也是你爸爸!
那么该怎么处理?这里子组件在父组件中作为标签引入,通过设置标签的属性传递数据,在子组件用props
接收
注这里的props可接收类型
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
这里我们设置一个标签属性message
parents组件
:
<template>
<div>
<childA :message="toChildA"/>
<childB :message="toChildB"/>
</div>
</template>
<script>
export default {
components: {
childA: () => import('@/components/childA'),
childB: () => import('@/components/childB'),
},
data(){
return{
toChildA:'Hi , ChildA! 我是你爸爸!',
toChildB:'Hi , ChildB! 我也是你爸爸!',
}
}
}
</script>
childA组件
:
<template>
<div>
<h2>Hello,我是ChildA组件</h2>
<div>来自parents组件的信息:{{message}}</div>
</div>
</template>
<script>
export default {
props:{
message:String
}
}
</script>
childB组件
:
<template>
<div>
<h2>Hello,我是ChildB组件</h2>
<div>来自parents组件的信息:{{message}}</div>
</div>
</template>
<script>
export default {
props:{
message:String
}
}
</script>
运行效果如下
2.子组件传递父组件,父组件接收子组件
子组件通过$emit
触发事件,父组件通过v-on
接收触发事件
通俗的来说
childA组件
:$emit('A触发的事件名称')
那么相应的parents组件
就需要接收同样的事件
<childA @A触发的事件名称="parents组件用于接收的方法" />
parents组件
:
<template>
<div>
<childA @from_child_a="receiveChildA" :message="toChildA"/>
<i>这是ChildA发过来的消息 : {{childAMsg}}</i>
<childB @from_child_b="receiveChildB" :message="toChildB"/>
<i>这是ChildB发过来的消息 : {{childBMsg}}</i>
</div>
</template>
<script>
export default {
components: {
childA: () => import('@/components/childA'),
childB: () => import('@/components/childB'),
},
data(){
return{
toChildA:'Hi , ChildA! 我是你爸爸!',
toChildB:'Hi , ChildB! 我也是你爸爸!',
childAMsg:'',
childBMsg:''
}
},
methods:{
receiveChildA(pramas){
this.childAMsg = pramas
},
receiveChildB(pramas){
this.childBMsg = pramas
}
}
}
</script>
childA组件
:
<template>
<div>
<h2>Hello,我是ChildA组件</h2>
<div>来自parents组件的信息:{{message}}</div>
</div>
</template>
<script>
export default {
props:{
message:String
},
mounted(){
this.$emit('from_child_a','Hi,爸爸 , 我是ChildA')
}
}
</script>
childB组件
:
<template>
<div>
<h2>Hello,我是ChildB组件</h2>
<div>来自parents组件的信息:{{message}}</div>
</div>
</template>
<script>
export default {
props:{
message:String
},
mounted(){
this.$emit('from_child_b','Hi,爸爸 , 我是ChildB')
}
}
</script>
运行效果如下
3.平行兄弟组件之间的数据传递
上面我们讲了子传父,父传子,子接收父,父接收子,那么平行的两个组件之间我们该怎么通信呢?这里引入一个概念‘总线’,你可以把它理解为全局的
window
,但是又不同于window
,它的作用就好像十字路口,就是我不管你什么方向的车,你都可以从我这里过,而我既可以接受你的信号,我也能把你的信号传递给别人。
具体怎么实现的?
这里我们新建一个bus.js
,新建一个Vue
对象并且挂载注入到vue
对象里,在main.js
引用
import Vue from 'vue'
export const Bus = new Vue()
export default Vue => {
const bus = Bus;
Vue.bus = bus;
Vue.prototype.$bus = bus
}
main.js
引入使用,这样全局就注册了一个bus
总线
注意:注册的总线事件要在组件销毁时卸载,否则会多次挂载,造成触发一次但多个响应的情况
import Bus from './utils/bus'
Vue.use(Bus)
ChildA组件
:
<template>
<div>
<h2>Hello,我是ChildA组件</h2>
<div>来自parents组件的信息:{{message}}</div>
<button @click="sendMsgToB">我要给ChildB发送信息</button>
</div>
</template>
<script>
export default {
props:{
message:String
},
mounted(){
this.sendToParent()
},
methods:{
sendToParent(){
this.$emit('from_child_a','Hi,爸爸 , 我是ChildA');
},
sendMsgToB(){
this.$bus.$emit('from_bro_child_a','Hi,兄弟,我是ChildA'+Math.random())
}
},
beforeDestroy () {
this.$bus.$off('from_bro_child_a')
}
}
</script>
ChildB组件
:
<template>
<div>
<h2>Hello,我是ChildB组件</h2>
<div>来自parents组件的信息:{{message}}</div>
<div style="color: red">来自兄弟ChildA组件的信息:{{fromBroChildAMsg}}</div>
</div>
</template>
<script>
export default {
props:{
message:String
},
data(){
return{
fromBroChildAMsg:null
}
},
mounted(){
this.sendToParent()
this.watchBus()
},
methods:{
sendToParent(){
this.$emit('from_child_b','Hi,爸爸 , 我是ChildB');
},
watchBus(){
let that = this;
this.$bus.$on('from_bro_child_a', (pramas) => {
that.fromBroChildAMsg= pramas
})
}
}
}
</script>
运行效果如下