309 votes

Comment surveiller les valeurs de magasin à partir de vuex ?

J'utilise vuex y vuejs 2 ensemble.

Je suis nouveau dans vuex Je veux regarder un store changement de variable.

Je veux ajouter le watch dans mon vue component

Voici ce que j'ai jusqu'à présent :

import Vue from 'vue';
import {
  MY_STATE,
} from './../../mutation-types';

export default {
  [MY_STATE](state, token) {
    state.my_state = token;
  },
};

Je veux savoir s'il y a des changements dans les my_state

Comment puis-je regarder store.my_state dans mon composant Vuejs ?

0 votes

Utilisez un plugin Vuejs qui est fourni avec chrome, il vous sera utile

352voto

Anastazy Points 1222

Disons, par exemple, que vous avez un panier de fruits, et qu'à chaque fois que vous ajoutez ou retirez un fruit de la corbeille, vous voulez (1) afficher des informations sur le nombre de fruits, mais vous souhaitez également (2) être informé du décompte des fruits d'une manière ou d'une autre...

Composant de comptage de fruits.vue

<template>
  <!-- We meet our first objective (1) by simply -->
  <!-- binding to the count property. -->
  <p>Fruits: {{ count }}</p>
</template>

<script>
import basket from '../resources/fruit-basket'

export default () {
  computed: {
    count () {
      return basket.state.fruits.length
      // Or return basket.getters.fruitsCount
      // (depends on your design decisions).
    }
  },
  watch: {
    count (newCount, oldCount) {
      // Our fancy notification (2).
      console.log(`We have ${newCount} fruits now, yay!`)
    }
  }
}
</script>

Veuillez noter que le nom de la fonction dans le champ watch doit correspondre au nom de la fonction dans l'objet computed objet. Dans l'exemple ci-dessus, le nom est count .

Les nouvelles et anciennes valeurs d'une propriété surveillée seront passées en paramètres dans le callback de la surveillance (la fonction de comptage).

Le magasin de paniers pourrait ressembler à ceci :

corbeille a fruits.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const basket = new Vuex.Store({
  state: {
    fruits: []
  },
  getters: {
    fruitsCount (state) {
      return state.fruits.length
    }
  }
  // Obviously you would need some mutations and actions,
  // but to make example cleaner I'll skip this part.
})

export default basket

Vous pouvez en savoir plus en consultant les ressources suivantes :

0 votes

Je me demande juste ce que je dois faire quand le watch L'action doit être divisée en deux étapes : 1) Tout d'abord, vérifier si les données souhaitées sont mises en cache et si c'est le cas, renvoyer simplement les données mises en cache ; 2) Si le cache a échoué, j'ai besoin d'une action ajax asynchrone pour récupérer les données, mais cela semble être la solution la plus simple. action Le travail de l'entreprise. J'espère que ma question a un sens, merci !

2 votes

Quel est l'avantage de cette méthode par rapport à la réponse de micah5, qui définit simplement un observateur dans le composant, sur la valeur du magasin ? Il y a moins de code à maintenir.

1 votes

@Exocentric Quand j'ai écrit la réponse, la question n'était pas claire pour moi. Il n'y a pas de contexte pourquoi il est nécessaire de surveiller les propriétés. Pensez-y comme suit : "Je veux surveiller la variable X, pour pouvoir faire Y." C'est probablement la raison pour laquelle la plupart des réponses proposent des approches si différentes. Personne ne sait quelle est l'intention. C'est pourquoi j'ai inclus les "objectifs" dans ma réponse. Si vous avez des objectifs différents, une réponse différente pourrait leur correspondre. Mon exemple n'est qu'un point de départ pour l'expérimentation. Il ne s'agit pas d'une solution plug & play. Il n'y a pas de "bénéfice", car les bénéfices dépendent de votre situation.

75voto

Gabriel Robert Points 1589

Vous ne devez pas utiliser les observateurs du composant pour écouter les changements d'état. Je vous recommande d'utiliser les fonctions getters puis de les mapper dans votre composant.

import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters({
      myState: 'getMyState'
    })
  }
}

Dans votre magasin :

const getters = {
  getMyState: state => state.my_state
}

Vous devriez être en mesure d'écouter toutes les modifications apportées à votre magasin en utilisant this.myState dans votre composant.

https://vuex.vuejs.org/en/getters.html#the-mapgetters-helper

2 votes

Je ne sais pas comment mettre en œuvre les mapGetters. Pouvez-vous m'indiquer un exemple ? Cela m'aiderait beaucoup. Pour l'instant, je me contente de mettre en œuvre la réponse GONG. TY

2 votes

@Rbex "mapGetters" fait partie de la bibliothèque 'vuex'. Vous n'avez pas besoin de l'implémenter.

0 votes

Merci, j'ai vu des vidéos en vuex et j'ai déjà utilisé les mapGetters en vuex. computed: { ...mapGetters({ myState: 'getMyState' }) } c'est la partie qui me donne l'erreur et j'installe babel. Maintenant ça marche comme sur des roulettes... TY

59voto

GONG Points 2079

Comme mentionné ci-dessus, il n'est pas judicieux de regarder les changements directement en magasin.

Mais dans certains cas très rares, cela peut être utile à quelqu'un, alors je vais laisser cette réponse. Pour les autres cas, voir la réponse de @gabriel-robert

Vous pouvez le faire par state.$watch . Ajoutez ceci dans votre created (ou à l'endroit où vous souhaitez qu'elle soit exécutée) dans le composant.

this.$store.watch(
    function (state) {
        return state.my_state;
    },
    function () {
        //do something on data change
    },
    {
        deep: true //add this if u need to watch object properties change etc.
    }
);

Plus de détails : https://vuex.vuejs.org/api/#watch

3 votes

Je ne pense pas que ce soit une bonne idée de regarder l'état directement. Nous devrions utiliser des getters. vuex.vuejs.org/fr/getters.html#the-mapgetters-helper

15 votes

@GabrielRobert Je pense qu'il y a une place pour les deux. Si vous avez besoin de changer les conditions du modèle de manière réactive, l'utilisation d'une valeur calculée avec mapState, etc. est logique. Mais autrement, comme pour le contrôle de flux dans un composant, vous avez besoin d'une surveillance complète. Vous avez raison, vous ne devriez pas utiliser de simples veilleurs de composants, mais state.$watch est conçu pour ces cas d'utilisation.

20 votes

Tout le monde le mentionne, mais personne ne dit pourquoi ! J'essaie de construire un magasin vuex qui est auto-synchronisé avec une base de données lors des changements. J'ai l'impression que la surveillance du magasin est le moyen le plus simple ! Qu'en pensez-vous ? Ce n'est toujours pas une bonne idée ?

22voto

yeahdixon Points 1713

Je pense que le demandeur veut utiliser watch avec Vuex.

this.$store.watch(
      (state)=>{
        return this.$store.getters.your_getter
      },
      (val)=>{
       //something changed do something

      },
      {
        deep:true
      }
      );

1 votes

Où doit-on l'appeler ?

2 votes

Quelque part qui a accès à l'instance Vue par le biais de this . comme, un created crochet. Fondamentalement, tout composant dont vous avez besoin

19voto

dube Points 1383

C'est pour toutes les personnes qui ne peuvent pas résoudre leur problème avec des getters et qui ont réellement besoin d'un watcher, par exemple pour parler à des choses tierces non-vue (cf. Vue Watchers sur le moment où il faut utiliser les veilleurs).

Les observateurs et les valeurs calculées des composants Vue fonctionnent également sur les valeurs calculées. Ce n'est donc pas différent avec Vuex :

import { mapState } from 'vuex';

export default {
    computed: {
        ...mapState(['somestate']),
        someComputedLocalState() {
            // is triggered whenever the store state changes
            return this.somestate + ' works too';
        }
    },
    watch: {
        somestate(val, oldVal) {
            // is triggered whenever the store state changes
            console.log('do stuff', val, oldVal);
        }
    }
}

s'il ne s'agit que de combiner l'état local et global, la doc de mapState fournit également un exemple :

computed: {
    ...mapState({
        // to access local state with `this`, a normal function must be used
        countPlusLocalState (state) {
          return state.count + this.localCount
        }
    }
})

0 votes

C'est une bonne idée, mais c'est trop fastidieux, tu ne crois pas ?

2 votes

Ce n'est pas un hack si c'est dans les docs, n'est-ce pas ? Mais alors, ce n'est pas non plus un argument en faveur de vue/vuex.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X