Je recherche une manière propre d'utiliser v-model et vuex store.
Vuex fournit plusieurs méthodes helpers qui sont assez utiles mais un peu ennuyeuses lors de l'utilisation avec v-model.
La manière Je fais aujourd'hui pour utiliser v-model et mon magasin modulaire est comme
computed: {
...mapState(['type']) // No need here to specify module name :)
}
Cela fonctionne MAIS j'ai trouvé préférable de profiter des helpers vuex pour éviter le code standard (ceci. $ Store , nom du module, ...)
Ok, donc je veux d'abord me débarrasser du nom du module. Vuex fournit un excellent createNamespacedHelpers qui renvoie des helpers modulaires.
Utilisons-le:
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
Alors, ok, nous avons maintenant des fonctions propres mapState et mapActions qui sont dédiées au module.
computed: {
type: {
get() {
return this.$store.state.mymodule.type;
},
set(newValue) {
this.$store.dispatch('mymodule/setType', newValue)
}
}
Assez cool mais comme mapState n'a que la fonction get, je ne peux pas définir une fonction de répartition pour mettre à jour les données ...
En cas d'utilisation de v-model, je trouve les helpers inutilisables. Je ne peux pas utiliser mapState, donc je ne peux pas utiliser createNamespacedHelpers.
Alors: Comment puis-je utiliser les avantages des fonctions d'aide de Vuex et du v-model pour travailler ensemble?
3 Réponses :
Vous ne pouvez pas. Il n'y a pas de moyen élégant de combiner les aides avec le modèle en V. Mais le v-model n'est qu'un sucre syntaxique, donc peut-être que le moyen le plus lisible est d'utiliser les helpers
<input :value="type" @input="setType">
sans le v-model
computed: {
...mapGetters('path/to/module', ['type'])
},
methods: {
...mapActions('path/to/module', ['setType'])
}
La façon dont j'ai finalement trouvé le plus lisible est la suivante:
<input :value="type" @input="setType($event.target.value)">
Utilisé comme ceci:
computed: {
...mapGetters(['type'])
},
methods: {
...mapActions(['setType'])
}
Et sans le v- modèle
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
Essayez ceci.
import { mapSetter } from 'path/to/utils/vuex.js';
...
export default {
name: 'ComponentName',
computed: {
...mapSetter(
mapState({
result: ({ ITEMS }) => ITEMS.result,
total: ({ ITEMS }) => ITEMS.total,
current: ({ ITEMS }) => ITEMS.page,
limit: ({ ITEMS }) => ITEMS.limit,
}),
{
limit(payload) {
this.$store.dispatch({ type: TYPES.SET_LIMIT, payload });
},
},
)
},
}
Dans votre fichier component.vue
// in some utils/vuex.js file
export const mapSetter = (state, setters = {}) => (
Object.keys(state).reduce((acc, stateName) => {
acc[stateName] = {
get: state[stateName],
};
// check if setter exists
if (setters[stateName]) {
acc[stateName].set = setters[stateName];
}
return acc;
}, {})
);
la liaison v-model devrait maintenant fonctionner.
pourquoi vous n'avez pas fait
: value = "computedValue"&@ input = "setterFunction"dans votre composant?On dirait que vous pourriez créer une fonction d'assistance qui produirait des calculs réglables et l'utiliser comme si vous utilisiez
... mapState.