¿Cómo llamo a un getter de otro getter en Vuex?

105

Considere un simple Vue blog:
Estoy usando Vuex como mi almacén de datos y necesito configurar dos captadores : un getPostcaptador para recuperar una postpor ID, así como listFeaturedPostsque los rendimientos de los primeros caracteres de cada puesto ofrecido. El esquema del almacén de datos para la lista de publicaciones destacadas hace referencia a las publicaciones por sus ID. Estas identificaciones deben resolverse en publicaciones reales con el fin de mostrar los extractos.

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
})

Según la documentación, el gettersparámetro se puede utilizar para acceder a otros captadores. Sin embargo, cuando intento acceder gettersdesde adentro listFeaturedPosts, está vacío y aparece un error en la consola debido a getters.getPostque no está definido en ese contexto.

¿Cómo llamo getPostcomo getter de Vuex desde adentro listFeaturedPostsen el ejemplo anterior?

Usuario no encontrado
fuente

Respuestas:

18

Pasa getterscomo segundo argumento para acceder a captadores locales y sin espacio de nombres. Para los módulos con espacio de nombres, debe usar rootGetters(como cuarto argumento, para acceder a los captadores definidos dentro de otro módulo):

export default foo = (state, getters, rootState, rootGetters) => {
    return getters.yourGetter === rootGetters['moduleName/getterName']
}
ego
fuente
3
Esto es útil para las personas que requieren un getter de otro módulo vuex. Solo quería enfatizar que los argumentos deben estar en el orden específico que se muestra en la respuesta sin omitir argumentos, para que funcione.
LJH
13

Probé sin statey no funcionó. Por eso statees necesario.

esto funciona:

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

esto no funcionó

export default foo = (getters) => {
    return getters.yourGetter
}
José Seie
fuente
1
Me gustaría agregar que no funciona en ninguna versión de Vue. La desestructuración de objetos no debe confundirse con argumentos con nombre (consulte la respuesta en la sugerencia original para omitir 'estado'). De hecho lo es (estado, captadores)
Igor Zinken
2
En el segundo ejemplo, está nombrando el stateobjeto getterse ignorando el segundo argumento, que sería el gettersobjeto real . Si gettershiciera una introspección en este ejemplo, vería que en realidad era su objeto de estado.
mraaroncruz
10

Los getters reciben otros getters como segundo argumento

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

Aquí hay un enlace a los documentos oficiales: https://vuex.vuejs.org/guide/getters.html#property-style-access

OziOcb
fuente
2
Aprobado por: a) un ejemplo de código claro b) enlace al lugar adecuado en los documentos
Katinka Hesselink
1
¿Es diferente escribir así? getters: {doneTodos: state => {return state.todos.filter (todo => todo.done)}, doneTodosCount: (state, getters) => {return this.getters.doneTodos.length}}
Rivo
@Rivo, que yo sepa, no puedes hacer eso. Si lo intentas, obtendrás un error como este: [Vue warn]: Error en el renderizado: "TypeError: No se puede leer la propiedad 'getters' de undefined"
OziOcb
-3

en lugar de pasar del estado , pasar captadores y luego llamar a cualquier otro comprador desea. Espero eso ayude.

En tu tienda / getters.js

export default foo = (getters) => {
   return  getters.anyGetterYouWant
}
Angie
fuente
2
Creo que estás confundiendo la desestructuración de objetos con argumentos. El primer argumento de la función es el estado, el segundo es el objeto getters. Puede nombrar el primer argumento 'getters', ¡pero seguirá siendo el estado! Estás buscando: export default foo = (state, getters) => ...
Igor Zinken
Oexport default foo = ({ getters }) => { return getters.anyGetterYouWant }
GaryMcM