咱们晓得通过全局事件总线的办法同样也可能实现任意组件间的通信,并且是依靠于Vue的个性联合一些技巧实现的,并不需要第三方的反对,那么和全局事件总线相比Vuex和全局事件总线$bus的区别在哪里呢?咱们上面来探讨一下:

总线和Vuex的共同点

组件能找到它们的原理一模一样

Vuex状态治理是利用Store仓库进行治理,而事件总线是通过$bus绑定($on)和触发($emit)事件实现的。他们都应用了Vue 数据代理的这个重要的一个内置关系:VueComponent.prototype.__proto__ === Vue.prototype

咱们来看看应用总线应用状态治理的时候调用的的API就晓得了

 /*--------事件总线-----------*/// 事件总线绑定事件this.$bus.$on('handleAdd',handleAdd)// 事件总线触发事件this.$bus.$emit('handleAdd',this.count) /*--------状态治理-----------*/// 获取状态this.$store.state.count// 批改状态this.$store.dispatch('increment',this.count)this.$store.commit('INCREMENT',this.count)

咱们能够看到调用他们的形式都是再组件中应用this获取到他们,这里的this就是指向以后的实例化组件(VueComponent),于是咱们就能够通过VueComponent.prototype.__proto__ === Vue.prototype这个内置关系晓得数据最终是透过原型链找到的$bus/store,所以不论是Vuex还是总线,想要让全局可能获取到$bus/store他们的原理是一样的,那就是将他们创立在Vue的原型对象上

const vm = new Vue({  render: h => h(App),   // 创立总线  beforeCreate() {    Vue.prototype.$bus = this  },   // 创立状态治理仓库  store,}).$mount('#app')

咱们能够看看Vue.use(Vuex)他到底帮咱们做了什么

// Vuex提供了install属性,通过Vue.use(Vuex)来注册。const install = function (Vue) {  Vue.mixin({    beforeCreate() {      if (this.$options.store) {        Vue.prototype.$store = this.$options.store      }    }  })}

原理一模一样!!

总线和Vuex的优缺点

是否应用第三方插件

事件总线不是三方库原来就有,而状态治理是一个弱小且配套的第三方库。

事件总线不是三方库原来就有

章节结尾时说过,全局事件总线是依靠于Vue的个性联合一些技巧实现的,并不需要第三方的反对。他是依附在Vue实例对象上的办法实现事件的绑定($on)、触发($emit)、解绑($off)

咱们对总线的比喻经常就是公交车(bus[他有总线的意思]),或者是来实现组件间任意通信的工具人。它能够是组件的实例化对象(VueComponent)也能够是Vue实例自身(VM)【罕用】,当$bus是Vue实例自身时就会在原型链上呈现一个闭环就是$bus = Vue实例化对象。总之,全局事件总线是依附Vue元编程的个性,通过经验总结造成的产物,没有应用到第三方插件(音讯订阅和公布、状态治理都是三方库)。

状态治理是三方库

说到三方库,咱们都说这个库可能活下来被大家fork的个别就是niubility的我的项目,他们个别都有着优雅、弱小等等这些标签。状态治理就是这其中的一个。

状态治理作为三方库是合乎Vue对渐进式框架这个定位的产物。咱们用不必状态治理次要是看有没有必要杀猪用牛刀了。咱们看看源码就晓得为什么是牛刀了。

/** * Extends interfaces in Vue.js */import Vue, { ComponentOptions } from "vue";import { Store } from "./index";declare module "vue/types/options" {  interface ComponentOptions<V extends Vue> {    store?: Store<any>;  }}declare module "vue/types/vue" {  interface Vue {    $store: Store<any>;  }}

咱们不须要读懂源码,只须要明确他是将vue引入了,在实现上咱们能够看到

Store仓库中Vue的实例化对象都呈现了,所以咱们心里面就明确了。Vuex其实是间接缔造了一个vm当作工具人(总线),并且将它封装的更加的优雅,作用更加的弱小。Vuex是间接创立vue实例,而总线最多也只不过是在咱们创立的vue实例上小打小闹,所以咱们有时候在小我的项目中用上vuex就会有种杀猪用牛刀的调侃。

是否优雅

在通过后面的比照,想必读者都晓得他们在实现上其实差不多,状态治理可能只是在总线的根底上做了优化罢了。没错这就是Vuex的外围竞争力——优雅。

纯熟应用$bus事件总线的读者就会发现$bus其实还是有一些小小的问题不太优雅的

  • 应用$on 绑定的事件名是不能反复的
  • $on 绑定数据之后,须要在组件销毁之前应用$off进行事件解绑

    而Vuex是响应式的,和数据双向绑定的原理一样,应用了gettersetter进行数据劫持,应用配置对象的模式来控制数据,所以当触发的事件名雷同时,雷同的名字对应的办法都会触发,也不须要对事件进行解绑,十分的优雅。

这些就是我总结的区别,如果有谬误之处欢送大家在评论区斧正。

补充:__proto__和prototype的区别和关系

对象具备属性__proto__,可称为隐式原型,一个对象的隐式原型指向结构该对象的构造函数的原型,这也保障了实例可能拜访在构造函数原型中定义的属性和办法。