vue3的axios请求封装

该文介绍了如何创建一个API文件夹,包含index.js、request.js和interface.js。在request.js中,利用axios和element-plus库设置了请求和响应拦截器,处理如携带token、错误提示等功能。interface.js则定义了HTTP接口,包括GET、POST、PUT和DELETE方法,用于与服务器交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建api文件夹

1、在api文件夹创建index.js
export * from './interface';
2、在api文件夹创建request.js
import axios from 'axios';
import { ElMessage } from 'element-plus';

let _global = typeof self === "undefined" ? typeof global === "undefined" ? this : global : self;
let typeOfTest = type => thing => typeof thing === type;
let isUndefined = typeOfTest('undefined');
let isContextDefined = (context) => !isUndefined(context) && context !== _global;
let { isArray } = Array;
function isPlainObject(val){
  	return val && val.constructor.name === 'Object'
}
function merge() {
	let {caseless} = isContextDefined(this) && this || {};
	let result = {};
	let assignValue = (val, key) => {
		let targetKey = caseless && findKey(result, key) || key;
		if (isPlainObject(result[targetKey]) && isPlainObject(val)) {
			result[targetKey] = merge(result[targetKey], val);
		} else if (isPlainObject(val)) {
			result[targetKey] = merge({}, val);
		} else if (isArray(val)) {
			result[targetKey] = val.slice();
		} else {
			result[targetKey] = val;
		}
	}
	for (let i = 0, l = arguments.length; i < l; i++) {
	  	arguments[i] && forEach(arguments[i], assignValue);
	}
	return result;
}
function forEach(obj, fn, {allOwnKeys = false} = {}) {
	if (obj === null || typeof obj === 'undefined') {
	  	return;
	}
	let i;
	let l;
	if (typeof obj !== 'object') {
	  	obj = [obj];
	}
	if (isArray(obj)) {
		for (i = 0, l = obj.length; i < l; i++) {
			fn.call(null, obj[i], i, obj);
		}
	} else {
		let keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
		let len = keys.length;
		let key;
		for (i = 0; i < len; i++) {
			key = keys[i];
			fn.call(null, obj[key], key, obj);
		}
	}
}

let statusText = {
	0: "请求状态为0,请求超时",
	400: "请求状态为400,服务器未能理解请求",
	404: "请求状态为404,服务器无法找到被请求的页面",
	405: "请求状态为405,请求中指定的方法不被允许",
	500: "请求状态为500,服务器遇到不可预知的情况",
	502: "请求状态为502,服务器从上游服务器收到一个无效的响应",
}
//请求拦截
let requestInterceptors = [
	cfg => {
		//携带token
		cfg.headers.Authorization = sessionStorage.getItem("token");
		//表单提交
		if(cfg.emulateJSON && isPlainObject(cfg.data)) {
			cfg.data = buildURL('', cfg.data).substr(1);
		}
		return cfg;
	}
]
//响应拦截
let responseInterceptors = [
	res => {
		return res.data;
	},
	err => {
		if(err.response){
			ElMessage.error(statusText[err.response.status]);
		}else{
			ElMessage.error(statusText[err.request.status]);
		}
		return Promise.reject(err)
	}
]
let defaults = {
	baseURL: process.env.VUE_APP_REQUEST_BASEURL,
	disableInterceptor: true,
	timeout: 5 * 60 * 1000, //请求时间,单位为毫秒,设置5分钟
}
export let serviceCreate = config => {
	let service = axios.create(merge(defaults, config));
	service.interceptors.request.use(...requestInterceptors);
	service.interceptors.response.use(...responseInterceptors);
	return service;
}
export { merge };
export let service = serviceCreate();
3、在api文件夹创建interface.js
import { serviceCreate, merge } from './request';

let http = serviceCreate({
    baseURL: process.env.NODE_ENV === 'production' ? "生产/正式环境" : "开发/本地环境",
})

//get类型(示例)
export function get(params, config) {
    return http.get('/get/getList', merge(config,{ params }));
}
//post类型(示例)
export function post(data, config) {
    return http.post('/post/postList', data, merge(config, { emulateJSON: false }));
}
//put类型(示例)
export function put(data, config) {
    return http.put('/put/putList', data, merge(config, { emulateJSON: false }));
}
//delete类型(示例)
export function del(params, config) {
    return http.delete('/del/delList', merge(config,{ params }));
}
### Vue3Axios 请求封装的最佳实践 #### 创建 Axios 实例并配置默认选项 为了提高代码的可维护性和复用性,通常会创建一个独立的文件来初始化和配置 Axios 实例。这一步骤可以集中管理所有的 HTTP 配置。 ```javascript // src/utils/axios.js import axios from &#39;axios&#39;; const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 设置基础URL timeout: 5000 // 超时时间 (毫秒) }); ``` #### 添加请求拦截器 在发送请求之前可以通过请求拦截器对请求做预处理,比如添加认证令牌或修改请求头信息: ```javascript service.interceptors.request.use( config => { const token = localStorage.getItem(&#39;token&#39;); if (token) { config.headers[&#39;Authorization&#39;] = `Bearer ${token}`; } return config; }, error => Promise.reject(error) ); ``` #### 添加响应拦截器 当接收到服务器端返回的数据后,可以在响应拦截器中统一处理错误逻辑或其他通用操作: ```javascript service.interceptors.response.use( response => response.data, error => { console.error(`Error occurred during API call:`, error.message); return Promise.reject(error); } )[^1]; ``` #### 定义API服务层 为了让业务逻辑更加清晰分离,建议定义专门的服务模块导出具体的 API 函数供页面调用: ```javascript // src/api/user.js import request from &#39;@/utils/axios&#39;; export function login(data) { return request.post(&#39;/auth/login&#39;, data); } export function getUserInfo() { return request.get(&#39;/user/profile&#39;); } ``` #### 使用 getCurrentInstance 获取组件实例 考虑到 Vue 3 组合式 API 的特性,在 setup 函数内部不再能直接访问 this 关键字指向的上下文对象。此时应该借助 Composition API 提供的方法来获取当前组件实例的相关属性和服务[^2]。 ```javascript <script> import { ref } from &#39;vue&#39;; import { useRoute, useRouter } from &#39;vue-router&#39;; import { login } from &#39;../api/user&#39;; import { getCurrentInstance } from "vue"; export default { name: &#39;LoginView&#39;, setup() { let loading = ref(false); const instance = getCurrentInstance(); async function handleLogin(form) { try { loading.value = true; await login({ username: form.username, password: form.password }); router.push(&#39;/&#39;); } catch (err) { alert(err?.message || &#39;登录失败!&#39;); } finally { loading.value = false; } } return { handleLogin }; } }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值