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

als*_*9xd 1 vue.js vuex 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>
Run Code Online (Sandbox Code Playgroud)

And*_*325 5

有正确的方法来做您想做的事情,但并非您正在做的事情。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>
Run Code Online (Sandbox Code Playgroud)

然后在您的商店中:

// 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)
        })
      }
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

您应该在涵盖所有内容的文档中仔细阅读。

  • 你的例子中有吸气剂的理由吗?我不能直接访问状态变量吗? (2认同)
  • @ als9xd上面的示例基本上不需要一个示例,但是使用getters是最佳的实践,如果需要计算存储状态(例如运行过滤器功能),则必不可少。这是一个好习惯。 (2认同)

Mar*_*dim 5

操作处理程序接收一个上下文对象,该对象在存储实例上公开相同的方法/属性集,因此您可以调用 context.commit 来提交突变,或通过context.state和 context.getters访问状态和 getter 。 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>
Run Code Online (Sandbox Code Playgroud)

存储文件中:

// 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)
            })
        }
      }
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 嗨,这里我使用了计算属性,希望使变量具有反应性 (4认同)