我的 Vue.js Vuex 商店有 2 个发出 GET 请求的操作。第二个动作需要第一个动作的响应才能起作用。怎么做?

Posted

技术标签:

【中文标题】我的 Vue.js Vuex 商店有 2 个发出 GET 请求的操作。第二个动作需要第一个动作的响应才能起作用。怎么做?【英文标题】:My Vue.js Vuex store has 2 actions that make GET requests. The second action requires the response from the first one in order to work. How to do it? 【发布时间】:2020-04-16 19:25:47 【问题描述】:

我有 2 个操作发出 GET 请求并将响应保存在 Vuex 存储中。第一个操作getVersion() 获取游戏的最新版本,并且需要该版本才能发出第二个 GET 请求。现在我已经在第二个操作中对版本进行了硬编码,但是,我的目标是将它连接到 URL 中。

遗憾的是,我不确定如何从函数内部访问它。 Console.log(state.version) 出于某种原因返回 null,即使它不应该是。我从 App.vue 内部调用这些函数,如下所示:

mounted()
    this.$store.dispatch('getVersion')
    this.$store.dispatch('getChampions')

Vuex 商店

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store(
    state: 
        version: null,
        champions: null
    ,
    mutations: 
        version(state, data)
            state.version = data.version
        ,
        champions(state, data)
            state.champions = data.champions
        
    ,
    actions: 
        getVersion(commit)
            axios.get("http://ddragon.leagueoflegends.com/api/versions.json")
            .then((response) => 
                commit('version', 
                    version: response.data[0]
                )
            )
            .catch(function (error) 
                console.log(error);
            )
        ,
        getChampions(commit, state)
            axios.get("https://ddragon.leagueoflegends.com/cdn/9.24.1/data/en_US/champion.json")
            .then((response) => 
                commit('champions', 
                    champions: response.data.data
                )
            )
            .catch(function (error) 
                console.log(error);
            )
        
    ,
    getters: 
        version: (state) => 
            return state.version;
        ,
        findChampion: (state) => (id) => 
            let championId = id.toString();
            let champion = Object.values(state.champions).find(value => value.key === championId);

            return champion
        
    
)

【问题讨论】:

【参考方案1】:

这部分:

this.$store.dispatch('getVersion')
this.$store.dispatch('getChampions')

第二次调度不会等待第一次调度完成。这意味着它在第一个有机会完成获取版本之前触发。

您需要创建一个应在调用第二个 dispatch 之前解决的承诺。

你可以试试这样:

async mounted()
    await this.$store.dispatch('getVersion')
    await this.$store.dispatch('getChampions')

或者如果你不想使用async/await

this.$store.dispatch('getVersion').then(() =>  
    this.$store.dispatch('getChampions');
);

在操作中,您应该将return 添加到请求中(这很重要):

return axios.get(...

【讨论】:

我应该在哪个操作中将退货添加到请求中?第一、第二还是两者兼而有之? 两者都是很好的做法。但主要是这种情况下的第一个【参考方案2】:

调度程序返回一个承诺

    this.$store.dispatch('getVersion').then(()=> 
        this.$store.dispatch('getChampions');
    );

【讨论】:

以上是关于我的 Vue.js Vuex 商店有 2 个发出 GET 请求的操作。第二个动作需要第一个动作的响应才能起作用。怎么做?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Vuex 商店的 Vue.js 组件中设置动态样式

Vue.js / Vuex + axios 发送多个 PUT 请求

状态渲染前的 Vue.js/vuex getters 错误

是否有推荐的 Vue JS 应用程序 API 和 Vuex 设计模式

Vuex mapstate 对象未定义和“[vuex] 未知突变类型:”

Vue.js- Vuex 更新数组中的对象,内部状态未反映在组件 DOM 中