eventBus VSvueX

EventBus & Vuex?

组件通信

在很久很久以前,在Vue王国里有一个组件塔,有一个组件家族,A,B,C,组件父亲A和儿子B,C生活在不同的层级之间,他们相隔非常远。

父->子

这个时候,父亲想念儿子了,想给他寄信,怎么办呢?简单!在每一个子组件上都有一个props “邮箱”,通过这个邮箱,父亲可以直接投递邮件(data)

    Vue.component('blog-post', {
      // 在 JavaScript 中是 camelCase 的
      props: ['postTitle'],
      template: '<h3>{{ postTitle }}</h3>'
    })
    <!-- 在 HTML 中是 kebab-case 的 -->
    <blog-post post-title="我是父亲的消息!"></blog-post>
复制代码

子->父

收到父亲来信后,B,C都非常高兴。想给父亲回话,这时白鸽使者vue. e m i t 出 来 了 , 子 组 件 用 v u e . emit出来了,子组件用vue. emitvue.emit传递消息,往上层传播。

this.$emit("todo",{
    res:"我是儿子的消息"
})
复制代码

接到消息后,父亲得对儿子传递过来的不同类型信息做出不同的回应

    this.$on('todo',function(data){
        // todo
        //data => 来自儿子的消息
    })
复制代码

兄弟

A经常教育B和C,说兄弟之间要多联系,增加感情,但是$emit又只能向上层传递消息,住在同一层的兄弟两又该怎么联系呢?

eventbu事件总线

这时候有一个智者想到了一个方法,既然你们都用 e m i t 这 个 方 法 , 我 何 不 直 接 开 个 顺 丰 快 递 呢 ? 这 时 候 v u e e v e n t b u s 事 件 总 线 出 来 了 , 利 用 一 个 游 离 在 组 件 塔 外 的 v u e 实 例 , 构 造 了 一 个 b u s 总 线 , 儿 子 的 消 息 通 过 emit这个方法,我何不直接开个顺丰快递呢? 这时候vue eventbus事件总线出来了,利用一个游离在组件塔外的vue实例,构造了一个bus总线,儿子的消息通过 emitvueeventbus线vuebus线emit给bus总线.

B.$root.bus.$emit('todo')
复制代码

这时候父亲所得到的消息是由bus总线发出的,并设置响应事件

A.$root.bus.on('todo',function(){})
复制代码

这样父亲儿子就可以轻轻松松的联系了
那最关键的问题是,兄弟之间怎么联系呢?
总线的智者这时候跳出来说,顾客就是上帝,不管是父亲儿子都可以使用我们顺丰快递总线,这样也就实现了兄弟组件之间的通信

B.$root.bus.$emit('todo')
// 兄弟C也能收到这个消息
C.$root.bus.on('todo',function(){})
复制代码

problem?

这个时候回到本文关键,为什么eventBus这么好的东西我们还要使用vuex呢?
以下内容参照 vuex-basics-tutorial
最开始,我们的项目可能是简简单单这样的

img

在过了很长一段时间之后,王国不断发展,项目越来越大,组件塔里的组件越来越多,他们长得也越来越复杂,整个王国变得乱七八糟,项目结构变成下面这个样子。不同组件之间通信越来越多,代码段里不断的出现 e m i t 和 emit和 emiton导致了以下几个主要问题

1. 代码逻辑性极具下降,可阅读性变低
2. 对于每一个action父组件都需要一个on(或dispatch)一个事件来处理
3. 你将很难查找到每一个事件是从哪里触发,满篇都是业务逻辑
复制代码

img

简单的例子

举个简单的例子。你的公司原来有一个display组件,他的作用是展现App根组件上increment的当前值。你新招了两个新员工,给他们分配了两个任务。

  1. 你让小A开发一个新的计数器在一个新的组件(childDisplay)里运用,实现点击一次增加increment一次,并在组件内展现increment当前的数字。这个计数器订阅了increment,点击计数器成功让display和childDisplay显示increment增加1后的数字。
    小A开开心心迅速的完成了这个任务commit然后push了
  2. 你跟小B说,我需要一个按钮组件,这个按钮组件向app实例emit了一个reset事件,这个事件将重置App上increment为0
    好的,小B也开开心心的commit然后push了
  3. 这个时候你会发现当你点击A组件时,在display和childDiplay上都成功显示了increment增加1以后的数字,但点击B组件触发reset事件时,根组件上的increment重置为了0,但由于小B并不知道A组件也订阅了increment这个数据,导致A组件状态没有更新。

vuex

为了防止这些问题,这个时候,国王尤小右站了出来,他借助隔壁flux王国的思想,带领全国的智者研究出了一个新的方式来解决这种混乱的问题。那就是vuex了。

按照定义来说

  1. store是一个仓库,仓库保存着项目的数据(store.state)
  2. (严格模式)为了解决无法追踪状态变化的问题,仓库里的数据不直接通过修改store.state来改变,而是通过commit一个动作告诉仓库,将会报错 [vuex] Do not mutate vuex store state outside mutation handlers
  3. 仓库收到了commit的动作后,将会在store.mutation里查找对应事件,并改变store.state
why better ?
  1. 如果在开发过程中保留了所有状态的副本,我们可以像super hero一样如时空穿梭般对代码进行调试,记录每一次状态的变化
  2. 你可以构建一个中间件,比如一个日志打印器,在每次用户提交一个action时记录操作,当出现问题时你将会更加容易的调试与fix bug
  3. 强制要求你把所有action通过一个store管理,这样团队开发将会更加便捷与明了

总结

通过长篇的分析我们可以得出本文结论了。

  1. vuex是官方推出的,事件总线是高手在民间
  2. 在大型应用方面,vuex确实是一个比EventBus更好的解决方案
  3. vuex更加易于调试与管理
  4. Vuex并不是最佳的解决方案,在某些小型应用上,你可能只有小部分的数据交互,甚至只有一个登录状态储存,那样事件总线或者简单状态管理都是值得推荐的。

的解决方案,在某些小型应用上,你可能只有小部分的数据交互,甚至只有一个登录状态储存,那样事件总线或者简单状态管理都是值得推荐的。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值