Last updated
Last updated
Мутации — это синхронные транзакции
Единственным способом изменения состояния хранилища во Vuex являются мутации. Мутации во Vuex очень похожи на события: каждая мутация имеет строковый тип и функцию-обработчик. В этом обработчике и происходят, собственно, изменения состояния, переданного в функцию первым аргументом:
Вызывать функцию-обработчик напрямую — нельзя. Это больше похоже на обработку события: "Когда мутация типа increment
инициирована, вызывается этот обработчик". Чтобы инициировать обработку мутации, необходимо вызвать store.commit
, указав её тип:
При вызове store.commit
в мутацию можно также передать дополнительный параметр, называемый нагрузкой (payload
):
В большинстве случаев нагрузка будет объектом, содержащим несколько полей. Запись мутаций в таком случае становится более описательной:
Другой способ вызвать мутацию — это передать в commit единственный параметр, в котором type
указан напрямую:
При использовании объектной записи, объект передаётся в качестве нагрузки целиком, так что обработчик остаётся тем же самым:
Поскольку состояние хранилища Vuex — это реактивная переменная Vue, при возникновении мутации зависящие от этого состояния компоненты Vue обновляются автоматически. Кроме того, это значит, что мутации Vuex имеют те же самые подводные камни, что и реактивность в обычном Vue:
Лучше инициализировать изначальное состояние хранилища, указав все поля в самом начале.
При добавлении новых свойств объекту необходимо либо:
Использовать Vue.set(obj, 'newProp', 123)
, или
Целиком заменить старый объект новым. Например, используя синтаксис расширения объектов можно написать так: state.obj = { ...stat.obj, newProp: 123 };
Можно вынесите все константы с типами мутаций и действий в отдельный файл, чтобы было проще использовать линтеры и другие инструменты, а также чтобы дать читателям возможность с первого взгляда понять, какие мутации возможны в приложении:
Теперь представьте, что вы отлаживаете приложение и смотрите в лог мутаций в инструментах разработчика. Для каждой залогированной мутации devtools должен сохранить слепки состояния приложения "до" и "после" её наступления. Однако, асинхронный коллбэк внутри приведённой выше мутации делает это невозможным: мутация-то уже записана, и у devtools нет никакой возможности знать, что далее будет вызван коллбэк, а, значит, и инициируемые им изменения становится, по сути дела, невозможно отследить.
Мутации можно вызывать из кода компонентов, используя this.$store.commit('xxx')
, или применяя вспомогательный метод mapMutations
, но регистрировать мутации нужно в methods который проксирует вызовы store.commit
через методы компонентов (для этого требуется наличие корневой ссылки на хранилище $store
):