- PVSM.RU - https://www.pvsm.ru -
Vuex [1] предоставляет удобные инструменты для работы с данными, но некоторые разработчики используют их не всегда по назначению, либо создают избыточные конструкции там, где можно было написать более понятно и ёмко, такое также случается, когда разработчик только знакомится с данными инструментами. В данной статье будут приведены некоторые рекомендации по организации геттеров (Getters [2]), которые вы сможете применить в работе.
Геттеры являются частью хранилища Vuex, вычисляемыми свойствами, если точнее. Они позволяют получать например отфильтрованные по какому-либо параметру данные. Но некоторые разработчики понимают название этого инструмента буквально и начинают использовать это, как замену получения данных напрямую из state [3]. Отсюда вытекает первая ошибка использования геттеров.
Давайте разберем простой пример кода:
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: {
filmById: state => state.films
.reduce((result, user) => ({
...result,
[film.id]: film,
}), {}),
},
В данном случае повторное вычисление произойдет только в случае изменения данных, а вы сможете обращаться к id, как к ключам объекта.
Данная статья написана для начинающихся и запутавшихся разработчиков, если вы еще не открывали документацию по Vue [4] и Vuex [1], а первым делом пошли смотреть информацию по вопросу на хабре, то перейдите по ссылкам выше и начните читать с них, используйте советы из различных источников после этого.
Автор: Максим Вишневский
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/323081
Ссылки в тексте:
[1] Vuex: https://vuex.vuejs.org/ru/guide/
[2] Getters: https://vuex.vuejs.org/ru/guide/getters.html
[3] state: https://vuex.vuejs.org/ru/guide/state.html
[4] Vue: https://ru.vuejs.org/v2/guide/
[5] Источник: https://habr.com/ru/post/459034/?utm_source=habrahabr&utm_medium=rss&utm_campaign=459034
Нажмите здесь для печати.