Хабрахабр

[Из песочницы] Vuex — чрезмерное использование геттеров в приложении. Разбор ошибки

Мы поговорим о геттерах (getters) и как их правильно использовать. В этой статье пойдет речь об распространенной ошибке, которую делают большинство начинающих при разработке приложения на Vue + Vuex. Также мы рассмотрим вспомогательные функции mapState и mapGetters.

Примечания перед прочтением: рекомендуется иметь базовые знания Vue и Vuex.

Глава 1. Что такое геттеры. Пример нецелесообразного использования

Геттеры — это часть хранилища Vuex, которые возвращают вычисляемые данные текущего состояния хранилища нашим компонентам.

Рассмотрим пример:

const store = new Vuex.Store(, { id: 2, title: '...', finished: false } ] }, getters: { // возвращаем список всех книг books: state => state.books }
});

Так будет выглядеть компонент со списком всех книг:

export default { computed: { // наш геттер books() { return this.$store.getters.books } }
}

Этим подходом мы перегружаем приложение. Пример выше работает, но так делать не стоит.

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

Глава 2. Использование mapState для получения данных из хранилища

Документация гласит:

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

Давайте вернемся к нашему компоненту и используем mapState вместо геттера:

import { mapState } from 'vuex'; export default { computed: { ...mapState([ 'books' ]) }
}

мы в нем больше не нуждаемся: Геттер из хранилища можно удалить, т.к.

const store = new Vuex.Store({ state: { // список книг books: [ { id: 1, title: '...', finished: true }, { id: 2, title: '...', finished: false } ] }
});

Мы избавились от ненужных геттеров и сократили количество кода. Намного удобнее, не так ли?

Глава 3. Зачем же нужны геттеры, если есть mapState

Геттеры используются в тех случаях, когда нужно вывести модифицированную информацию из хранилища (например список всех прочитанных книг). И все таки они нужны.

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

const store = new Vuex.Store({ state: { // список книг books: [ { id: 1, title: '...', finished: true }, { id: 2, title: '...', finished: false } ] }, getters: { // возвращаем список прочитанных книг finishedBooks: state => { return state.books.filter(books => books.finished); } }
});

Теперь наш компонент будет выглядеть так:

import { mapState } from 'vuex'; export default { computed: { // получаем список всех книг ...mapState([ 'books' ]), // получаем список прочитанных книг finishedBooks() { return this.$store.getters.finishedBooks } }
}

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

Давайте рассмотрим пример:

// не забываем про импорт
import { mapState, mapGetters } from 'vuex'; export default { computed: { // получаем список всех книг ...mapState([ 'books' ]), // получаем список геттеров, или в // нашем случае список всех прочитанных книг ...mapGetters([ 'finishedBooks' ]) }
}

Улучшение налицо: использовав mapGetters мы сократили количество кода.

Этого можно добиться передав аргумент нашему геттеру. Вы так же можете вычислить информацию из хранилища основываясь на каких-то данных, например достать книгу по её id или названию.

const store = new Vuex.Store({ state: { // список книг books: [ { id: 1, title: '...', finished: true }, { id: 2, title: '...', finished: false } ] }, getters: { // возвращаем список прочитанных книг finishedBooks: state => { return state.books.filter(books => books.finished); }, // возвращаем книгу по id getBookById: (state) => (id) => { return state.books.find(books => books.id === id) } }
});

import { mapState, mapGetters } from 'vuex'; export default { computed: { ...mapState([ 'books' ]), ...mapGetters([ 'finishedBooks', 'getBookById' ]), getBook() { // получаем книгу с id === this.id return this.getBookById(this.id) } }
}

Закрепление материала

  • Вы можете использовать геттеры в своих действиях (actions) vuex или непосредственно в компонентах.
  • Результаты геттера обновляются при изменении одной из зависимостей.
  • Геттерам можно передавать дополнительные аргументы, чтобы проводить вычисления данных на их основе.
  • Используйте геттеры только для вычисления нетривиальных данных, которые требуются в нескольких компонентах, в иных случаях используйте вспомогательную функцию mapState.

Документация по геттерам на русском

Пример приложения из статьи на codepen

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть