Я пытаюсь выяснить, какой шаблон / код дизайна является самым чистым для локального редактирования одного элемента магазина в компоненте vue без обновления его исходной версии из магазина.
Исходная версия из магазина должна быть обновлена, как только пользователь подтвердит изменения в компоненте.
Элементы в магазине уже могут быть заполнены, если пользователь зашел на страницу со списком элементов, но они также могут быть пустыми, если они поступили непосредственно на страницу с одним элементом (из закладки или прямой ссылки).
Вот мое рабочее решение, но оно мне не нравится, потому что:
- Компонент vue определяет вычисляемое свойство, которое требуется только для наблюдателя
- Этот дизайн может привести к тому, что пользователь потеряет свои изменения, если что-то асинхронное обновит магазин (из-за наблюдателя).
Магазин
export default {
namespaced: true,
state: {
items: [],
},
mutations: {
updateItems(state, items) {
state.items = payload;
},
updateItem(state, item) {
//replaces the corresponding item of state.items by the new one
},
},
actions: {
fetchAll({commit, state}) {
axios.get('/item').then(response => {
commit('updateItems', response.data);
}).catch(error => {
//...
});
},
fetchSingle({commit, state}, itemId) {
if(/*already in state.items*/){
return ;
}
axios.get('/item/' + itemId).then(response => {
commit('updateItem', response.data);
}).catch(error => {
//...
});
},
saveItem({commit,state},item){
//async call to the backend, calls a state mutator on success
}
},
getters: {
item: (state) => (id) => state.items[id]
}
}
Компонентный
export default {
data() {
return {
//this one is edited via the form in the UI
item: {}
}
},
computed : {
//not used, only for the watch
dummyItem: function() {
return this.$store.getters['items/item'](this.$route.params.itemId);
}
},
watch: { // watch changes here
dummyItem: function(newValue, oldValue) {
//Copy the data from the store
this.item= {...newValue} ;
}
},
methods: {
submitForm() {
//dispatch action to the store saveItem with this.item
}
},
mounted() {
let itemId = this.$route.params.itemId ;
let item = this.$store.getters['items/item'](itemId) ;
if(!item ){
this.$store.dispatch('items/fetchSingle',itemId) ;
//the watcher will update this.item when the item is loaded from the backend
} else {
//Shallow copy from the store
this.item= {...item} ;
}
}
}
Как я могу улучшить этот код? Это лучшие практики?