前言
vue组件通信的方式如此之多 今天我们来总结一下 完整代码
一、 props、$emit/v-on
父组件通过props向子组件传递数据
子组件使用事件抛出一个值
父组件代码
1 | <template> |
2 | <div class="parent"> |
3 | <h4>我是父组件</h4> |
4 | <child :title="title" @getMsg="getMsgFromChild"></child> |
5 | <div>子组件向我传递的消息 <b>{{ msgFromChild }}</b></div> |
6 | </div> |
7 | </template> |
8 | |
9 | <script> |
10 | // @ is an alias to /src |
11 | import child from '@/components/child.vue' |
12 | |
13 | export default { |
14 | data(){ |
15 | return { |
16 | title: '我是来自父组件的title', |
17 | msgFromChild: '' |
18 | } |
19 | }, |
20 | methods: { |
21 | getMsgFromChild(msg){ |
22 | this.msgFromChild = msg |
23 | } |
24 | }, |
25 | components: { |
26 | child |
27 | } |
28 | } |
29 | </script> |
子组件代码
1 | <template> |
2 | <div class="child"> |
3 | <h4>我是子组件</h4> |
4 | <div>这是来自父组件的title: <b>{{ title }}</b></div> |
5 | <button @click="sendMsgToParent">点我向父组件传递信息</button> |
6 | </div> |
7 | </template> |
8 | <script> |
9 | export default { |
10 | props: ['title'], |
11 | methods: { |
12 | sendMsgToParent(){ |
13 | this.$emit('getMsg','我是来自子组件的信息') |
14 | } |
15 | } |
16 | } |
17 | </script> |
二、 事件总线 $on/$emit
通过事件总线的话我们需要在Vue原型上添加一个Vue实例作为事件总线,
实现组件间相互通信,从而不受组件关系影响
1 | // 在main.js中 |
2 | Vue.prototype.$bus = new Vue() |
3 | |
4 | // 子组件中通过 $bus.$emit发送事件 |
5 | this.$bus.$emit('getMsgByBus','我是通过事件总线传递的信息') |
6 | |
7 | // 父组件通过 $bus.$on 来监听事件 |
8 | this.$bus.$on('getMsgByBus',(msg)=>{ |
9 | this.msgFromChild = msg |
10 | }) |
在原型上添加一个vue实例其实就是需要用到实例的$emit和$on 方法
我们也可以自己写一个事件总线
1 | class Bus { |
2 | constructor(){ |
3 | this.callbacks = {} |
4 | } |
5 | $on(name, fn){ |
6 | this.callbacks[name] = this.callbacks[name] || [] |
7 | this.callbacks[name].push(fn) |
8 | } |
9 | $emit(name, args){ |
10 | if(this.callbacks[name]){ |
11 | this.callbacks[name].forEach(cb => cb(args)) |
12 | } |
13 | } |
14 | } |
那么现在就可以在原型上添加Bus的实例达到同样的效果
1 | Vue.prototype.$bus = new Bus() |