15-事件总线
码路教育 6/3/2022
# 1, 事件总线
# 1.1, 事件总线
在开发中,我们构建了组件树之后,除了父子组件之间的通信之外,还会有非父子组件之间的通信
- 全局事件总线
- Provide/Inject
// ErZi1.vue
<template>
<div class="erzi1">
<h1>我是儿子1组件</h1>
<button @click="$bus.$emit('maotai','一车茅台')">给老二一车茅台</button>
</div>
</template>
<script>
export default {
name: "ErZi1",
props:[],
data() {
return {
};
},
methods: {},
};
</script>
<style lang="less" scoped>
.erzi1{
width: 400px;
height: 200px;
background-color: gold;
margin: 50px 0px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// ErZi2.vue
<template>
<div class="erzi2">
<h1>我是儿子2组件</h1>
<SunZi></SunZi>
</div>
</template>
<script>
import SunZi from "./SunZi.vue"
export default {
name: "ErZi2",
props: [],
data() {
return {};
},
mounted(){
this.$bus.$on("maotai",val=>{
console.log("val:",val);
})
},
methods: {},
components:{
SunZi
}
};
</script>
<style lang="less" scoped>
.erzi2 {
width: 400px;
height: 200px;
background-color: pink;
margin: 50px 0px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// SunZi.vue
<template>
<div class="sunzi">
<span>我是孙子组件</span>
<button @click="clickHandler">点击给爷爷100万</button>
</div>
</template>
<script>
export default {
name: "SunZi",
props:[],
data() {
return {
money:"100万"
};
},
methods: {
clickHandler(){
// 发布
this.$bus.$emit("money",this.money)
}
},
};
</script>
<style lang="less" scoped>
.sunzi{
width: 300px;
height: 100px;
background-color: skyblue;
margin: 20px 0px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// App.vue
<template>
<div id="app">
<h1>我是App组件----{{money}}</h1>
<ErZi1></ErZi1>
<ErZi2></ErZi2>
</div>
</template>
<script>
import ErZi1 from "./components/ErZi1.vue"
import ErZi2 from "./components/ErZi2.vue"
export default {
name: 'App',
data(){
return{
money:0
}
},
mounted(){
// 在mounted中进行订阅
// 绑定一个自定义事件
this.$bus.$on("money",(val)=>{
console.log("爷爷接收money:",val);
this.money = val
})
},
components: {
ErZi1,
ErZi2
}
}
</script>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// let $bus = new Vue(); // $buts就相当于是vm实例 通过$bus可以得到$on $emit
// Vue.prototype.$bus = new Vue();
new Vue({
beforeCreate(){
// this表示vm
// 配置全局事件总线,说白了,就是在Vue原型对象上添加$bus属性,值是vm
// this是vm,不是vc
// 在$bus身上有,$on和$emit $on可以用来接收数据 $emit可以用来发送数据
Vue.prototype.$bus = this;
},
render: h => h(App),
}).$mount('#app')
// 目前为止,vue中数据通信的方案?
// 1)props 自定义属性 一般是父传子 如果传递的是方法,也可以实现子传父
// 2)emit 自定义事件 子传子 子可以把数据传递给父
// 3)事件总线 $bus 值是一个vm $on订阅 $emit发布
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25