Как стать автором
Обновить

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

Время на прочтение3 мин
Количество просмотров36K


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


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


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


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


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


const store = new Vuex.Store({
    state: {
        // список книг
        books: [
            { id: 1, title: '...', finished: true },
            { 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)
        }
    }
}

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


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

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


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

Теги:
Хабы:
Всего голосов 20: ↑19 и ↓1+18
Комментарии21

Публикации

Истории

Работа

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн