在Vue中保存异步数据的最佳方法是什么?

时间:2019-01-16 07:20:54

标签: javascript vue.js vuejs2 async-await vuex

我有以下商店模块:

const state = {
    user: {}
}

const mutations = {
    saveData(state, payload) {
        state.user = payload
    }
}

const actions = {
    async loadData({ commit }, payload) {
        try {
            const res = await axios.get('https://api.example.com/user/1')
            commit('saveData', res.data.data)
        } catch(e) {
            console.log(e)
        }
    } 
}

const getters = {
    getData(state) {
        return state.user
    } 
}

现在将数据保存在组件中的最佳方法是什么?是否使用watch

import { mapGetters } from 'vuex'

export default {
    data() {
        return {
            user: {}
        }
    },
    computed: {
        ...mapGetters({
            getData
        })
    },
    watch: {
        '$store.state.users.users'() {
            this.user = this.getData
        }
    }
}

...还是store.subscribe?

import { mapGetters } from 'vuex'

export default {
    data() {
        return {
            user: {}
        }
    },
    computed: {
        ...mapGetters({
            getData
        })
    },
    created() {
        this.$store.subscribe((mutation, state) => {
            if(mutation.type === 'saveData') {
                this.user = this.getData
            }
        })
    }
}

2 个答案:

答案 0 :(得分:2)

由于您已经了解商店映射,所以我想您尝试使用某种编辑形式,在其中您需要从数据库中获取实际数据,并且还具有更改此数据以便稍后将其发送回数据库的功能。

您不需要吸气剂即可简单地引用商店商品。在组件中使用mapState会很好:

{
  computed: {
    ...mapState({
      user: state => state.user,
    }),
  }
}

因此,一旦商店中的user发生了变化,您的组件就会知道这一点。在这里,您可以更新正在编辑的对象。让我们将其重命名为edit以避免冲突:

{
  data() {
    return {
      edit: {},
    }
  },

  computed: {
    ...mapState({
      user: state => state.user,
    }),
  },

  watch: {
    user: {
      immediate: true,
      handler(user) {
        this.edit = { ...user }
      },
    },
  },
}

现在edit也会进行相应的更新,即使在更新商店商品后挂载了组件(感谢immediate选项),您也可以在组件中安全地对其进行修改,而不会影响商店参考。

P.S。必须提及的是,在此实现中,如果您希望对edit对象中的字段具有反应性,则需要像这样对每个edit对象进行字段更新,以更新整个this.edit = {...this.edit, [prop]: value}对象。但是,如果您希望它是自然的Vue方式,那么首先需要使用实际的对象结构初始化edit,然后在user的观察程序中执行类似Object.assign(this.edit, user)的操作。

答案 1 :(得分:0)

最好使用computed属性来访问存储数据并保持其反应性。 可以像在共享快照中一样使用mapGetters创建计算属性,但是考虑到getter只是从状态返回user,我认为您根本不需要getter ,您只需使用mapState助手即可从状态映射值。这样,该组件将简化为如下所示:

import { mapState } from 'vuex'

export default {
    computed: {
        ...mapState([
            'user'
        ])
    }
}

使用上述方法,您可以在组件的方法中将用户引用为this.user,或者在组件的模板中将用户引用为user。另外,由于该吸气剂已停用,因此您可以从商店中删除该吸气剂定义(除非您在其他任何地方使用它)。

相关问题