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
// 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
// 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
// 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
// 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
Last Updated: 12/25/2022, 10:02:14 PM