Kozack
@Kozack
Thinking about a11y

Как сделать геттер-функцию?

В хранилище vuex есть массив категорий и массив постов с id категории к которой он принадлежит:

{
  posts: [
    {id: 1, catId: 1, title: 'Foo'},
    //...
  ],
  categories: [
    {id: 1, title: 'CatFoo'}
  ]
}

По ходу приложения нужно получать массив постов для определённой категории. Как это сделать через vuex getter? Чтобы он кэшировал результат и не выполнял фильтр массива при каждом обращении.
  • Вопрос задан
  • 137 просмотров
Решения вопроса 1
Kozack
@Kozack Автор вопроса
Thinking about a11y
По итогу написал что-то такого:

getters: {
  getPostsByCategory(state) {
    const map = new Map();
    state.posts; // Необходимо чтобы геттер пересчитывался при изменении state.posts

    return (catId) => {
      if (map.has(catId)) {
        return map.get(catId);
      }

      let posts = state.posts.filter(p => p.catId === catId);
      map.set(catId, posts);


      return posts;
    };
  }
}


Как это работает:
Геттер возвращает не результат, но функцию. Эта функция фильтрует посты, и через замыкание кэширует результат. Если в любом другом компоненте потребуется список постов этой же категории — эни будут возвращены из кэша.

При изменении state.posts — этот внутренний кэш очищается и список постов будет сформирован заново
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
0xD34F
@0xD34F
Зачем функция? Делаем геттер, представляющий посты, сгруппированные по категориям:

getters: {
  postsByCatId: ({ posts }) =>
    posts.reduce((acc, n) => (
      (acc[n.catId] = acc[n.catId] || []).push(n),
      acc
    ), {}),
},

Соответственно, в компоненте добавляем свойство, представляющее id категории, и вычисляемое свойство, представляющее массив постов. Можно оформить миксин, если подобное нужно в разных компонентах:

const postsMixin = {
  data: () => ({
    catId: null,
  }),
  computed: {
    posts() {
      return this.$store.getters.postsByCatId[this.catId] || [];
    },
  },
};
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы