【问题标题】:Vue + Vuex using axios asynchrnously yet getters return empty arrayVue + Vuex 异步使用 axios 但 getter 返回空数组
【发布时间】:2019-08-21 18:54:26
【问题描述】:

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

在我的组件中,我有一个 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 异步调用,在最早的生命周期钩子上设置 onload 状态(我认为 created() 是最早的钩子)并准备好在挂载时调用。我显然在 getter 上异步做错了什么,我只是不知道到底是什么。

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    您没有在组件中调用 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
    }
    
    

    【讨论】:

    • this.$store.dispatch("SET_STORIES"); 用于调用(调度)一个动作。
    • 我确实发送了它,我在问题中写了它:created() { this.$store.dispatch("SET_STORIES"); },
    • 此外,您正在对挂载进行异步调用,如果服务器端出现问题,这将使整个应用程序挂起。但我必须补充一点,它确实解决了异步问题,但我不确定mounted 是不是正确的地方..
    • 哦,对不起,我没有意识到你一开始就发送了它,我打错了它不应该是 this.$store.actions,而是 this.$store.dispatch :) @Daniel .实际上,当我查看文档时,创建的方法更好用
    • 如果我的帖子确实解决了您的问题,您可以将其标记为已解决 :)
    猜你喜欢
    • 1970-01-01
    • 2021-01-24
    • 2021-09-30
    • 2021-05-04
    • 1970-01-01
    • 2019-05-15
    • 2019-05-08
    • 1970-01-01
    • 2020-08-23
    相关资源
    最近更新 更多