关于vue.js:Vuex和全局事件总线的区别

2次阅读

共计 2451 个字符,预计需要花费 7 分钟才能阅读完成。

咱们晓得通过全局事件总线的办法同样也可能实现任意组件间的通信,并且是依靠于 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__,可称为隐式原型,一个对象的隐式原型指向结构该对象的构造函数的原型,这也保障了实例可能拜访在构造函数原型中定义的属性和办法。

正文完
 0