在vuex中缓存数据的正确方法

时间:2019-03-09 00:36:11

标签: vue.js vuejs2 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>

2 个答案:

答案 0 :(得分:3)

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

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

// 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)
        })
      }
    }
  }
});

您应该在docs中仔细阅读所有内容。

答案 1 :(得分:0)

  

动作处理程序会收到一个上下文对象,该对象在商店实例上公开了相同的方法/属性集,因此您可以调用context.commit进行更改,或通过<<>访问状态和获取方法strong> context.state 和context.getters。   https://vuex.vuejs.org/guide/actions.html

尝试一下:

// AnyPage.vue

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

<script>
export default {
  computed: {
    myData () {
      return this.$store.state.myData
    }
  },
  mounted () {
    this.$store.dispatch('getData')
  }
}
</script>

存储文件中:

// store.js

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