【问题标题】:How to separate AXIOS requests from a Vuex store如何从 Vuex 商店中分离 AXIOS 请求
【发布时间】:2018-09-13 08:13:13
【问题描述】:

我有一个非常普通的 Vuex 存储文件,代码如下:

//store.js
import Vue from 'vue';
import Vuex from 'vuex';


Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    loading: true,
    companyBasicInfo: [

    ]
  },
  mutations: {
    getCompanyBasicInfo: (state, res) => {
      state.companyBasicInfo.push(res);
    },
    changeLoadingStatue: (state, loading) => {
      state.loading = loading;
    }
  },
  actions: {
    getCompanyBasicInfo: context => {
// HERE IS MY AXIOS REQUESTS
    }
  }
});

我正在 getCompanyBasicInfo() 操作中编写我的 axios 请求,一切正常。

我想做什么

将我的 AXIOS 请求分离到另一个文件中,然后在我的 store.js 文件中调用它们,以减少我的 store.js 文件..

我尝试过的

我尝试创建名为 requests.js 的文件并在其中写入以下代码:

import axios from 'axios';

export default GET_COMPANY_DETAILS = () => {
  setTimeout(() => {
    axios.get('http://localhost:3000/companies/show/trade key egypt').then((res) => {
      context.commit('getCompanyBasicInfo', res.data);
      context.commit('changeLoadingStatue', false);
    }).catch(e => {
      console.log(e);
    });
  }, 3000);
};

然后尝试将它们导入我的 store.js 文件中

import requests from './requests';

问题

每当我尝试在getCompanyBasicInfo() 操作中写入requests.GET_COMPANY_DETAILS(); 时,我都无法访问requests.js 文件中的方法。

我得到错误

Uncaught ReferenceError: GET_COMPANY_DETAILS is not defined 在控制台中

【问题讨论】:

  • 你得到什么错误?
  • 我刚刚在axios-middlewareaxios-resource 上写了an answer 的示例,这有助于解决这个问题。
  • @Prashant 我已经编辑了我的问题
  • 为什么要将 axios 调用包装在 setTimeout 中?
  • @EmileBergeron 问题是我无法从我的文件中访问任何变量,不仅是 axios 请求函数

标签: javascript vue.js vuex


【解决方案1】:

导出问题

由于你使用的是export default GET_COMPANY_DETAILS,所以当你导入requests时,就是GET_COMPANY_DETAILS函数。

所以你可以直接拨打requests()

查看MDN documentation on export 了解所有可能性。

如何导出 API

话虽如此,导出 API 的正确方法是:

// api.js
import axios from 'axios';

// create an axios instance with default options
const http = axios.create({ baseURL: 'http://localhost:3000/' });

export default {
    getCompanyDetails(tradeKey) {
        // then return the promise of the axios instance
        return http.get(`companies/show/${tradeKey}`)
            .catch(e => {
                // catch errors here if you want
                console.log(e);
            });
    },
    anotherEndpoint() {
        return http.get('other/endpoint');
    }
};

您可以像我一样导出default API,甚至可以同时导出命名和默认导出。

export function getCompanyDetails(tradeKey){ /*...*/ }
export default { getCompanyDetails }

然后,在您的商店中:

import api from './api';

// ...

actions: {
    getCompanyBasicInfo({ commit }, key) {
        // It's important to return the Promise in the action as well
        return api.getCompanyDetails(key).then(({ data }) => {
            commit('getCompanyBasicInfo', data);
            commit('changeLoadingStatue', false);
        });
    }
}

商店相关的代码仍然需要在您的操作中。

进一步推动隔离

我在axios-middlewareaxios-resource 上写了an answer 的示例,这有助于创建单一职责模块。

您可以处理中间件中的错误,同时将端点配置集中在资源类中。

【讨论】:

  • 我得到同样的错误:Uncaught ReferenceError: GET_COMPANY_DETAILS is not defined
  • 感谢您的回答和宝贵的时间
  • @Dill 您确定 Prashant 的答案是您想要接受的答案吗?我已经介绍了一些模式细节,它可能对未来的访问者更有用。 (除了编辑问题的格式)
  • 其实这两个答案都对我有帮助
  • @Dill 是的,但 Prashant 的答案仍然有不正确的信息,例如在操作函数中缺少 return
【解决方案2】:

我建议你根据 Vuex 文档中建议的 application structure 来构建你的代码。

这将为您提供很好的关注点分离,并使您的 store.js 美观而精简。

然后,导出函数而不是默认导出。将来,您可能希望从requests.js 导出多个函数。

例如

import axios from 'axios';

export function getCompanyDetails() {
  setTimeout(() => {
    axios.get('http://localhost:3000/companies/show/trade key egypt').then((res) => {
      context.commit('getCompanyBasicInfo', res.data);
      context.commit('changeLoadingStatue', false);
    }).catch(e => {
      console.log(e);
    });
  }, 3000);
};

export function someOtherApiMethod() {}

然后,不要在GET_COMPANY_DETAILS 中使用setTimeout,而是从Axios 本身返回promise。

例如

 export function getCompanyDetails() {
    return axios
        .get('http://localhost:3000/companies/show/trade key egypt')
        .then(res => res.data)
};

然后,在你的行动中使用承诺

import { getCompanyDetails } from './requests';

actions: {
    getCompanyBasicInfo: context => {
        getCompanyDetails().then(() => {
            // commit your mutations
        });
    }
  }

【讨论】:

    猜你喜欢
    • 2019-03-23
    • 2020-07-12
    • 2018-01-14
    • 2020-06-19
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    相关资源
    最近更新 更多