web-dev-qa-db-ja.com

計算されたプロパティを使用するとVuex $ storeプロパティが無効になる

私はVuexストアを持っています。これをインスタンスに挿入しています:

import store from '../store';

const mainNav = new Vue({
  el: '#main-nav',
  store,
  components: { NavComponent }
});

そして、私はコンポーネントのそのストアから計算されたプロパティを作成しています:

computed: {
  isWide() {
    return this.$store.state.nav.type === 'wide';
  }
}

これにより、コンポーネントの初期化時にテンプレートのthis.isWideプロパティが作成されますが、ストア値が更新されても、コンポーネントはこれを登録しません。古い値がテンプレートに残っています。

ここで何が悪いのですか?

13
babbaggeii

すべてが正しく設定されていれば、コードは機能するはずです。 http://codepen.io/CodinCat/pen/RKZeZe?editors=101

よくある間違いは、州の初期データを提供しなかったことです。

状態の形状を明示的に宣言する必要があるので、代わりに

state: {}

// or

state: {
  nav: {}
}

これを行う:

state: {
  nav: {
    type: '...'
  },
  ...
}

または、プロパティは次の例のように反応しません: http://codepen.io/CodinCat/pen/ggxBEV?editors=101

そして、状態を更新したことを確認してください。おそらく問題は、期待どおりに状態を正しく更新しなかっただけです。

15
CodinCat

実際には、Vue.set()関数を使用して、新しいプロパティをリアクティブにする必要があります。

changeType () {
   Vue.set(this.$store.state.nav, 'type', 'wide');
}

このコードペンを参照してください: https://codepen.io/DedicatedManager/pen/JZgpaa

私はこのテーマで全画面キャプチャビデオを行いました:youtu.be/8GHczab2Lbs

2

コンポーネントオブジェクトのメソッドからストアオブジェクトを直接操作しないでください。ストアオブジェクトの変更をコミットする必要があります。ミューテーションはリスナーを持つ関数であり、呼び出されると、変更された変数が追跡され、変更が伝達されます。サーバーにデータを送信するなどの非同期処理が必要な場合は、ストアでのアクションをさらに1ステップ定義して、非同期呼び出しを実行し、そこから変更をコミットして状態オブジェクトを更新します。耳障りに聞こえるかもしれませんが、慣れれば簡単です。

const store = new Vuex.Store({
  state: {
    nav: {
      type: 'not wide by default'
    }
  },
  mutations: {
    changeType: (state, type) => {
      state.nav.type = type;
    }
  }
})

Vue.component('NavComponent', {
  template: '<div>isWide?: {{isWide}}</div>',
  computed: {
    isWide () {
      return this.$store.state.nav.type === 'wide'
    }
  }
})

new Vue({
  el: '#app',
  store,
  methods: {
    changeType (type) {
      this.$store.commit('changeType', type);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.1.0/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.js"></script>
<div id="app">
  <nav-component></nav-component>
  <button @click="changeType('wide')">
    Change to Wide
  </button>
  <button @click="changeType('narrow')">
    Change to Narrow
  </button>
</div>

https://codepen.io/zoransa/pen/KyqvWd?editors=101

タイプなしでstat.navでも直接動作します https://codepen.io/zoransa/pen/xPrLyW?editors=101

1
Zoran

Vuexストアからオブジェクトに新しいプロパティを追加するときは、次のいずれかを使用する必要があります

Vue.set(obj, 'newProp', 123)

または、そのオブジェクトを新しいオブジェクトに置き換えます

state.obj = { ...state.obj, newProp: 123 }

から Vuex docs

1
ssten

これが私の問題でした。

  const store = new Vuex.Store({
    state: {
      isTrackPlaying: false,
    },
  ...
  });

初期状態を設定するのを忘れてしまいましたが、今はリアクティブです。

0
chovy