Vue3+TypeScript组合式API中如何全局配置Axios?
Vue3组合式API+TypeScript全局配置Axios的问题与解决方案
问题重现
尝试provide/inject配置Axios失败
先通过插件形式封装Axios并提供给应用:
plugins/axios.ts:
import axios from 'axios' import type { AxiosInstance } from 'axios' import type { App } from 'vue' export default { install: (app: App, baseUrl: string) => { const axiosInstance: AxiosInstance = axios.create({ baseURL: baseUrl }) axiosInstance.defaults.headers.post['Content-Type'] = 'application/json' app.provide('axios', axiosInstance) } }
plugins/index.ts:
import router from '@/router' import { createPinia } from 'pinia' import { axios } from '@/plugins/axios' import type { App } from 'vue' export function registerPlugins(app: App) { const pinia = createPinia() app.use(pinia).use(router) axios.install(app, 'http://localhost:4000') }
main.ts:
import App from '@/App.vue' import { createApp } from 'vue' import { registerPlugins } from '@/plugins' const app = createApp(App) registerPlugins(app) app.mount('#app')
尝试在Pinia Store中注入使用:stores/someStore.ts:
import { inject } from 'vue' import type { AxiosInstance } from 'axios' import { defineStore } from 'pinia' export const useSomeStore = defineStore('SomeStore', () => { const axios = inject<AxiosInstance>('axios') const getSomeWidgets = async () => { return await axios.get('/widgets') } return { getSomeWidgets } })
运行后触发警告:
[Vue warn]: injection "axios" not found.
调用getSomeWidgets方法时会抛出undefined错误。
尝试globalProperties配置Axios受阻
修改plugins/axios.ts,将Axios实例挂载到全局属性:
app.config.globalProperties.$axios = axiosInstance
但组合式API环境中无法通过this访问全局属性:
// 因`this`未定义无法编译 return await this.$axios.get('/widgets')
解决方案
1. 创建独立Axios实例模块
在plugins目录下新建axiosHttp.ts,直接创建并导出配置好的Axios实例:
import axios from 'axios' const axiosInstance = axios.create({ baseURL: `${import.meta.env.VITE_API_HOST}:${import.meta.env.VITE_API_PORT}`, headers: { 'Content-Type': 'application/json' } }) // 可在此添加请求/响应拦截器、超时设置等自定义配置 export default axiosInstance
2. 封装API调用的Pinia Store
在stores目录下新建apiStore.ts,统一封装API调用逻辑(以GraphQL为例):
import { defineStore } from 'pinia' import axiosHttp from '@/plugins/axiosHttp' export const useApiStore = defineStore('ApiStore', () => { const query = async (name: string, parameters: Record<string, any>, resultSelector: string) => { const response = await axiosHttp.post('', { query: `{ ${name}( ${Object.entries(parameters) .map(([key, value]) => `${key}: ${JSON.stringify(value)}`) .join(', ')}) { ${resultSelector} } }` }) return response.data.data[name] } return { query } })
3. 在业务Store中复用API Store
业务Store(如widgetStore.ts)中直接引入并使用封装好的API Store:
import { defineStore } from 'pinia' import { useApiStore } from '@/stores/apiStore' export const useWidgetStore = defineStore('WidgetStore', () => { const apiStore = useApiStore() // 可在此定义业务状态、getter等 async function getWidgets(categoryId: number) { return await apiStore.query('widgets', { category: categoryId }, `id, name, creationTime`) } return { getWidgets } })
内容的提问来源于stack exchange,提问作者AJ.
相关产品推荐
相关产品推荐

