In my Vue application I have a view for editing a record. From that component I'm (1) calling a vuex action to persist the record to database and (2) calling $router.push()
to navigate back to the overview view. The vuex action will persist the record using AJAX and then push (replace or append) the returned record to the overview list in the store. The problem is that the changes do not show up in the overview view until I do some manual navigation.
vuex/store.js:
import Vue from 'vue'
import Vuex from 'vuex'
import $ from 'jquery'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
records: [],
activeRecord: {}
},
mutations: {
pushRecord: function(state, record) {
var added = false;
for (var i = 0; i < state.records.length; i++) {
if (state.records[i]._id == record._id) {
state.records[i] = record;
added = true;
break;
}
}
if (!added) {
state.records.push(record);
}
}
},
actions: {
saveRecord({ commit, state }) {
$.ajax({
type: "POST",
url: "http://127.0.0.1:8080/record",
data: JSON.stringify(state.activeRecord),
dataType: "json",
contentType: "application/json"
}).done(function(data) {
commit("pushRecord", data)
});
}
}
})
RecordDetail.vue (notice subsequent dispatch and navigation):
export default {
name: "record-detail",
computed: {
record() {
return this.$store.state.activeRecord
}
},
methods: {
save: function() {
this.$store.dispatch("saveRecord")
this.$router.push({ path: '/records' })
}
}
}
In the mutation, instead of doing:
state.records[i] = record;
try following:
Vue.set(state.records, i, Object.assign({}, record))
Why:
Due to limitations in JavaScript, Vue can't detect when you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
You can do one of following to overcome this:
state.records.splice(i, 1, record)
or
Vue.set(state.records, i, Object.assign({}, record))