Шаблон проектирования Vue для редактирования элемента из магазина VueX в компоненте - PullRequest
0 голосов
/ 05 мая 2019

Я пытаюсь выяснить, какой шаблон / код дизайна является самым чистым для локального редактирования одного элемента магазина в компоненте 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} ;
            }
        }
    }

Как я могу улучшить этот код? Это лучшие практики?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...