Это на самом деле не имеет ничего общего с Vuex, просто работает вызов функций JavaScript. Аргументы передаются по позиции, а не по имени.
У вас есть REMOVE_TODO: (state, id) => {
, но имена state
и id
действительно важны только внутри функции. За пределами функции, с точки зрения вызывающего, эти имена не имеют значения. С таким же успехом это может быть REMOVE_TODO: (a, b) => {
.
Когда Vuex вызывает мутацию, он передает объект state
в качестве первого аргумента и payload
в качестве второго аргумента. Фактически это звонит:
mutations.REMOVE_TODO(state, payload)
Я повторяю, что имена аргументов на самом деле не имеют значения, только их позиции.
Это внутреннее внутри Vuex, а не то, над чем у вас есть прямой контроль. Если бы вы вызывали функцию самостоятельно, вы могли бы передавать все, что хотите, но это не так (и не должны). Вместо этого вы (совершенно правильно) звоните commit
. Вы передаете желаемый payload
на commit
, а Vuex сделает все остальное, вызвав соответствующую мутацию и передав ей state
и payload
.
Определение функции как REMOVE_TODO: (id) => {
вместо этого не изменит аргументы, переданные вызывающей стороной. Первым аргументом все равно будет объект state
. Вы назвали его id
, но это не имеет значения, это все равно будет объект state
.
В общем, проблема с попыткой отбросить первый аргумент заключается в том, что все остальные аргументы эффективно перемешиваются, поэтому позиции имен желаемых аргументов больше не соответствуют позициям передаваемых аргументов. Нет такой проблемы с отбрасыванием аргумента с конца, так как другие аргументы не перемещают позиции. Так что если вам нужен state
, но не payload
, тогда вы можете просто оставить второй аргумент без проблем. Разработчики API всегда стараются довести до конца необязательные аргументы, чтобы их можно было отбрасывать, не вызывая проблем.
Для мутации payload
очень легко может быть ненужным, но state
всегда необходим. Весь смысл мутации в том, чтобы изменить state
. Если вы не меняете state
, вам не следует использовать мутацию.
Как отмечено в вашем коде, actions
являются асинхронными, тогда как mutations
должны быть синхронными. Но это не то, что у вас есть. В настоящее время у вас много асинхронных вызовов Firebase внутри ваших мутаций. Все это нужно перенести в actions
. Обратите внимание, что Обещания всегда асинхронны, поэтому, если вы обнаружите, что вызываете then
внутри мутации, вы делаете это неправильно. Единственная часть этого, которая должна быть внутри mutations
, это когда вы модифицируете state
.
Вам также следует избегать использования this
в магазине Vuex. Вы должны обнаружить, что все, что вам нужно, доступно из аргументов, переданных функции. В настоящее время у вас есть this.errors = error
и подобные мутации. Я предполагаю, что это должно быть state.errors = error
.
Обновление:
В соответствии с просьбой в комментариях:
SET_TODO (state, todos) {
state.todos = todos
}
setTodo ({commit}) {
db.collection('items').orderBy('created_at').onSnapshot(snapshot => {
const todos = []
snapshot.forEach(doc => {
todos.push({ id: doc.id, title: doc.data().title })
})
commit('SET_TODO', todos)
})
}
Обратите внимание, что здесь не предпринимается попыток справиться с возможными условиями гонки.