Vuex 的应用场景

本文在 GitHub上的连接vue

昨天被问了一个问题:git

Vuex 的应用场景有什么?何时适合使用 Vuex,何时不适合使用 Vuex?github

在当时,个人答案是通常人会回答的内容:vuex

  1. 涉及到非父子关系的组件,例如兄弟关系、祖孙关系,甚至更远的关系;
  2. 他们之间若是有数据交互,那么应该使用Vuex来实现;
  3. 若是页面复杂度比较低的话,也能够考虑使用 global-event-bus 来实现;
  4. 若是只是父子关系的组件数据交互,那么应该考虑使用props进行单向传递;
  5. 若是涉及到子组件向父组件的数据传递,那么应该考虑使用 $emit$on

讲道理说,这个答案也不算错,当时我也只能回想起这些。cookie

但后来,我又想了想,其实还能够更有针对性一些。session

例如,在如下场景里,咱们应当使用 Vuex:异步

一、组件会被销毁this

咱们能够假设这样一个场景:spa

  1. 假若有这样一个组件,他是弹窗,有一些复选框和输入框,用户会选择和填写信息;
  2. 而后这个弹窗会被关闭和打开,因为业务须要,这个弹窗输入的内容,但愿关闭后能够保留,在从新打开后,内容依然存在。

解决办法:code

  1. 咱们能够考虑将值存在父组件中,也就是说,实际修改的是父组件的值;
  2. 存在好比 sessionStoragecookies之类的里面,在 created 时从中读取,destroyed的时候写入其中;
  3. 能够存到 global-event-bus 里面;

但事实上,最好的仍是存在 Vuex 里:

  1. 能够直接经过 $store.state 来调用,经过 commit() 来修改值;
  2. 也能够在 created 的时候,读取存在 state 里面的值,在 destroyed 的时候,写回 state;

这样处理的优势是解耦,不跟其余组件打交道。

二、组件基于数据而建立

咱们能够假设这样一个场景:

  1. 用户登陆后,读取权限配置表,这显然是一个异步操做;
  2. 这个配置表可能会影响不少页面。好比被影响的组件的加载条件,例如是 v-if="$store.state.userInfo.superVIP

那么:

  1. 由于读取权限配置表这个异步操做,可能影响多个组件,而这些组件之间的关系,显然是不可预料的(即不必定是在同一个父组件下面);
  2. 那么这个异步操做,写在某一个组件里就不太合适(由于其余组件读取这个组件很不方便,即便他是根组件);

解决办法:

  1. 一个妥协的解决办法,是写在 global-event-bus 里面来实现;
  2. 可是显然,更好的解决办法是写在 vuex 里面更专业一些;

三、多对多事件——多处触发,影响多处

咱们能够假设这样一个场景:

  1. 假若有一个事件,好比:切换页面显示风格,他将改变某一个变量的值;
  2. 当该变量为 true 时,那么页面风格为白天(主要影响 v-bind:style 的值);
  3. 当该变量为 false 时,那么页面风格为晚上(同上);
  4. 在多个地方能够切换这个页面风格开关;
  5. 毫无疑问,这个变量将影响多个地方的 v-bind:style 的值;
  6. 这就是 多对多 场景;

那么:

  1. 不管这个变量放在哪一个组件里,其余组件调用他都是很麻烦的事情;
  2. 即便存于根组件,而后经过 this.$root.xx 来获取这个变量,也是很麻烦的,并且很丑陋;

解决办法:

  1. 若是不使用 Vuex,那么咱们可能会去考虑使用 global-event-bus 来存储这个变量,并使用它;
  2. 这不是不能够,但不优雅,并且管理麻烦;
  3. 而使用 Vuex,那么这就是一件很方便的事情了;
  4. 咱们能够经过 $store.state.xxx 来获取这个变量的值;
  5. 经过 $store.getters.yyy 来获取某些基于这个值的,表示通用样式(例如黑底白字)的对象;
  6. 经过 $store.commit() 来提交修改(好比在某些状况下能够禁止修改);
  7. 甚至能够经过 $store.dispatch() 来获取其余风格的样式,并经过 $store.state$store.getters 来返回新风格的样式;

四、总结

总而言之,假如你须要 数据组件 分离,分别处理,那么使用 Vuex 是很是合适的。

相反,若是不须要分离处理,那么不使用 Vuex 也不要紧。

好比某个数据只跟某组件打交道,是强耦合的。那么这个数据就应该存放在该组件的 data 属性中。

相关文章
相关标签/搜索