Jak wywołać getter z innego gettera w Vuex?

113

Rozważmy prosty blog Vue:
używam Vuex jako mojego magazynu danych i muszę skonfigurować dwa gettery : getPostpobierający do pobierania postwedług identyfikatora oraz listFeaturedPostszwracający kilka pierwszych znaków każdego polecanego postu. Schemat magazynu danych dla listy polecanych postów odwołuje się do postów według ich identyfikatorów. Te identyfikatory muszą być zamienione na rzeczywiste posty w celu pokazania fragmentów.

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

Zgodnie z dokumentacją za pomocą tego gettersparametru można uzyskać dostęp do innych metod pobierających. Jednak kiedy próbuję uzyskać dostęp gettersod wewnątrz listFeaturedPosts, jest pusta i pojawia się błąd w konsoli z powodu getters.getPostniezdefiniowania w tym kontekście.

Jak wywołać getPostfunkcję pobierającą Vuex od wewnątrz listFeaturedPostsw powyższym przykładzie?

Użytkownik nie znaleziony
źródło

Odpowiedzi:

19

Przekaż gettersjako drugi argument, aby uzyskać dostęp do metod pobierających lokalnych i bez przestrzeni nazw. W przypadku modułów z przestrzenią nazw należy użyć rootGetters(jako czwartego argumentu, aby uzyskać dostęp do metod pobierających zdefiniowanych w innym module):

export default foo = (state, getters, rootState, rootGetters) => {
    return getters.yourGetter === rootGetters['moduleName/getterName']
}
ego
źródło
4
Jest to przydatne dla osób wymagających gettera z innego modułu vuex. Chciałem tylko podkreślić, że argumenty muszą być w określonej kolejności pokazanej w odpowiedzi bez pominiętych argumentów, aby zadziałało.
LJH
14

Testowałem bez statei nie działało. Dlatego jest stateto konieczne.

to działa:

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

to nie zadziałało

export default foo = (getters) => {
    return getters.yourGetter
}
Jose Seie
źródło
1
Dodam, że nie działa w żadnej wersji Vue. Destrukcji obiektu nie należy mylić z nazwanymi argumentami (patrz odpowiedź w oryginalnej sugestii, aby pominąć „stan”). To rzeczywiście (stan, getters)
Igor Zinken
2
W drugim przykładzie nazywasz stateobiekt gettersi ignorujesz drugi argument, który byłby rzeczywistym gettersobiektem. Gdybyś miał przeprowadzić introspekcję gettersw tym przykładzie, zobaczyłbyś, że faktycznie był to twój obiekt stanu.
mraaroncruz
12

Metody pobierające otrzymują inne metody pobierające jako drugi argument

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

Oto link do oficjalnej dokumentacji - https://vuex.vuejs.org/guide/getters.html#property-style-access

OziOcb
źródło
2
Kciuki w górę za: a) przykład przejrzystego kodu b) link do odpowiedniego miejsca w dokumentach
Katinka Hesselink
1
Czy zamiast tego pisać w ten sposób? getters: {doneTodos: state => {return state.todos.filter (todo => todo.done)}, doneTodosCount: (state, getters) => {return this.getters.doneTodos.length}}
Rivo
@Rivo, o ile wiem, nie możesz tego zrobić. Jeśli spróbujesz, pojawi się następujący błąd: [Vue warn]: Error in render: "TypeError: Cannot read property 'getters' of undefined"
OziOcb
-3

zamiast przekazywać stan , przekaż getters, a następnie wywołaj dowolny inny getter. Mam nadzieję, że to pomoże.

W Twoim sklepie / getters.js

export default foo = (getters) => {
   return  getters.anyGetterYouWant
}
Angie
źródło
2
Myślę, że mylisz niszczenie obiektów z argumentami. Pierwszym argumentem funkcji jest stan, a drugim obiekt pobierający. Możesz nazwać pierwszy argument „pobierający”, ale nadal będzie to stan! Szukasz: export default foo = (state, getters) => ...
Igor Zinken
Lubexport default foo = ({ getters }) => { return getters.anyGetterYouWant }
GaryMcM