Несколько простых, но полезных советов по работе с геттерами в Vuex

?v=1

Vuex предоставляет удобные инструменты для работы с данными, но некоторые разработчики используют их не всегда по назначению, либо создают избыточные конструкции там, где можно было написать более понятно и ёмко, такое также случается, когда разработчик только знакомится с данными инструментами. В данной статье будут приведены некоторые рекомендации по организации геттеров (Getters), которые вы сможете применить в работе.

Геттеры являются частью хранилища Vuex, вычисляемыми свойствами, если точнее. Они позволяют получать например отфильтрованные по какому-либо параметру данные. Но некоторые разработчики понимают название этого инструмента буквально и начинают использовать это, как замену получения данных напрямую из state. Отсюда вытекает первая ошибка использования геттеров.


Использование геттеров для простого получения данных из хранилища

Давайте разберем простой пример кода:

state: {
  films: [
    { id: 1, name: 'Джеймс Бонд' },
    { id: 2, name: 'Гарри Поттер' },
    { id: 3, name: 'Автострада 60' },
  ],
},
getters: {
  films: state => state.films,
},

Такое использование геттеров встречается достаточно часто и это плохо. Для доступа к состоянию в вашем компоненте достаточно сделать вычисляемое значение в computed, например:

computed: {
  films() {
    return this.$store.state.films;
  },
},

Либо еще более удобный вариант с использованием mapState:

computed: {
  ...mapState(['films']),
},

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

ИМХО: многие миксуют использовние mapState и создание вычисляемых значений, возвращающих состояние. Для создания единообразного кода используйте mapState и остальные инструменты даже для одного значения, так как ваш код станет более единообразным и в него можно будет вносить изменения гораздо быстрее и добнее, к примеру если придется вывести еще одно знанчение.


Создавать геттер для единственного случая использования фильтра

Предположим, что вам нужно получить фильм про Джеймса Бонда, для какого-то специфического случае, возможно вам захочется сделать так:

getters: {
  bondFilm: (state) => {
    const [film = {}] = state.films
      .filter(f => f.name === 'Джеймс Бонд');
    return film;
  },
},

Не нужно так поступать, лучше снова обратиться к mapState и сделать следующим образом:

computed: {
  ...mapState({
    bondFilm: (state) => {
    const [film = {}] = state.films
      .filter(f => f.name === 'Джеймс Бонд');
    return film;
  },
  }),
},

По сути вы просто переносите специфический фильтр в ваш компонент, где он необходим, пример весьма абстрактный, но я часто встречал его на практике.


Создавать геттеры с параметрами

Даннный способ работы с геттерами весьма удобен и часто встречается, но нельзя забывать, что геттеры являются вычисляемыми свойствами и кэшируются. Это не значит, что использовать это нельзя вовсе, но лучше лишний раз подумайте, нельзя ли иначе. Взгляните на пример:

getters: {
  filmById: (state) => (id) => {
    const [film = {}] = state.films
      .filter(f => f.id === id);
    return film;
  },
},

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

getters: {
  filmsById: state => state.films
    .reduce((result, film) => ({
      ...result,
      [film.id]: film,
    }), {}),
},

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


Подведем небольшой итог


  • Не используйте геттеры для простого получения данных, не нужно усложнять свой код обертками для простых операций
  • Не создавайте геттреры для специфических фильтров, которые будет необходимы только однажды, основная идея геттеров — это получение производных состояний, но не нужно переносить логику компонента в логику хранилища
  • Параметризированные геттеры теряют своё основное свойство — кэшируемость, подумайте несколько раз, прежде чем пользоваться ими таким способом
  • Пользуйтесь всеми преимуществами mapState, помните, что большую часть специфических задач для компонента можно выполнить с его помощью
  • Используйте mapGetters, об этом было сказано косвенно, но единообразие лучше, чем его отсутствие

Данная статья написана для начинающихся и запутавшихся разработчиков, если вы еще не открывали документацию по Vue и Vuex, а первым делом пошли смотреть информацию по вопросу на хабре, то перейдите по ссылкам выше и начните читать с них, используйте советы из различных источников после этого.

© Habrahabr.ru