#vue.js #vuex
#vue.js #vuex
Вопрос:
У меня есть хранилище Vuex, которое управляет массивом ( state.all
), и у меня есть кнопка, которая вызывает действие Vuex, которое выполняет HTTP-вызов, а затем добавляет данные в ответ на state.all
путем изменения. Однако состояние никогда не обновляется, и компоненты никогда не обновляются.
Чтобы доказать, что я не сумасшедший, я использовал два alert()
s внутри мутации, чтобы убедиться, что я знаю, где я нахожусь в коде. alert()
s всегда запускались с правильными значениями.
Вот усеченное хранилище Vuex (это модуль):
const state = {
all: []
}
// actions
const actions = {
...
runner ({ commit, rootState }, { did, tn }) {
HTTP.post(url, payload)
.then(function (response) {
commit('setNewConversations', response.data)
})
})
}
}
const mutations = {
...
setNewConversations(state, new_conv) {
for (let new_c_i in new_conv) {
let new_c = new_conv[new_c_i]
alert(new_c) // I always see this, and it has the correct value
if (!(new_c in state.all)) {
alert('I ALWAYS SEE THIS!') // testing
state.all.push(new_c)
}
}
}
...
}
Когда я захожу, чтобы протестировать это, я вижу свои два alert()
параметра, первый со значением, которое я ожидаю, а второй со значением «Я ВСЕГДА ВИЖУ ЭТО!», но с моим v-for
компонентом ничего не происходит, и состояние никогда не обновляется, несмотря на state.all.push()
.
Каков следующий шаг к устранению этой проблемы? В консоли JS нет ошибок, и я не могу понять, по какой причине состояние не будет обновлено.
Спасибо!
Комментарии:
1. Вы уверены, что это не обновляет хранилище? Может быть, по какой-то причине представление просто не обновляется?
2. Теперь, когда я удаляю свой
alert()
, он внезапно начинает работать. Теперь это проблема, которая возникает только изредка. Что я мог бы сделать, чтобы выяснить, почему это происходит?3. У вас
vue devtools
установлено расширение / плагин / что угодно в вашем браузере, это отличный способ отслеживать состояние вашего vuex
Ответ №1:
Одно из возможных решений — вместо перехода к текущему значению состояния сохранить предыдущее значение state.all
в новом массиве и внести новые изменения в этот новый массив.
После завершения присвойте этому новому массиву state.all
, как показано ниже.
setNewConversations(state, new_conv) {
const prevState = [...state.all];
for (let new_c_i in new_conv) {
let new_c = new_conv[new_c_i]
if (!(new_c in prevState)) {
prevState.push(new_c);
}
}
state.all = prevState;
}
Комментарии:
1. С какой стати мне использовать
const
в этой конкретной ситуации?2. @David почему бы и нет? Вы можете помещать данные в массив const, вы знаете
3. @downvoter, я действительно не возражаю против понижения, но я был бы признателен, если бы вы оставили комментарий / причину понижения, чтобы я мог также учиться и не повторять ту же ошибку в следующий раз. @David, вы можете изменить объявленный массив
const
, если вы не переназначаете его.4. @AnaLizaPandac не уверен, почему вы были отклонены, кто-то, должно быть, не понимает vue / javascript, потому что это действительно правильный ответ
Ответ №2:
Учитывая, что вы сказали, что удаление предупреждения заставляет его работать, я задаюсь вопросом, не наблюдаете ли вы значение в неправильном месте. Я не могу быть уверен в том, что вы указали.
Помните, что Javascript является однопоточным, и ваша мутация должна завершиться, прежде чем сможет выполняться любой другой код реактивности, введенный Vue.
Если вы действительно хотели, чтобы значение отображалось до завершения мутации, вы, вероятно, могли бы вызвать Vue.nextTick(() => alert(...))
, но лучший ответ — проверить наличие обновлений где-нибудь в другом месте, например, в вычисляемом, который вызывает средство получения состояния.весь массив.
(Кстати, я обнаружил, что использование любого из них console.log(...)
или vue-dev-tools намного быстрее, чем alert()
для произвольной отладки.)