如何将AXIOS请求从Vuex Store中分离?附现有Store代码示例
嘿,这事儿我太熟了!把Axios请求从Vuex的actions里抽离出来,不仅能让代码结构更清爽,还能让API逻辑复用性拉满,我给你几个落地的具体方案:
方案1:创建独立的API服务模块(最常用)
这是中小型项目的首选方案——把API请求单独放到专门的文件里,和Vuex彻底解耦。
首先,新建一个api/company.js文件,专门存放公司相关的API请求:
// api/company.js import axios from 'axios'; // 先配置一个axios实例,统一处理baseURL、超时、请求头这些 const apiClient = axios.create({ baseURL: 'https://your-api-domain.com', // 替换成你的API域名 timeout: 10000, }); // 定义获取公司基础信息的请求方法 export const getCompanyBasicInfoAPI = async () => { try { const response = await apiClient.get('/company/basic-info'); return response.data; } catch (error) { // 统一处理错误,抛出后让Vuex的action来处理后续逻辑 throw new Error(error.response?.data?.message || '获取公司信息失败'); } };
然后修改你的Vuex Store文件,引入这个API方法:
// store.js import Vue from 'vue'; import Vuex from 'vuex'; import { getCompanyBasicInfoAPI } from './api/company'; // 引入API方法 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: { async getCompanyBasicInfo({ commit }) { commit('changeLoadingStatue', true); try { const data = await getCompanyBasicInfoAPI(); // 调用抽离后的API commit('getCompanyBasicInfo', data); } catch (error) { console.error(error.message); // 这里可以加错误处理的mutation,比如更新全局错误状态 } finally { commit('changeLoadingStatue', false); } } } });
这个方案的好处很明显:API逻辑集中管理,多个组件或Vuex action都能复用,还能在axios实例里统一配置请求拦截器(比如加token)、响应拦截器(比如统一处理401过期)。
方案2:用类封装API(适合大型项目)
如果你的项目API请求特别多,用类来封装同一领域的API会更清晰,维护起来也方便。
新建api/CompanyAPI.js文件:
// api/CompanyAPI.js import axios from 'axios'; class CompanyAPI { constructor() { // 初始化axios实例 this.client = axios.create({ baseURL: 'https://your-api-domain.com', timeout: 10000, }); // 统一添加请求拦截器,比如自动携带token this.client.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); } // 获取公司基础信息 async getBasicInfo() { const response = await this.client.get('/company/basic-info'); return response.data; } // 还可以扩展其他公司相关API,比如更新信息 async updateBasicInfo(info) { const response = await this.client.put('/company/basic-info', info); return response.data; } } // 导出单例实例,避免重复创建 export default new CompanyAPI();
然后在Vuex里使用:
// store.js import Vue from 'vue'; import Vuex from 'vuex'; import CompanyAPI from './api/CompanyAPI'; Vue.use(Vuex); export const store = new Vuex.Store({ // state和mutations保持不变 actions: { async getCompanyBasicInfo({ commit }) { commit('changeLoadingStatue', true); try { const data = await CompanyAPI.getBasicInfo(); commit('getCompanyBasicInfo', data); } catch (error) { console.error('获取公司信息失败:', error); } finally { commit('changeLoadingStatue', false); } } } });
这种方式适合大型项目,把同一业务领域的API都封装在一个类里,结构清晰,还能利用类的特性做一些统一逻辑处理。
额外小建议
- 可以在API模块里统一处理错误提示(比如用Element的Message组件弹出错误),这样Vuex里就不用重复写提示逻辑了;
- 如果有全局的axios配置(比如baseURL、超时),可以单独建一个
api/config.js文件,然后在各个API模块里引入; - 对于需要参数的请求,直接在API方法里接收参数即可,比如
getCompanyBasicInfoAPI(companyId)。
内容的提问来源于stack exchange,提问作者Dill
相关产品推荐
相关产品推荐

