首页 > 解决方案 > vuex中缓存数据的正确方法

问题描述

我正在尝试将数据异步加载到静态但由多个路由使用的 vuex 中。我只想获取一次数据,并且仅在访问需要它的路由时获取。这是我目前正在做的,但我不确定这是否是正确的约定,或者是否有更好/更 Vueish 的方式。

// store.js

export default new Vuex.Store({
  state: {
    _myData: null,
  },
  getters: {
    myData: (state) => new Promise((resolve,reject) => {
      if(state._myData){
        resolve(state._myData);
      } else {
        axios.get('http://myData.com/')
        .then(myData => {
          state._myData = myData;
          resolve(state._myData);
        });
      }
    })
  }
});

// ProfilePage.vue

<template>
 <div>{{myData}}</div>
</template>

<script>
export default {
  data() {
    return {
      myData:null
    }
  },
  async created(){
   this.myData = await this.$store.getters.myData;
  }
}
</script>

// AboutPage.vue

<template>
 <div>{{myData}}</div>
</template>

<script>
export default {
  data() {
    return {
      myData:null
    }
  },
  async created(){
   this.myData = await this.$store.getters.myData;
  }
}
</script>

标签: vue.jsvuejs2vuex

解决方案


有一种正确的方法可以做你想做的事,但这不是你正在做的事情。Vue 对“不要在突变处理程序之外改变 vuex 存储状态”非常严格。

这意味着您应该只通过突变更改存储状态,然后仅使用您的 getter 来获取数据。您还应该使用操作来提交突变。因此,对于您要尝试做的事情,您应该像这样尝试。

// AnyPage.vue

<template>
 <div>{{myData}}</div>
</template>

<script>
export default {
  data() {
    return {
      myData:null
    }
  },
  async created(){
    if(this.$store.state._myData === null) {
      await this.$store.dispatch('getData')
    }
    this.myData = this.$store.getters.myData;
  }
}
</script>

然后在你的商店:

// store.js

export default new Vuex.Store({
  state: {
    _myData: null,
  },
  getters: {
    myData: (state) => state._myData,
  }
  mutations: {
    SET_DATA(state, data) {
      state._myData = data
    }
  }
  actions: {
    getData({ context }){
        axios.get('http://myData.com/')
        .then(res => {
          context.commit('SET_DATA', res)
        })
      }
    }
  }
});

您应该阅读涵盖所有内容的文档。


推荐阅读