2017-06-20 16 views
1

計算されたゲッターが更新される前の状態にアクセスして古い状態をレンダリングする問題があります。私はすでにアクションと突然変異をマージし、状態をさまざまな値に変更するなどのいくつかの試みを試みましたが、ディスパッチが完了する前にゲッターが呼び出されています。非同期アクション(API呼び出し)が完了する前にVuexにアクセスする前に非同期アクションが完了しました

問題

状態がアクセスされます。

コード構造

  1. コンポーネントAの負荷のAPIデータ。
  2. ユーザーが1つのデータをクリックします。
  3. コンポーネントAは、クリックされたデータ(オブジェクト)をコンポーネントBにディスパッチします。
  4. コンポーネントBが受け取ったオブジェクトをロードします。

DOMはうまくレンダリングします。これはコンソールエラーです。 Vueは常にDOMの変更を監視し、即座に再レンダリングします。しかし、コンソールはすべてをピックアップします。 (成分のみの後に呼び出される)

目標

防止成分B、成分Aのディスパッチ前に計算されたゲッターメソッドを実行してから完了します。

Store.js

import Vue from 'vue' 
import Vuex from 'vuex' 
import axios from 'axios'; 

Vue.use(Vuex); 

export const store = new Vuex.Store({ 

    state: { 
    searchResult: {}, 
    selected: null, 
    }, 

    getters: { 
    searchResult: state => { 
     return state.searchResult; 
    }, 
    selected: state => { 
     return state.selected; 
    }, 
    }, 

    mutations:{ 
    search: (state, payload) => { 
     state.searchResult = payload; 
    }, 
    selected: (state, payload) => { 
     state.selected = payload; 
    }, 
    }, 

    actions: { 
    search: ({commit}) => { 
     axios.get('http://api.tvmaze.com/search/shows?q=batman') 
     .then(response => { 
      commit('search', response.data); 
     }, error => { 
      console.log(error); 
     }); 
    }, 

    selected: ({commit}, payload) => { 
     commit('selected', payload); 
    }, 
    }, 

}); 

SearchResult.vue

<template> 
<div> 
    //looped 
    <router-link to="ShowDetails" @click.native="selected(Object)"> 
     <p>{{Object}}</p> 
    </router-link> 
</div> 
</template> 

<script> 
export default { 
    methods: { 
    selected(show){ 
     this.$store.dispatch('selected', show); 
    }, 
    }, 
} 
</script> 

ShowDetails.vue

<template> 
<div> 
    <p>{{Object.name}}</p> 
    <p>{{Object.genres}}</p> 
</div> 
</template> 

<script> 
export default { 
    computed:{ 
    show(){ 
     return this.$store.getters.selected; 
    }, 
    }, 
} 
</script> 

This image shows that the computed method "show" in file 'ShowDetails' runs before the state is updated (which happens BEFORE the "show" computed method. Then, once it is updated, you can see the 2nd console "TEST" which is now actually populated with an object, a few ms after the first console "TEST".

質問

Vuexはので、どのように私はこのコンソールのエラーを防ぐことができ、すべての状態が監視や管理についてですか?

ありがとうございます。

答えて

1

store.dispatchをもたらしていない約束を扱うことができる場合は、テンプレートのレンダリングを避けるために、V-IFを使用しようとすることができ

0

状態を初期化します。 他のすべてのVueのデータと同じように、開始点では、空の''または[]でも初期化する方が常に良いですが、VueJS(AngularまたはReactが同じ動作をするかどうかわかりませんが、類似しているとは思いますが)あなたの変数の初期化。

ストアインスタンスで状態の最初の空の値を定義できます。

ここだけでなく、ほとんどのプラグインは初期化されたデータで正常に動作しますが、初期化されていないデータでは正しく動作しないため、フォームの検証が必要です。

希望します。あなたはそれが何の検索が

v-if="$store.getters.searchResult" 
0

は、トリガー・アクションハンドラによって返されると、それはまた約束を返します。 Composing Actionsを参照してください。 router-linkは、ボタンを使用しての成功コールバックでprogrammatic navigationを行う使用するのではなく、あなたのSearchResults.vueで次に

selected: ({commit}, payload) => { 
    return new Promise((resolve, reject) => { 
     commit('selected', payload); 
    }); 
} 

あなたはセットアップあなたの選択アクションは、このような約束を戻すことができますあなたののような行動の約束を選択しました:

<template> 
<div> 
    //looped 
    <button @click.native="selected(Object)"> 
     <p>{{Object}}</p> 
    </button> 
</div> 
</template> 

<script> 
export default { 
    methods: { 
    selected(show){ 
     this.$store.dispatch('selected', show) 
      .then(() => { 
      this.$router.push('ShowDetails'); 
     }); 
    }, 
    }, 
} 
</script>