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?
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:
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
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
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
}
);
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
}
}
})
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, todoById
ne sera mis à jour que si this.id
est modifié
Si vous souhaitez mettre à jour vos composants dans ce cas, utilisez this.$store.watch
solution fournie par Gong . Ou manipulez votre composant consciemment et mettez à jour this.id
lorsque vous devez mettre à jour todoById
.
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);
}
}
C'est aussi simple que:
watch: {
'$store.state.drawer': function() {
console.log(this.$store.state.drawer)
}
}
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()}`)
}
}
})
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');
}
},
//...
});
Vous pouvez également vous abonner aux mutations du magasin:
store.subscribe((mutation, state) => {
console.log(mutation.type)
console.log(mutation.payload)
})
Vous pouvez également utiliser mapState dans votre composant vue pour obtenir directement l'état d'un magasin.
Dans votre composant:
computed: mapState([
'my_state'
])
Où my_state
est une variable du magasin.