前言

本文主要参照学习视频实现一个简单版本的vuex

代码地址

https://codesandbox.io/s/vue-code-study-mpewl

实现内容

  • store
  • state
  • mutations
  • actions
  • getters
  • 响应式

代码实现

  1. let Vue;
  2. class Store {
  3. constructor(options) {
  4. // 同样对vue强依赖 使用vue实现响应数据的更新
  5. this.state = new Vue({
  6. data: options.state
  7. });
  8. this.mutations = options.mutations;
  9. this.actions = options.actions;
  10. options.getters && this.handleGetters(options.getters);
  11. }
  12. //为什么没有定义到构造器内部?因为每个实例可以公用这些方法
  13. // 为mutations actions getters为每个实例化单独享有的
  14. // 声明为箭头函数,why?为了直接可以使用this.mutations,this.state
  15. commit = (type, arg) => {
  16. this.mutations[type](this.state, arg);
  17. };
  18. dispatch(type, arg) {
  19. this.actions[type](
  20. {
  21. commit: this.commit,
  22. state: this.state
  23. },
  24. arg
  25. );
  26. }
  27. // getters为参数 而this.getters是实例化的
  28. handleGetters(getters) {
  29. this.getters = {};
  30. // 遍历getters所有key
  31. Object.keys(getters).forEach(key => {
  32. // 为this.getters定义若干属性,这些属性是只读的
  33. // $store.getters.score
  34. Object.defineProperty(this.getters, key, {
  35. get: () => {
  36. return getters[key](this.state);
  37. }
  38. });
  39. });
  40. }
  41. }
  42. function install(_Vue) {
  43. Vue = _Vue;
  44. Vue.mixin({
  45. beforeCreate() {
  46. if (this.$options.store) {
  47. Vue.prototype.$store = this.$options.store;
  48. }
  49. }
  50. });
  51. }
  52. export default { Store, install };

要点分析

vue使用外来依赖

因为插件本身就使用了传入的vue,因此尽量不要内部定义vue,直接从从参数获取。

mixin

是否需要混入,混入本身很好用,但使用混入的最大前提是需要拿到组件的实例,如果你不希望或者不用拿到,那么直接定义到Vue的原型上即可。

getter为什么是只读的

通过Object.defineProperty实现定义一个get函数,让其变成只读的

箭头函数

当你需要使用外部环境,并且在组件实例的使用中不受影响的话,你就因该考虑箭头函数。