同様の突然変異の作用は、突然変異を直接ステータスを変更するのではなく、送信アクションであり、非同期動作中の任意のアクションを含むことができることを除いて、各変異のパラメータは、次の6つのプロパティを含んでいてもよい、オブジェクト1:
COMMIT;コミットに対応する現在の名前空間
ディスパッチするステップと、名前空間の現在のディスパッチに対応する
状態;名前空間は、現在の状態に対応する
ゲッター、現在の名前空間対応ゲッターの
rootState、ルートモジュール状態
ゲッタールートモジュールとrootGetters
突然変異と同様、Vuex.Store()は各アクションのアクションを介して作成することができる作成時にインスタンス倉庫
次のようにどちらも私たちがアクションを呼び出す必要がありますが、store.dispatchによって呼び出され、ディスパッチは、2つのパラメータを取ることはできません。
タイプ、対応するアクション名
ペイロード、着信パラメータ
書かれたディスパッチがオブジェクトに渡され、オブジェクトはオブジェクト全体がアクションに引数として渡され、指定されたアクションの名前を入力し、型引数を取ることができますもあります。注意:アクションは、非同期操作を含めることができます
例えば:
<!DOCTYPE HTML > < HTML LANG = "EN" > < 頭> < メタ文字コード= "UTF-8" > < タイトル>ドキュメント</ タイトル> < スクリプトSRC = "https://cdn.jsdelivr.net/npm/vue @ 2.5.16 / DIST / vue.js」> </ スクリプト> < スクリプトSRC = "https://unpkg.com/[email protected]/dist/vuex.js" > </ スクリプト> </ ヘッド> < 身体> > < P > {{ない}} </ P > < ボタン@click = "テスト" >测试</ ボタン> </ DIV > < スクリプト> CONSTストア= 新しいVuex.Store({ 状態:{NO:100 } 、 変異:{ インクリメント(状態、ペイロード){state.no + = payload.no;} }、 アクション:{ インクリメント({コミット}、情報){ 戻り 、新たな約束(関数を{(拒否、解決) // オブジェクト内のアクションの約束を返す のsetTimeout(関数(){ コミット(' INCREMENT ' 、インフォ) 解決(' OK ' ) }、500 ) )} } } )}を VAR のApp = 新しい新しいヴュー( { EL:" #app " 、 店舗、 計算:{ NO(){ リターン 、この$ store.state.no。} }、 メソッド:{ テスト(){ この。$のstore.dispatch(' 増加' 、{NO:100 }) } } }) </ スクリプト> </しませんボディ> </ HTML >
私たちは、自動的にターゲットの約束に値を返す内部vuexはPromise.resolveを呼び出して、約束のオブジェクトアクションも開催することができます返しません
ソースコード解析
砂漠のQQ:22969969によって作家
作成Vuex.Store()は、ルートモジュールの初期化をインストールするinstallModule()を実行し、のように関連する変異は、以下:
関数 installModule(ストア、rootState、パス、モジュール、ホット){ // モジュールをインストール / * 少し* / module.forEachAction(機能(アクション、キー){ // 見つかった場合のアクションは、このの後、実装、トラバースモジュールモジュールオブジェクト無名関数のパラメータ1:各アクションの値キー:名に対応するキー VARタイプ= action.rootキーの名前空間+キー;? // 名前空間キー+対応 するvarハンドラ= action.handler ||アクション; //は対応を取得します関数 のRegisterAction(ストア、タイプの、ハンドラ、地元は); // 呼び出しのRegisterActionは登録されているアクション }); / * 少し* / }
RegisterActionは、次のようにアクションを登録するために使用されます。
機能のRegisterAction(ストア、タイプ、ハンドラ、ローカル){ // ストア例のタイプ:コンテキストオブジェクト:名前のアクションハンドラの名前空間を構成する:機能ローカル登録アクション機能ストアは VARの(||エントリ= store._actions [タイプ] store._actionsは、[タイプ] = []); // タイプに対応_actionsストアオブジェクトが空の場合、配列は空に初期化さ entry.push(関数 wrappedActionHandler(ペイロード、CB){ // store._actionsには、中に押し込み無名関数 のvar RES = handler.call(ストア、{ // この関数 派遣:local.dispatch、 コミット:local.commit、 ゲッター:local.getters、 状態:local.state、 rootGetters:store.getters、 rootState:STORE.STATE }、ペイロード、CB); // ストアの実行ハンドラ関数コンテキストは、オブジェクトのパラメータは、1であり、2は、パラメータデータペイロードは、戻り値はRESに格納されている IF(isPromise! (RES)){ // そうでない場合プロミスresは RES = Promise.resolve(RES)を; // それがオブジェクトの約束に変換される } IF (store._devtoolHook){ リターン。RES キャッチ(関数(ERR){ ストア。 _devtoolHook.emit( 'vuex:エラー' 、ERR); スロー ERR }) } 他{ 戻りRES } })。 }
ここからは、パラメータ1を対応する各アクションはハンドラ関数であることがわかります戻り値は、オブジェクトを約束されていない場合、オブジェクトの約束に変換しPromise.resolve()を呼び出して、入ってくるオブジェクト、ここで実行されます
私たちは、この$のstore.dispatch(「増分」、{NO:100})呼びたい。アクショントリガー、第1のトリガディスパッチ機能ストアは再定義、それは現在のコンテキストオブジェクトのプロトタイプストアを継続ストア機能しますディスパッチ関数、次のように:
= Store.prototype.dispatch 関数ディスパッチ(_type、_payload){ // アクション非同期動作配布 VAR この $ 1 =。この; // チェックスタイルオブジェクトディスパッチ するvar REF = unifyObjectStyle(_type、_payload); // 指定次のパラメータ、オブジェクトを返し、呼をコミットここで同じである VaRのタイプ= ref.type; VARのペイロード= ref.payload; VARのアクション= ; {ペイロードタイプ:タイプ、ペイロード} VARのエントリ= この ; ._actions [タイプ] / / アクションの種類のタイプを取得しようとし たIF(!エントリー){ // 如果不存在则报错并返回 { console.error(( "[vuex]未知のアクションタイプ:" + タイプ)); } 戻り } 試みる{ この._actionSubscribers .filter(関数(サブ){ 戻りsub.beforeを;}) .forEach(関数(サブ){ 戻り sub.before(アクション、この $ 1 .state);}); } キャッチ(E){ { console.warn("前アクション加入で[vuex]エラー:" ); console.error(E); } } VARの結果= entry.length> 1 ?Promise.all(entry.map(関数(ハンドラ){ 戻りハンドラ(ペイロード);})) :エントリ[ 0](ペイロード)。 // 执行该アクション、大于1则如果用Promise.all() の戻り result.then(機能(RES){ しようと{ この $ 1 ._actionSubscribersの .filter(機能(サブ){ 返す }); sub.after (.forEachを機能(サブ){ 戻り sub.after(アクション、この $ 1 .state);}); } キャッチ(E){ { console.warn( "アクション加入後に[vuex]エラー:" )。 console.error(E); } } 戻りRES }) }。
最後のリターンプロミスは、このように非同期操作を実現し、オブジェクトである、RESました。