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

3

我有一个以下的商店模块:

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

... or 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
            }
        })
    }
}

3
您只需简单地使用Computed,它会随着存储中的值发生更改而自动更新。 - niclas_4
2个回答

3

既然您已经了解了存储映射,我想您会尝试拥有某种编辑表单,在此表单中需要从数据库中获取实际数据并能够更改这些数据以便稍后将其发送回数据库。

您不需要一个getter来简单地引用存储项。在组件中,使用 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)的操作。

谢谢您的解释!现在问题是什么时候使用store.subscribe()?您能给我一个例子吗? - Axel
当你需要了解任何存储突变时,可以使用它。说实话,我从未使用过它。当许多存储项可能发生更改时,它可能会有所帮助,但我通常只将它们捆绑在单个对象中并进行监视。 - stas.yaranov
抓住了!谢谢。 - Axel

0

最好使用computed属性来访问存储数据并使其具有响应性。 可以使用mapGetters创建计算属性,就像在共享代码片段中所做的那样。但是,考虑到getter只是从状态返回user,我认为您根本不需要getter,您可以使用mapState助手从状态映射值。这样,组件将简化为以下内容:

import { mapState } from 'vuex'

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

使用上述方法,您可以在组件的方法中引用用户作为this.user,或者在组件模板中简单地引用user。此外,由于getter未使用,您可以从存储中删除getter定义(除非您在其他地方使用它)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接