web-dev-qa-db-fra.com

vuejs 2 comment regarder les valeurs de magasin de vuex

J'utilise vuex et vuejs 2 ensemble.

Je suis nouveau à vuex, je veux regarder un changement de variable store.

Je veux ajouter la fonction watch dans mon vue component

C'est ce que j'ai jusqu'ici:

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 le my_state

Comment regarder store.my_state dans mon composant vuejs?

84
raffffffff

Supposons, par exemple, que vous ayez un panier de fruits, Et que chaque fois que vous ajoutez ou retirez un fruit du panier, vous Souhaitez (1) afficher des informations sur le nombre de fruits, mais vous souhaitez également (2) être averti du décompte des fruits de façon élégante ...

fruit-count-composant.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, yaay!`)
    }
  }
}
</script>

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

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

Le magasin de paniers pourrait ressembler à ceci:

fruit-basket.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
    }
  }
  // Obvously you would need some mutations and actions,
  // but to make example cleaner I'll skip this part.
})

export default basket

Vous pouvez en lire plus dans les ressources suivantes:

98
Anastazy

Vous ne devez pas utiliser les observateurs du composant pour écouter le changement d'état. Je vous recommande d'utiliser les fonctions de lecture, puis de les mapper à l'intérieur de votre composant.

import { mapGetters } from 'vuex'

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

Dans votre magasin:

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

Vous devriez pouvoir écouter les modifications apportées à votre magasin en utilisant this.myState dans votre composant.

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

63
Gabriel Robert

Comme mentionné ci-dessus, il est déconseillé de suivre les modifications directement en magasin

Mais dans de très rares cas, cela peut être utile pour quelqu'un, je laisserai donc cette réponse. Pour d'autres cas, veuillez consulter la réponse @ gabriel-robert}

Vous pouvez le faire via state.$watch. Ajoutez ceci dans votre méthode created (ou si vous avez besoin que cela soit exécuté) 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/fr/api.html#vuex-store-instance-methods

32
GONG

Je pense que le demandeur veut utiliser la montre avec Vuex. 

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

      },
      {
        deep:true
      }
      );
12
yeahdixon

C’est pour toutes les personnes qui ne peuvent pas résoudre leur problème avec des accesseurs et qui ont réellement besoin d’un observateur, par exemple. parler à des tiers non-vue (voir Vue Watchers pour savoir quand utiliser Watchers).

Les observateurs et les valeurs calculées du composant Vue fonctionnent également sur les valeurs calculées. Donc, ce n'est 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, le docState de la carte 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
        }
    }
})
6
dube

La meilleure façon de surveiller les changements de magasin consiste à utiliser mapGetters comme l'a dit Gabriel… .. Mais il est un cas où vous ne pouvez pas le faire via mapGetters par exemple. vous voulez obtenir quelque chose du magasin en utilisant le paramètre:

getters: {
  getTodoById: (state, getters) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}

dans ce cas, vous ne pouvez pas utiliser mapGetters. Vous pouvez essayer de faire quelque chose comme ceci à la place:

computed: {
    todoById() {
        return this.$store.getters.getTodoById(this.id)
    }
}

Mais malheureusement, todoByIdne sera mis à jour que si this.id est modifié

Si vous souhaitez mettre à jour vos composants dans ce cas, utilisez this.$store.watchsolution fournie par Gong . Ou manipulez votre composant consciemment et mettez à jour this.id lorsque vous devez mettre à jour todoById.

4
Arseniy-II

Créez un état local de votre variable de magasin en surveillant et en définissant les changements de valeur . Ainsi, la variable locale change pour formulaire-entrée v-modèle ne mute pas directement la variable magasin.

data() {
  return {
    localState: null
  };
 },
 computed: {
  ...mapGetters({
    computedGlobalStateVariable: 'state/globalStateVariable'
  })
 },
 watch: {
  computedGlobalStateVariable: 'setLocalState'
 },
 methods: {
  setLocalState(value) {
   this.localState = Object.assign({}, value);
  }
 }
2
Mukundhan

C'est aussi simple que:

watch: {
  '$store.state.drawer': function() {
    console.log(this.$store.state.drawer)
  }
}
2
micah5

Vous pouvez utiliser une combinaison de Vuex actions , getters , propriétés calculées et observateurs pour écouter les modifications apportées à la valeur d’un état Vuex.

Code HTML:

<div id="app" :style='style'>
  <input v-model='computedColor' type="text" placeholder='Background Color'>
</div>

Code JavaScript:

'use strict'

Vue.use(Vuex)

const { mapGetters, mapActions, Store } = Vuex

new Vue({
    el: '#app',
  store: new Store({
    state: {
      color: 'red'
    },
    getters: {
      color({color}) {
        return color
      }
    },
    mutations: {
      setColor(state, payload) {
        state.color = payload
      }
    },
    actions: {
      setColor({commit}, payload) {
        commit('setColor', payload)
      }
    }
  }),
  methods: {
    ...mapGetters([
        'color'
    ]),
    ...mapActions([
        'setColor'
    ])
  },
  computed: {
    computedColor: {
        set(value) {
        this.setColor(value)
      },
      get() {
        return this.color()
      }
    },
    style() {
        return `background-color: ${this.computedColor};`
    }
  },
  watch: {
    computedColor() {
        console.log(`Watcher in use @${new Date().getTime()}`)
    }
  }
})

Voir la démo de JSFiddle .

1
Amin NAIRI

Lorsque vous souhaitez surveiller au niveau de l'état, vous pouvez le faire de la manière suivante:

let App = new Vue({
    //...
    store,
    watch: {
        '$store.state.myState': function (newVal) {
            console.log(newVal);
            store.dispatch('handleMyStateChange');
        }
    },
    //...
});
1
Andy

Vous pouvez également vous abonner aux mutations du magasin:

store.subscribe((mutation, state) => {
  console.log(mutation.type)
  console.log(mutation.payload)
})

https://vuex.vuejs.org/api/#subscribe

0
alloyking

Vous pouvez également utiliser mapState dans votre composant vue pour obtenir directement l'état d'un magasin.

Dans votre composant:

computed: mapState([
  'my_state'
])

my_state est une variable du magasin.

0
Eugene Kulakov