J'ai un magasin Vuex, que j'injecte dans mon instance:
import store from '../store';
const mainNav = new Vue({
el: '#main-nav',
store,
components: { NavComponent }
});
Et je crée une propriété calculée à partir de ce magasin dans le composant:
computed: {
isWide() {
return this.$store.state.nav.type === 'wide';
}
}
Cela crée le this.isWide
propriété du modèle lors de l'initialisation du composant, mais lorsque la valeur de stockage est mise à jour, le composant ne l'enregistre pas - l'ancienne valeur se trouve toujours dans le modèle.
Qu'est-ce que je fais mal ici?
Votre code devrait fonctionner si vous configurez tout correctement: http://codepen.io/CodinCat/pen/RKZeZe?editors=101
Une erreur très courante est que vous n'avez pas donné les données initiales de votre état.
Vous devez déclarer explicitement la forme d'état, donc au lieu de
state: {}
// or
state: {
nav: {}
}
faites ceci:
state: {
nav: {
type: '...'
},
...
}
ou les propriétés ne seront pas réactives, comme cet exemple: http://codepen.io/CodinCat/pen/ggxBEV?editors=101
Et assurez-vous d'avoir mis à jour l'état, peut-être que le problème est simplement que vous n'avez pas mis à jour l'état correctement comme prévu.
En fait, vous devez utiliser la fonction Vue.set () pour rendre la nouvelle propriété réactive.
changeType () {
Vue.set(this.$store.state.nav, 'type', 'wide');
}
Voir ce codepen: https://codepen.io/DedicatedManager/pen/JZgpaa
J'ai fait une vidéo de capture d'écran entière sur ce sujet: youtu.be/8GHczab2Lbs
vous ne devez pas manipuler les objets du magasin directement à partir des méthodes des composants, vous devez valider les mutations sur l'objet du magasin. Les mutations sont des fonctions qui ont des écouteurs et lorsqu'elles sont appelées, les variables modifiées sont suivies et les modifications sont propagées. Si vous devez faire quelque chose d'asynchrone comme soumettre des données au serveur, vous devez même aller plus loin pour définir des actions sur le magasin, faire un appel asynchrone, puis valider des mutations à partir de là pour mettre à jour l'objet d'état. Je sais que cela semble si ennuyeux, mais une fois que vous y êtes habitué, c'est assez simple.
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
il fonctionne également directement sur stat.nav sans type https://codepen.io/zoransa/pen/xPrLyW?editors=101
Lorsque vous ajoutez de nouvelles propriétés à un objet à partir de votre magasin Vuex
, vous devez soit utiliser
Vue.set(obj, 'newProp', 123)
ou remplacez cet objet par un nouveau
state.obj = { ...state.obj, newProp: 123 }
C'était mon problème.
const store = new Vuex.Store({
state: {
isTrackPlaying: false,
},
...
});
J'ai oublié de définir l'état initial et maintenant il est réactif.