Как мне вызвать геттер из другого геттера в Vuex?

105

Рассмотрим простой Вью блог:
Я использую Vuex как мой датасторе и мне нужно создать два добытчиками : а getPostпоглотитель для извлечения postпо идентификатору, а также , listFeaturedPostsчто возвращает несколько первых символов каждого признакам пост. Схема хранилища данных для списка избранных сообщений ссылается на сообщения по их идентификаторам. Эти идентификаторы необходимо преобразовать в фактические сообщения для отображения отрывков.

магазин / 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',
  ]
}

магазин / 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);
}

магазин / 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
})

Согласно документации, gettersпараметр может использоваться для доступа к другим геттерам. Однако, когда я пытаюсь получить доступ gettersизнутри listFeaturedPosts, он пуст, и я получаю сообщение об ошибке в консоли из-за getters.getPostтого, что он не определен в этом контексте.

Как мне вызвать getPostгеттер Vuex изнутри listFeaturedPostsв примере выше?

Пользователь не найден
источник

Ответы:

18

Передайте gettersв качестве второго аргумента для доступа к локальным и не имеющим пространств имен геттерам. Для модулей с пространством имен вы должны использовать rootGetters(в качестве 4-го аргумента для доступа к геттерам, определенным в другом модуле):

export default foo = (state, getters, rootState, rootGetters) => {
    return getters.yourGetter === rootGetters['moduleName/getterName']
}
эго
источник
3
Это полезно для людей, которым требуется получатель из другого модуля vuex. Я просто хотел подчеркнуть, что аргументы должны быть в определенном порядке, указанном в ответе, без пропуска аргументов, чтобы он работал.
LJH
13

Я тестировал без него stateи не работал. Поэтомуstate необходимо.

это работает:

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

это не сработало

export default foo = (getters) => {
    return getters.yourGetter
}
Jose Seie
источник
1
Хочу добавить, что он не работает ни в одной версии Vue. Деструктуризацию объекта не следует путать с именованными аргументами (см. Ответ в исходном предложении об опускании «состояния»). Это действительно (состояние, получатели)
Игорь Зинкен
2
Во втором примере вы называете stateобъект gettersи игнорируете второй аргумент, который будет фактическим gettersобъектом. Если бы вы gettersв этом примере занялись самоанализом , вы бы увидели, что это на самом деле ваш объект состояния.
mraaroncruz
10

Геттеры получают другие геттеры в качестве второго аргумента

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

Вот ссылка на официальные документы - https://vuex.vuejs.org/guide/getters.html#property-style-access

OziOcb
источник
2
Поднимите палец вверх за: а) четкий пример кода б) ссылку на нужное место в документации
Катинка Хесселинк
1
Разве вместо этого писать так? геттеры: {doneTodos: state => {return state.todos.filter (todo => todo.done)}, doneTodosCount: (state, getters) => {return this.getters.doneTodos.length}}
Риво,
@Rivo, насколько я знаю, ты не можешь этого сделать. Если вы попробуете, то получите такую ​​ошибку: [Предупреждение Vue]: Ошибка при рендеринге: «TypeError: Невозможно прочесть свойство 'getters' of undefined»
OziOcb
-3

вместо передачи состояния передайте геттеры, а затем вызовите любой другой получатель, который хотите. Надеюсь, это поможет.

В вашем магазине / getters.js

export default foo = (getters) => {
   return  getters.anyGetterYouWant
}
Энджи
источник
2
Я думаю, вы путаете деструктуризацию объектов с аргументами. Первый аргумент функции - это состояние, второй - объект получения. Вы можете назвать первый аргумент «геттерами», но он все равно будет состоянием! Вы ищете: export default foo = (state, getters) => ...
Игорь Зинкен
Илиexport default foo = ({ getters }) => { return getters.anyGetterYouWant }
GaryMcM