【フロントエンド辞書】ソースコードからVuex注入Vueライフサイクルを解読する過程

11897 ワード

前言
この文章は「フロントエンド辞書」シリーズの13番目の文章で、次の9編はVueをめぐって展開します.この9編がVueに対する理解を深めることができることを願っています.もちろん、これらの文章の前提は、Vueに一定の基礎があることを黙認することです.基礎が少しもない場合は、まず公式文書を見ることをお勧めします.
最初の文章では、VueとVuexの一部のソースコードを組み合わせて、VuexがVueライフサイクルに注入される過程を説明します.
ソースといえば、思ったほど難しくはありません.私たちが普段書いているビジネスコードとあまり差がなく、メソッドの呼び出しです.しかし、ソースコードの呼び出しツリーは複雑です.
なぜVuexを使うのか
Vueを使用すると、コンポーネント間で共有されているデータやステータスに遭遇することは避けられません.アプリケーションのトラフィックコードは次第に複雑になり,props,イベント,イベントバスなどの通信方式の弊害が顕著になる.この時私たちはVuexが必要です.Vuexは、Vue専用のステータス管理ツールです.
状態管理はVueコンポーネントのデカップリングの重要な手段である.
Flux、reduxの基本思想を参考にして、状態をグローバルに引き出し、Storeを形成しています.
Vuexはコード構造を制限しませんが、いくつかのルールを遵守する必要があります.
  • アプリケーションレベルのステータスは、単一storeオブジェクトの
  • に集中する必要があります.
  • がmutationをコミットすることは状態を変更する唯一の方法であり、このプロセスは同期
  • である.
  • 非同期論理はactionにカプセル化されるべき
  • VuexがVueライフサイクルに注入するプロセス
    私たちはプラグインをインストールするとき、いつも下のようにVue.use()でプラグインをロードしますが、Vue.use()は何をしましたか?
    import Vue from 'vue';
    import Vuex from 'vuex';
    
    Vue.use(Vuex);
    

    Vue.use()は何をしましたか
    Vueをインストールします.jsプラグイン.プラグインがオブジェクトの場合、installメソッドを指定する必要があります.プラグインが関数である場合、installメソッドとして使用されます.Installメソッド呼び出し時に、Vueがパラメータとして入力されます.
    以上が公式文書の解釈です.
    次に、ソース部分からVue.use()が何をしたかを見てみましょう.
    Vueソースコードは、initGlobalAPIエントリメソッドでinitUse (Vue)メソッドを呼び出し、このメソッドはVue.use()が行うべき内容を定義する.
    function initGlobalAPI (Vue) {
      ......
      initUse(Vue);
      initMixin$1(Vue); //     Vue.mixin    
      ......
    }
    
    function initUse (Vue) {
      Vue.use = function (plugin) {
        var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
        /*               */
        if (installedPlugins.indexOf(plugin) > -1) {
          return this
        }
        var args = toArray(arguments, 1);
        args.unshift(this);
        /*         install    */
        if (typeof plugin.install === 'function') {
          plugin.install.apply(plugin, args);
        } else if (typeof plugin === 'function') {
          plugin.apply(null, args);
        }
        installedPlugins.push(plugin);
        return this
      };
    }
    

    このコードは主に2つのことをしました.
  • 同じplugin
  • の再インストールを防止する
  • もう1つはplugin
  • の初期化である
    プラグインのinstallメソッド
    以上のソースコードを見て、プラグイン(Vuex)はinstallの方法を提供する必要があることを知っています.では、Vuexソースコードにこの方法があるかどうかを見てみましょう.結果はもちろんあります.
    /*        install    */
    function install (_Vue) {
      /*       (Vue.use                    )*/
      if (Vue && _Vue === Vue) {
        {
          console.error(
            '[vuex] already installed. Vue.use(Vuex) should be called only once.'
          );
        }
        return
      }
      Vue = _Vue;
      /*   vuexInit     Vue   beforeCreate(Vue2.0)   _init   (Vue1.0) */
      applyMixin(Vue);
    }
    

    このコードは主に2つのことをしました.
  • 一つは、Vuexが
  • に再インストールことを防止するものである.
  • は、Vuex
  • の初期化方法applyMixinを実行することを目的とするvuexInitを実行する.
    次に、applyMixin(Vue)のソースコードを見てみましょう.
    /*   vuexInit     Vue   beforeCreate */
    function applyMixin (Vue) {
      var version = Number(Vue.version.split('.')[0]);
      if (version >= 2) {
        Vue.mixin({ beforeCreate: vuexInit });
      } else {
        /* Vue1.0      ,     */
        ......
      }
      function vuexInit () {
        ......
      }
    }
    

    上記のソースコードから、Vue.mixinメソッドがvuexInitメソッドをbeforeCreateフックに混同するのも、この動作のためであり、vmインスタンスごとにvuexInitメソッドが呼び出されることがわかる.では、vuexInitは何をしましたか.
    vuexInit()
    Vuexを使用する場合は、storeをVueインスタンスに転送する必要があります.
    new Vue({
      el: '#app',
      store
    });
    

    しかし、私たちはvmごとにstoreにアクセスすることができます.これはvuexInitに頼る必要があります.
      function vuexInit () {
        const options = this.$options
        if (options.store) {
          /*       stroe   */
          this.$store = typeof options.store === 'function'
            ? options.store()
            : options.store
        } else if (options.parent && options.parent.$store) {
          /*              $store,                     store*/
          this.$store = options.parent.$store
        }
      }
    

    ルートノードにstroeが存在する場合、options.storethis.$storeに直接割り当てられる.そうでなければ、ルートノードではなく、親ノードの$storeから取得されることを示す.
    このステップでは、任意のvmでthis.$を通過します.storeはStoreのインスタンスにアクセスします.次にVueについてお話ししますmixin().
    Vue.mixin()
    グローバル登録は、登録後に作成されたすべてのVueインスタンスに影響を与える混入です.プラグインの作成者は、ブレンドを使用して、コンポーネントにカスタムの動作を注入することができます.アプリケーションコードでの使用は推奨されません.
    vueのinitGlobalAPIエントリメソッドでは、initMixin$1(Vue)メソッドが呼び出されます.
    function initMixin$1 (Vue) {
      Vue.mixin = function (mixin) {
        this.options = mergeOptions(this.options, mixin);
        return this
      };
    }
    

    VuexがVueライフサイクルに注入される過程は大体そうですが、興味があれば、Vuexのソースコードを直接見て、Storeについてお話しします.
    Store vuexInitはoptionsからStoreを取得すると述べた.では、Storeはどうやって来たのでしょうか.
    Vuexを使用すると、次のようなStoreインスタンスが定義されます.
    import Vue from 'vue'
    import Vuex from 'vuex'
    import mutations from './mutations'
    
    Vue.use(Vuex)
    
    const state = {
        showState: 0,                             
    }
    
    export default new Vuex.Store({
        strict: true,
    	state,
    	getters,
    })
    
    

    パブリケーション環境で厳格なモードを有効にしないでください.厳格モードでは、ステータスツリーを深く監視して、不規則なステータス変更を検出します.パフォーマンスの損失を回避するために、リリース環境で厳格モードをオフにしてください.
    stateの応答式
    stateがどのように応答できるかに関心を持っていますか?これは主にStoreのコンストラクション関数で呼び出されるresetStoreVM(this, state)メソッドによって実現される.
    この方法は主にプライベートをリセットします.vm(Vueのインスタンス)オブジェクト.これはvmオブジェクトはstateツリーを保持し、storeのgettersを計算プロパティで格納します.具体的にその実現過程を見てみましょう.
    /*    Vue          state */
    function resetStoreVM (store, state, hot) {
      /*      vm   */
      const oldVm = store._vm 
    
      store.getters = {}
      const wrappedGetters = store._wrappedGetters
      const computed = {}
    
      /*    Object.defineProperty     store.getters     get   。        this.$store.getters.xxx        ,    store._vm[xxx]*/
      forEachValue(wrappedGetters, (fn, key) => {
        computed[key] = partial(fn, store)
        Object.defineProperty(store.getters, key, {
          get: () => store._vm[key],
          enumerable: true // for local getters
        })
      })
    
      const silent = Vue.config.silent
      /*    silent   true          _vm          */
      Vue.config.silent = true
      /*    new   Vue  ,  Vue          state  computed*/
      store._vm = new Vue({
        data: {
          $$state: state
        },
        computed
      })
      Vue.config.silent = silent
    
      /*       ,Vuex    state        mutation        */
      if (store.strict) {
        enableStrictMode(store)
      }
    
      if (oldVm) {
        /*     vm   state    ,        _vm    */
        if (hot) {
          store._withCommit(() => {
            oldVm._data.$$state = null
          })
        }
        Vue.nextTick(() => oldVm.$destroy())
      }
    }
    

    stateの応答式は,resetStoreVMメソッドを初期化するプロセスであると考えられる.
    Storeのcommitメソッドを見てみましょう
    commitメソッドはmutationをトリガするために使用されることを知っています.
    commit (_type, _payload, _options) {
      /* unifyObjectStyle      */
      const {
        type,
        payload,
        options
      } = unifyObjectStyle(_type, _payload, _options)
    
      const mutation = { type, payload }
      /*       mutation    */
      const entry = this._mutations[type]
      if (!entry) {
        if (process.env.NODE_ENV !== 'production') {
          console.error(`[vuex] unknown mutation type: ${type}`)
        }
        return
      }
      /*    mutation      */
      this._withCommit(() => {
        entry.forEach(function commitIterator (handler) {
          handler(payload)
        })
      })
      /*        ,      mutation        state */
      this._subscribers.forEach(sub => sub(mutation, this.state))
    
      if (
        process.env.NODE_ENV !== 'production' &&
        options && options.silent
      ) {
        console.warn(
          `[vuex] mutation type: ${type}. Silent option has been removed. ` +
          'Use the filter functionality in the vue-devtools'
        )
      }
    }
    

    この方法は、まずパラメータスタイルチェックを行い、その後、_withCommit法を用いて、今回のバッチトリガmutation処理関数を実行する.実行が完了すると、_subscribers(サブスクリプション関数)の今回の操作のmutationオブジェクトと現在のstateステータスがすべて通知されます.
    Vue関連記事出力計画
    最近いつも友达が私にVueの関连する问题を闻いて、だから私はこれから9篇のVueの関连する文章を出力して、みんなに対して一定の助けがあることを望みます.私は7日から10日以内に更新します.
  • 【フロントエンド辞書】Vuex注入Vueライフサイクルのプロセス
  • 【フロントエンド辞書】Vue応答式原理
  • を浅く分析する
  • 【フロントエンド辞書】新旧VNodeがpatchを行う過程
  • 【フロントエンド辞書】機能コンポーネントを開発しnpm
  • をアップロードする方法
  • 【フロントエンド辞書】このいくつかの面からあなたのVueプロジェクト
  • を最適化します.
  • 【フロントエンド辞書】Vue-Router設計からフロントエンドルーティング発展
  • 【フロントエンド辞書】プロジェクトでWebpack
  • を正しく使用する方法
  • 【フロントエンド辞書】Vueサービス側レンダリング
  • 【フロントエンド辞書】AxiosとFetchはどのように
  • を選択します
    私の公衆番号に注目することをお勧めします.最初の時間に最新の文章を受け取ることができます.
    グループコミュニケーションを追加したい場合は、スマートなロボットを追加して、自動的にグループに引き込むこともできます.
    人気記事配信ゲート
  • 【フロントエンド辞書】スクロールスルー問題の解決策
  • 【フロントエンド辞書】5種類のスクロールトップ実装方式の比較(性能アップグレード版)
  • 【フロントエンド辞書】幸福感を高める9つのCSSテクニック
  • 【フロントエンド辞書】8つの面白くて実用的なAPI
  • を共有
  • 【フロントエンド辞書】入力URLから、どのようなキャッシュに関するかを示すコーナー(非常に詳細)