为什么我们需要 Vuex

作者: 小虫巨蟹 | 来源:发表于2017-05-25 00:50 被阅读296次

    一、一个错误引发的思考

    在 Weex 子组件中通过 this.$parent.$emit('event') 触发父组件的事件,父组件通过 this.$on('event', handler) 接收事件,从而实现父子组件的通信。这在 Native 端表现正常,然而当使用 Vue-loader 编译代码,引入 vue-runtimeweex-vue-render 在浏览器端运行的时候,事件无法正常捕获,这是什么原因呢?

    假设把前文所说的父组件命名为 father, 子组件命名为 child,起初, Weex 中:

        child.$parent === father // true
    

    我们为了通知 father 去做某件事情,可以在 child 中使用 this.$parent.$emit,可是当解析到浏览器执行的时候,Debugger 发现:

        child.$parent === father // false
        child.$parent.$parent === father // false
    

    也就是在 father 和 child 之间,多了一层组件的封装,之前的父子关系发生了改变,事件自然无法正常传达

    这是因为,在 Weex 中有很多内建组件,底层基于 Native 端实现,当通过 vue-runtime 在浏览器运行的时候,需要将这些内建组件用基于浏览器的 Vue 组件代替,而这些 Vue 组件要实现类似底层 Native 组件的效果,极有可能需要封装多层,也就是会出现上述的父子关系变更的情况

    可以认为是 Weex 做得不好的地方,但是我觉着,就算没有这个错误,也应该避免使用
    this.$parent

    二、this.$parent 背离了组件解耦的原则

    上述的组件通信方式,是从哪来的奇淫巧技,我都已忘记,目前在 Vue 官网上找不到这种使用方法,也就是连官方都不推荐了更印证了不应该使用 this.$parent 的说法。

    其实原因也很简单,子组件引用父组件的实例,这种强关联背离了组件的解耦原则,子组件依赖于某一特定的父组件,那么这个子组件只适用在这个父组件下,把这个子组件放到别处,就无法正常运行(或者有功能的缺失),并且一旦出现章节一中父子关系变更的情况,结果更加难以预料

    那么子父组件确实是需要通信的时候,不使用 this.$parent 有什么替代方案么?答案是有的,Vue 中有个 bus 总线,子组件通过 bus.$emit把事件发到总线中,任何组件都可以监听这个事件。也就是子组件只负责触发事件,并不需要关心具体的处理组件。总线接收到事件信号后,发送到监听了该事件的组件处理

    对于父到子的通信,父组件通过 props 向子组件传入参数,对于这个方向的数据流,我们却不用太担心的解耦的问题,因为父组件作为调用方只需要传递子组件需要的参数即可,子组件只需要关心参数,并不需要关心是谁在调用,同样可以顺利移植,完成解耦

    从这个层面来说,从某种意义上说,单向数据流促进了组件间的解耦

    三、这同样可以解释为什么我们需要 Vuex

    以这个角度来观察 Vuex 以及所有单向数据流状态控制框架,是不是某种意义上的事件总线呢?

    bus.png store.png

    其实 Vuex 不过是 Bus 更高级细致的实现而已,连官方文档也说了,有必要好好思考下你是否真的需要 Vuex,如果你的应用本身不复杂,其实只需要一个简单的 Bus 就够了

    菲麦前端专题,汇聚前端好文,邀您关注!

    相关文章

      网友评论

      • goCan6:虽然说有点引战的意味,父子通讯虽然是背离了组件解耦,但是引进了vuex,就意味着解耦?难道拆开了store,组件能独立运行?不可吧?所谓解耦也只是从父子的耦合,转变为组件和store的耦合。依我看法,中央集中管理数据是铁定耦合的,我觉得vuex是没必要的,你只是需要一个全局变量,去做这种事情
        小虫巨蟹:@猫五号 首先很欢迎探讨,我是这么看的
        1. 解耦也有个范围,在应用内部,集中管理数据的话,达到了内部解耦,当然你剥离了 store 是不能允许的(通过传入属性的组件除外),否则继续往下抬杠的话,脱离了 vue-runtime 你的 vue 代码能跑?
        2. 其次,不是说父子通讯背离了解耦,而是子对父的定向控制背离了解耦,注意方向,是子对父
        3. 全局变量,数据总线,vuex 其实是同一个原理,按照你的说法,使用 全局变量 去替代 vuex ,难道就可以剥离全局变量跑?这个不能够吧
        vuex 是 数据总线的一种高级形式,数据总线呢,又是全局变量的一种设计方法,文章也说了,如果你的应用足够简单,你可以好好思考下是否需要 vuex。
        换句话说,使用 vuex 来复杂应用的数据状态,要比你用零散的全局变量来管理要清晰,仅此而已,简单的时候,则大可不必
      • 薛墨林:你是猛人
      • aa02ef4b29dd:啦啦啦

      本文标题:为什么我们需要 Vuex

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