Vuex学習-Vuexの原理を理解する

18076 ワード

最近ではVuexを使用する際に、VuexとNGRXを比較してみましたが、全体的にFLUX思想の実現ですが、使用すると、個人的にはvuexの使用がNGRXよりも快適だと感じます.以下にいくつかのVuexの実現原理を紹介し、本文は最も簡単なクラスvuexを実現するだけで、vuexの動作方式を理解するのに役立つために、実際のvuexの実現はこれよりずっと複雑である.
Vuex実現の原理
コードを先に置いて、ブロックで説明します.
const Store = function Store (options = {}) {
  const {state = {}, mutations={}, getters={},actions={}} = options
  const computed = {}
  const store = this
  store.getters = {};
  for (let [key, fn] of Object.entries(getters)) {
    computed[key] = function () { return fn(store.state, store.getters); };
    Object.defineProperty(store.getters, key, {
      get: function () { return store._vm[key]; },
    });
  }
  this._vm = new Vue({
    data: {
      $$state: state
    },
    computed,
  })
  this._mutations = mutations
  this._actions = actions
}
Store.prototype.commit = function(type, payload){
  if(this._mutations[type]) {
    this._mutations[type](this.state, payload)
  }
}

Store.prototype.dispatch = function(type){
  if(this._actions[type]) {
    const store = this;
    this._actions[type]({commit:this.commit.bind(store)});
  }
}

Object.defineProperties(Store.prototype, { 
  state: { 
    get: function(){
      return this._vm._data.$$state
    } 
  }
});


Vuexデータの応答式
Vueフレームワークでは、データをData属性の下に定義すると、中の属性は応答的に傍受することができますが、実際にはProxyによって行われています.つまり、よく言われています.
Object.defineProperty(obj, prop, value);

そのため、VueでVuexを実現するには、この考えを完全に適用して、あなたのstateをVueインスタンスのdata属性に置くことができます.
this._vm = new Vue({
    data: {
      $$state: state
},

この中のstateは私たちがVuexを使って入ってきたstateです.このように私たちが使っている間に、その傍受と通知はVueフレームワークがVueコンポーネントをインスタンス化するときに手伝ってくれました.実はnew Vue()という関数でやったのです(興味のある後に1編分けて書くことができます).
もう一つ質問ですが、私たちが直接取得したstate属性であり、「_vm.$$state」などは呼び出されていません.これは簡単です.
Object.defineProperties(Store.prototype, { 
  state: { 
    get: function(){
      return this._vm._data.$$state
    } 
  }
});

stateのプロパティ取得を定義するだけでいいです.
Commitの実装
Storeは大きなステータスコンテナです(はっきり言えばObjectに簡略化できます)、mutationでデータを変更するしかなく、mutationは非同期操作を含まない純粋な関数であることを規定しています.
Store.prototype.commit = function(type, payload){
  if(this._mutations[type]) {
    this._mutations[type](this.state, payload)
  }
}

Dispatchの実装
dispatchは通常trigger actionに用いられるが、dispatchの実現はどのようなものなのか.
Store.prototype.dispatch= function(type, payload){
  if(this._actions[type]) {
    this._actions[type]({this.commit.bind(this)}, payload)
  }
}

gettersの実装
皆さんはgettersを使うときに確かに便利だと気づきましたが、それはどのように実現されていますか?gettersは、vueのcomputedプロパティを借りてキャッシュします.
store.getters = {};
  for (let [key, fn] of Object.entries(getters)) {
    computed[key] = function () { return fn(store.state, store.getters); };
    Object.defineProperty(store.getters, key, {
      get: function () { return store._vm[key]; },
    });
  }

最初の作成Vueコンポーネントと組み合わせて、vueコンポーネントのcomputedプロパティにcomputedを登録します.
  this._vm = new Vue({
    data: {
      $$state: state
    },
    computed,
  })

これがVuexの基本的な実装形式であり、もちろんVuexのソースコードとは異なる点があるに違いない.例えばmodulesの実装、例えばactionsのparamが実際にcontextであるなどである.皆さんが興味を持っているのは、vuexのソースコードをもっと深く読むことができます.