如何将 AXIOS 请求与 Vuex 存储区分开
How to separate AXIOS requests from a Vuex store
我有一个非常正常的 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
在控制台中
导出问题
由于您使用的是 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);
});
}
}
商店相关代码仍然需要在您的操作中。
进一步隔离
我写了 an answer with examples on axios-middleware and axios-resource 来帮助创建单一责任模块。
您可以在中间件中处理错误,同时将端点配置集中在资源中 类。
我建议您根据 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
,return 来自 Axios 本身的承诺。
例如
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
});
}
}
我有一个非常正常的 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
在控制台中
导出问题
由于您使用的是 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);
});
}
}
商店相关代码仍然需要在您的操作中。
进一步隔离
我写了 an answer with examples on axios-middleware and axios-resource 来帮助创建单一责任模块。
您可以在中间件中处理错误,同时将端点配置集中在资源中 类。
我建议您根据 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
,return 来自 Axios 本身的承诺。
例如
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
});
}
}