Comment appeler un getter depuis un autre getter dans Vuex?

105

Considérez un simple blog Vue:
j'utilise Vuex comme magasin de données et je dois configurer deux getters : un getPostgetter pour récupérer un postpar ID, ainsi qu'un listFeaturedPostsqui renvoie les premiers caractères de chaque article présenté. Le schéma du magasin de données pour la liste des articles en vedette fait référence aux articles par leur ID. Ces identifiants doivent être résolus en messages réels afin d'afficher les extraits.

store / state.js

export const state = {
  featuredPosts: [2, 0],
  posts: [
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
  ]
}

store / getters.js

export default getPost = (state) => (postID) => {
  return state.posts[postID]
}

export default listFeaturedPosts = (state, getters) => () => {
  console.log(getters) // {}

  return state.featuredPosts.map(postID => getters.getPost(postID).substring(0, EXCERPT_LENGTH);
}

store / index.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import * as getters from './getters'
import * as mutations from './mutations'

Vue.use(Vuex)

export default new Vuex.Store({
  state,
  getters,
  mutations
})

Selon la documentation, le gettersparamètre peut être utilisé pour accéder à d'autres getters. Cependant, lorsque j'essaie d'accéder gettersde l'intérieur listFeaturedPosts, il est vide et j'obtiens une erreur dans la console car il getters.getPostn'est pas défini dans ce contexte.

Comment appeler en getPosttant que getter Vuex de l'intérieur listFeaturedPostsdans l'exemple ci-dessus?

Utilisateur non trouvé
la source

Réponses:

18

Passez getterscomme deuxième argument pour accéder aux getters locaux et sans espace de nom. Pour les modules d'espacement de noms, vous devez utiliser rootGetters(comme 4ème argument, afin d'accéder aux getters définis dans un autre module):

export default foo = (state, getters, rootState, rootGetters) => {
    return getters.yourGetter === rootGetters['moduleName/getterName']
}
ego
la source
3
Ceci est utile pour les personnes nécessitant un getter d'un autre module vuex. Je voulais juste souligner que les arguments doivent être dans l'ordre spécifique indiqué dans la réponse sans aucun argument omis, pour que cela fonctionne.
LJH
13

J'ai testé sans stateet n'a pas fonctionné. C'est pourquoi statec'est nécessaire.

cela marche:

export default foo = (state, getters) => {
    return getters.yourGetter
}

cela n'a pas fonctionné

export default foo = (getters) => {
    return getters.yourGetter
}
José Seie
la source
1
Je voudrais ajouter que cela ne fonctionne dans aucune version de Vue. La déstructuration d'objet ne doit pas être confondue avec des arguments nommés (voir la réponse dans la suggestion originale d'omettre «état»). C'est en effet (état, getters)
Igor Zinken
2
Dans le deuxième exemple, vous nommez l' stateobjet getterset ignorez le deuxième argument qui serait l' gettersobjet réel . Si vous deviez introspecter gettersdans cet exemple, vous verriez qu'il s'agissait en fait de votre objet d'état.
mraaroncruz le
10

Les getters reçoivent d'autres getters comme deuxième argument

getters: {
  doneTodos: state => {
    return state.todos.filter(todo => todo.done)
  },
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}

Voici un lien vers la documentation officielle - https://vuex.vuejs.org/guide/getters.html#property-style-access

OziOcb
la source
2
Bravo pour: a) un exemple de code clair b) un lien vers le bon endroit dans la documentation
Katinka Hesselink
1
Est-ce différent d'écrire comme ça à la place? getters: {doneTodos: state => {return state.todos.filter (todo => todo.done)}, doneTodosCount: (state, getters) => {return this.getters.doneTodos.length}}
Rivo
@Rivo pour autant que je sache, vous ne pouvez pas faire ça. Si vous essayez, vous obtiendrez une erreur comme celle-ci: [Vue warn]: Erreur de rendu: "TypeError: Impossible de lire la propriété 'getters' de undefined"
OziOcb
-3

au lieu de passer l' état , passez les getters puis appelez tout autre getter de votre choix. J'espère que cela aide.

Dans votre magasin / getters.js

export default foo = (getters) => {
   return  getters.anyGetterYouWant
}
Angie
la source
2
Je pense que vous confondez la déstructuration d'objets avec des arguments. Le premier argument de la fonction est l'état, le second est l'objet Getters. Vous pouvez nommer le premier argument «getters», mais ce sera toujours l'état! Vous recherchez: export default foo = (state, getters) => ...
Igor Zinken
Ouexport default foo = ({ getters }) => { return getters.anyGetterYouWant }
GaryMcM