Vue公共广播/父子组件广播 $emit、$on的实现及原理解答

版权声明:【原创】GitHub:https://github.com/susuGirl,微信公众号:fuxiaodexing,博客:https://blog.csdn.net/weixin_41845146 https://blog.csdn.net/weixin_41845146/article/details/84784155

vm.$emit( event, […args] )

  • 参数:

    • {string} event

    • [...args]

    • 触发当前实例上的事件。附加参数都会传给监听器回调

m.$on( event, callback )

  • 参数:

    • {string | Array<string>} event (数组只在 2.2.0+ 中支持)
    • {Function} callback
  • 用法:

    监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。

  • 示例:

vm.$on('test', function (msg) {
console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"
  • 应用一
// index.vue
<template>
    <div>
        <my-dialog @change-data="receiveDate"></my-dialog>
    </div>
</template>
<script>
    import myDialog from './myDialog'
    export default {
        components: {
            myDialog
        },
        methods: {
            receiveDate (val) {
                            console.log(val) // params
                       }
        }
    }
</script>
// myDialog.vue
<template>
    <div>
        <div @click="handleClick"></div>
    </div>

</template>

<script>
    export default {
        methods: {
                    handleClick (){
                        let params = ""
                        this.$emit("change-data", params)
                }

            }
    }
</script>
  • 应用二

    扫描二维码关注公众号,回复: 4503436 查看本文章
    • eventHub 文件里导出了一个 new vue 实例 ①
    • 与 main.js 里 new  vue 实例 ② 是平级的
    • 两个 vue 实例上都有 $emit $on 方法,但是这个栗子里的广播 $emit $on 都只在 vue 实例 ① 上

    • vue 实例 ① 一直在监听

    • 当 vue 实例 ②  中在满足某个条件需要触发广播时,然后用 vue 实例 ① 上的 $emit (eventHub.$emit)发送广播,当 vue 实例 ①  上监听到时,就用 eventHub.$on 接收这个同名的广播,然后执行回调函数,至于回调函数里有什么亦或做了是吗就与它无关了,因为 vue 实例 ① 只负责监听和接收广播。

    • 而且 vue 实例 ① 一直存在不会消失。但是 vue 实例 ② 上由于是单页面应用,所以各种组件会经常被销毁或者重建,如果组件被销毁了,它里面的广播也就被销毁了,所以会导致找不到相对应广播。

// utils/eventHub.js

import Vue from 'vue'

export default new Vue()  // 什么都没有绑定,因为它只是一个跳板,并且在实时监听
// index.vue
<template>
    <div>
        <my-dialog></my-dialog>
    </div>
</template>
<script>
    import myDialog from './myDialog'
    import eventHub from 'utils/eventHub'

    export default {
        components: {
            myDialog
        },
        mounted() {
            eventHub.$on("change-data", (val) => {
                console.log(val) // params
            })
        },
        beforeDestroy () { // 在实例销毁之前,移除监听器
            eventHub.$off("change-data")
        }
     }
</script>

// myDialog.vue
<template>
    <div>
        <div @click="handleClick"></div>
    </div>

</template>
<script>
    import eventHub from 'utils/eventHub'
    export default {
        methods: {
                    handleClick (){
                        let params = ""
                        eventHub.$emit("change-data", params)
                }
            }
    }
</script>
// main.js

new Vue({
    el: '#app',
    router,
    store,
    template: '<app/>',
    components: { app }
})

猜你喜欢

转载自blog.csdn.net/weixin_41845146/article/details/84784155