Vue设计模式,用于编辑组件中VueX存储中的项目

时间:2019-05-05 20:18:04

标签: vue.js vuex

我试图找出最干净的设计模式/代码来实现对vue组件中一个商店商品的本地编辑,而无需从商店中更新其原始版本。 一旦用户验证了组件中的更改,就必须更新商店中的原始版本。

如果用户浏览到“商品列表”页面,商店中的商品可能已经被填充,但是如果直接到达单个商品页面(通过书签或直接链接),则商店中的商品也可能为空。 / p>

这是我的工作解决方案,但我不喜欢它,因为:

  • 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} ;
            }
        }
    }

如何改进此代码?他们是一些最佳实践吗?

0 个答案:

没有答案