• Vue2&3全局事件总线


    Vue2&3全局事件总线

    Vue2全局事件总线

    在这里插入图片描述

    • 功能:可以解决所有组件之间通信传数据的问题
    • 原理:通过一个共享对象,将所有组件全部绑定到对象上,即可通过这个对象实现组件与组件之间的传递数据,而这个共享对象叫做全局事件总线。

    如何分清楚谁是发送方,谁是接收方?谁用绑定事件,谁用触发事件?

    • 假设:我向你传送数据,我是发送方,你是接收方。
      • 若我不向你发送数据,则你就不知道数据的内容,无法拿取(绑定)。(我不触发,你不能绑定,因为你没有数据)
      • 只有我发送数据给你,你才能知道数据的内容,才能对数据进行拿取。(谁发送谁触发,谁拿取谁绑定)

    共享对象创建位置:main.js文件

    • 第一种方法:创建vc对象
    // 获取 VueComponent 构造函数
    const VueComponentConstructor = Vue.extend({})
    // 创建 vc 对象
    const vc = new VueComponentConstructor()
    // 使所有组件共享 vc 对象
    Vue.prototype.$bus = vc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 第二种方法(常用):使用原有的vm对象
      • 在Vue初始化时(beforeCreate),创建共享对象vm
    new Vue({
      el : '#app',
      render: h => h(App),
      beforeCreate(){
        // this指向的是vm
        Vue.prototype.$bus = this
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    以上代码中出现的$bus有什么作用?

    • $bus:事件总线,用来管理总线。
    • 其他组件在调用vc共享对象时可通过this.$bus.$on()this.$bus.$emit()来绑定或触发事件

    数据发送方:触发事件$emit

    • 触发事件:this.$bus.$emit('事件名', 接受的数据)
    // Vip.vue
    <template>
        <div>
            <button @click="triggerEvent">触发事件</button>
        </div>
    </template>
    
    <script>
        export default {
            name : 'Vip',
            data(){
                return{
                    name : 'zhangsan'
                }
            },
            methods : {
                triggerEvent(){
                    this.$bus.$emit('event', this.name)
                }
            }
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    数据接收方:绑定事件$on

    • 绑定事件:this.$bus.$on('事件名', 回调函数)
    // App.vue
    <template>
        <div>
            <Vip></Vip>
        </div>
    </template>
    
    <script>
        import Vip from './components/Vip.vue'
        export default {
            name : 'App',
            mounted() {
                this.$bus.$on('event', this.test)
            },
            methods : {
                test(name){
                    console.log(name);
                }
            },
            components : {Vip}
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Vue3全局事件总线

    安装mitt

    • 在CMD窗口中,跳转到Vue3安装路径下
    • 输入命令npm i mitt,当出现up to date in 595ms等类似信息表示安装成功

    使用mitt(只要使用全局事件总线,所在的组件就要引入emitter)

    • 第一步:创建一个文件夹utils,在文件夹中创建js文件(event-bus.js)
    • 第二步:在js文件中导入并暴露mitt(如下)
      • 这里的操作主要是为了生成对象emitter
    // utils/event-bus.js
    import mitt from 'mitt'
    
    // mitt函数的执行会生成一个对象:emitter对象
    // emitter对象是一个全局事件总线对象
    // 绑定和触发的操作都在这个对象上的完成
    export default mitt()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实现绑定与触发事件

    • 绑定事件:emitter.on('事件名', 回调函数)
    • 触发事件:emitter.emit('事件名', 接收的数据)
    // App.vue
    <template>
        <Info></Info>
    </template>
    
    <script>
        // 引入全局事件总线对象
        import emitter from './utils/event-bus.js'
        import Info from './components/Info.vue'
        // 引入组合式API:生命周期钩子
        import { onMounted } from 'vue'
        export default {
            name : 'App',
            components : {Info},
            setup(){
                // 生命周期钩子:onMounted
                onMounted(() => {
                    // 绑定事件
                    emitter.on('event1', showInfo)
                })
                
                function showInfo(info){
                    alert(`姓名:${info.name}`)
                }
    
                return {showInfo}
            }
        }
    </script>
    
    • 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
    // Info.vue
    <template>
        <button @click="triggerEvent1">触发event1事件</button>
    </template>
    
    <script>
        // 导入全局事件总线对象
        import emitter from '../utils/event-bus.js'
        export default {
            name : 'Info',
            setup(){
                function triggerEvent1(){
                    // 触发事件
                    emitter.emit('event1', {name:'jack'})
                }
                
                return {triggerEvent1}
            }
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    解绑事件

    • 原理:在子组件中使用 off 可以消除指定的事件
    • 解绑事件:emitter.off('事件名')
    // Info.vue
    <template>
        <button @click="triggerEvent1">触发event1事件</button>
        <br>
        <button @click="clearEvent1">解绑event1事件</button>
    </template>
    
    <script>
        // 引入入全局事件总线对象
        import emitter from '../utils/event-bus.js'
        export default {
            name : 'Info',
            setup(){
                function triggerEvent1(){
                    // 触发全局事件总线上的事件
                    emitter.emit('event1', {name:'jack'})
                }
    
                function clearEvent1(){
                    // 解绑指定的事件
                    emitter.off('event1')
                }
                
                return {triggerEvent1, clearEvent1}
            }
        }
    </script>
    
    • 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

    Vue2和Vue3在触发和绑定上的不同

    • 第一点:引用的方式不同
    // Vue2 的 main.js
    new Vue({
      el : '#app',
      render: h => h(App),
      beforeCreate(){
        Vue.prototype.$bus = this
      }
    })
    
    // Vue3 的 utils/event-bus.js
    import mitt from 'mitt'
    export default mitt()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 第二点:调用方式的不同
    // Vue2
    绑定:this.$bus.$on('事件名', 回调函数)
    触发:this.$bus.$emit('事件名', 接受的数据)
    解绑:this.$bus.$off('事件名')
    
    // Vue3 需要先引入 import emitter from '../utils/event-bus.js'
    绑定:emitter.on('事件名', 回调函数)
    触发:emitter.emit('事件名', 接收的数据)
    解绑:emitter.off('事件名')
    JavaScript
    // Vue2
    绑定:this.$bus.$on('事件名', 回调函数)
    触发:this.$bus.$emit('事件名', 接受的数据)
    解绑:this.$bus.$off('事件名')
    
    // Vue3 需要先引入 import emitter from '../utils/event-bus.js'
    绑定:emitter.on('事件名', 回调函数)
    触发:emitter.emit('事件名', 接收的数据)
    解绑:emitter.off('事件名')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    黑猫带你学UFS协议栈第10篇:Unipro协议框架详解
    莫比乌斯召回系统介绍
    nagios
    webrtc安全性 加密方式
    Python基础之生成器
    2021-10《信息资源管理 02378》真卷(独家文字版),圈定章节考点+统计真题分布
    携职教育:这么备考中级经济师的,90%都考不过
    Element-plus 图标使用
    ElasticSerach+MongoDB:实现文章检索历史功能
    前端工程化以及WebPack的使用
  • 原文地址:https://blog.csdn.net/weixin_47957908/article/details/134453017