美文网首页Devlopment
巧用Vue Mixins实现跨级组件通信(Event Bus)

巧用Vue Mixins实现跨级组件通信(Event Bus)

作者: ryderdu | 来源:发表于2019-04-16 18:46 被阅读0次

众所周知,在我们现代开发中必不可少要用到Vue或者React, 那么我们一般父子通信一般会用Props, 虽然官方也会说两个同级兄弟组件你可以传到同级父组件然后分发,但是这样的效率实在令人捉急,层级一多你就蛋疼了(react官方出的context也是为了解决此类问题),既然都是单页应用,我们搞个事件监听和传递不就行了

在以前就有

element.addEventListener('click;', function(){})

首先我们需要借助发布订阅实现几个关键api,on / off / emit
他的原理也相当容易理解,我们维护一个事件队列,如果我们用一个key去增加/触发事件函数获得所需要的值,这样就完成了我们跨组件数据传递的需求

Event.js

class EventEmitter {
    constructor() {
        this.handersArr = {}
    }
    on(eventType, handle) {
        this.handersArr[eventType] = this.handersArr[eventType] || []
        this.handersArr[eventType].push(handle)
    }

    emit(eventType, ...args) {
        if (Array.isArray(this.handersArr[eventType])) {
            this.handersArr[eventType].forEach((item) => {
                item(...args)
            })
        }
    }

    off(eventType) {
        this.handersArr[eventType] && delete this.handersArr[eventType]
    }
}

export default EventEmitter

当然这样我们就完成了超级简单的事件管理器, 但是这里我们想把它用在vue上会需要做这么几个事情,在created接收其他组件的事件(如果有),同比react就是componentDidMount 然后在destoryed阶段(同比react就是componentWillUnmount)把这个事件摧毁,嗯,如果每次这么做就有点不够先进,而且和其他业务代码揉合在一起,不科学

那我们可以在Event.js搞点事情,

    bindVue(handlers) {
        const _this = this
        let handlersWithVue = {}
        return {
            created() {
               for (const [event, _handler] of Object.entries(handlers)) {
                   const handler = _handler.bind(this) // 把_handler的this绑定到vue调用环境中去
                   _this.on(event, handler)
                   handlersWithVue[event] =  handler
               } 
            },

            beforeDestroy() {
                _this.off(handlersWithVue)
            }
        }
    }

这里涉及到一个奇技淫巧,vue的mixins特征,简单暴力来说,它可以把你需要定制的vue的js部分的逻辑全部塞进你的业务.js里面,并起到作用,咦...这上面说的不就成了。

import EventBus from '../util/bus.js'
export default {
    mixins: [EventBus.bindVue({
         changeText(value) {  // 这里就是on方法啦
              this.msg = value
         }
    })],


   [emit:]  EventBus.emit({changeText: 666})

当然你会问React怎么实现,因为react真的是class,所以你拿到component真的就是标准对象,所以react的处理更方便点,直接把我们那个bindVue换成这个就成,react建议在constructor里面on监听(其实我们项目还有个hooks的实现23333),把我们需要的事件在componentDidMount执行,componentWillUnmount销毁

    bindComponent(component, handlers) {
        const didMount = component.componentDidMount
        const willUnmount = component.componentWillUnmount

        component.componentDidMount = () => {
            this.on(handlers)
            if (didMount) {
                return didMount.apply(component)
            }
        }

        component.componentWillUnmount = () => {
            this.off(handlers)
            if (willUnmount) {
                return willUnmount.apply(component)
            }
        }
    }

其实这里正好运用了JavaScript事件驱动和单线程的特点,比较复杂的是,你要注意this的指向,这里确实还是挺乱的,一不小心就不知道操作的是谁的this了。

相关文章

  • 巧用Vue Mixins实现跨级组件通信(Event Bus)

    众所周知,在我们现代开发中必不可少要用到Vue或者React, 那么我们一般父子通信一般会用Props, 虽然官方...

  • vue文档集合

    Vue2使用笔记3--父子组件的通信Vue 2.0开发实践(组件间通讯)Event Bus 在Vue中的使用vue...

  • vue 新增属性 $attrs及$listeners (组件通信

    介绍:vue组件之间的通信方式有很多种,props/emit , event bus, vuex, provide...

  • Vue - 组件通信之 event bus

    前言 vue通信手段有很多种,props/emit、vuex[https://www.jianshu.com/p/...

  • Vue组件通信

    Vue组件通信 Vue组件关系可分为三大类: 父子组件 兄弟组件 跨级组件, 相应的组件之间的通信也分类三大类: ...

  • Vue组件通信

    总体来说,Vue中组件之间的通信场景如下图: 可以将其分为父子组件通信、兄弟组件通信、跨级组件通信。 1. 自定义...

  • react 跨级组件通信

    跨级组件通信所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方...

  • vue非父子组件通信

    非父子组件之间的通信一般通过一个空的 Vue 实例作为 中转站,也可以称之为 事件中心、event bus。

  • 组件通讯 event bus事件总线 ,Context和prop

    一、event bus 事件总线 进行非父子组件间的通信(兄弟组件) 二、Context的应用场景:在于很多不同层...

  • 组件通信

    组件关系 组件关系可以分为父子组件通信、兄弟组件通信、跨级组件通信。 父子组件通信 1. 子组件使用 $emit(...

网友评论

    本文标题:巧用Vue Mixins实现跨级组件通信(Event Bus)

    本文链接:https://www.haomeiwen.com/subject/fadiwqtx.html