首页 > 解决方案 > Vue + Vuex 异步使用 axios 但 getter 返回空数组

问题描述

我的问题是返回初始状态([])的吸气剂。

在我的组件中,我有一个created将 axios 调用结果设置为状态的方法。

created() {this.$store.dispatch("SET_STORIES");},

我有 mapGetters 计算:

  computed: {
    ...mapGetters(["GET_STORIES"])
  },

还有一种获取状态的方法:

  methods: {
    stories() {
      return this.$store.getters.GET_STORIES;
    }
  }

mounted()正在返回一个空数组:

  mounted() {
    console.log("stories", this.$store.getters.GET_STORIES);
  },

store.js

import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
import VueAxios from "vue-axios";
import chunk from "lodash/chunk";
Vue.use(Vuex, VueAxios, axios);

export default new Vuex.Store({
  state: {
    stories: [],
    twoChunkStories: []
  },
  getters: {
    GET_STORIES: state => {
      return state.stories;
    }
  },
  mutations: {
    SET_STORIES(state, stories) {
      state.stories = stories;
    },
    SET_CHUNKED_STORIES(state, stories) {
      state.twoChunkStories= stories;
    },
  },
  actions: {
    SET_STORIES: async ({ commit }) => {
      const options = {
        headers: {
          "Content-Type": "application/json"
        }
      };
      let { data } = await axios.get(
        "https://api.example.com/get.json",
        options
      );
      if (data.meta.code === 200) {
        let storiesArray = data.data.stories;
        let chunkSize = 2;
        commit("SET_STORIES", storiesArray);
        let chunkedArray = chunk(storiesArray, chunkSize);
        commit("SET_CHUNKED_STORIES", chunkedArray);
      }
    }
  }
});

如何进行 axios 异步调用,该调用将在最早的生命周期钩子(我认为created()是最早的钩子)上设置 onload 状态并准备好在挂载时调用。我显然在 getter 上异步做错了什么,我只是不知道到底是什么。

标签: javascriptvue.js

解决方案


您没有在组件中调用SET_STORIES的操作方法,因此商店中的故事不会更新,首先您需要从 Vue 组件中调用操作,例如

mounted() {
 this.$store.actions.SET_STORIES
}

另外,我认为您需要在这里使用不同的逻辑,因为您不知道从服务器获取故事数据需要多长时间。

在您的组件中,您可以创建一个名为isDataLoaded的变量并最初将其设为 false。在您的组件中,您可以有条件地呈现您的列表,例如


<div v-if="!isDataLoaded">
  Loading ...
</div>

<div v-if="isDataLoaded">
  ... your list goes here ...
</div>

在您的mounted()方法中,您需要在这样的操作调用之后更新isDataLoaded,以便您的列表将显示在屏幕中

async mounted() {
 await this.$store.actions.SET_STORIES
 this.isDataLoaded = true
}


推荐阅读