axios 是一个基于 Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生 XHR 的封装,只不过它是 Promise 的实现版本,符合最新的 ES 规范,有以下特点:
pnpm install axios
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EAMzKPU7-1677467923225)(…/img/axios.png)]
service
文件夹下创建 index.js
文件import axios from "axios";
import { ElLoading, ElMessage } from "element-plus";
import router from "@/router";
// request是一个axios实例,每一个实例你都可以单独定制它的baseURL,超时时间,请求头和一些其他配置项。
const baseUrl = import.meta.env.VITE_BASE_URL; //接口统一域名
const service = axios.create({
baseURL: baseUrl,
timeout: 60 * 1000, //设置超时
headers: {
"Content-Type": "application/json;charset=UTF-8;",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
".AspNetCore.Culture": "c=zh-Hans|uic=zh-Hans",
},
});
let loading;
//正在请求的数量
let requestCount = 0;
//显示loading
const showLoading = () => {
if (requestCount === 0) {
loading = ElLoading.service({
fullscreen: true,
text: "Loading ",
background: "rgba(0, 0, 0, 0.7)",
});
}
requestCount++;
};
//隐藏loading
const hideLoading = () => {
requestCount--;
if (requestCount == 0) {
loading.close();
}
};
//请求拦截器
instance.interceptors.request.use(
(config) => {
showLoading();
// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
//若请求方式为post,则将data参数转为JSON字符串
if (config.method === "POST") {
config.data = JSON.stringify(config.data);
}
return config;
},
(error) =>
// 对请求错误做些什么
Promise.reject(error)
);
//响应拦截器
instance.interceptors.response.use(
(response) => {
hideLoading();
if (response.data.code == 402) {
ElMessage.error(response.data.msg);
router.push("/");
}
//响应成功
// console.log('拦截器报错');
else return response.data;
},
(error) => {
hideLoading();
//响应错误
let message = "";
if (error.response && error.response.status) {
const status = error.response.status;
switch (status) {
case 400:
message = "请求错误";
break;
case 401:
message = "请求错误";
break;
case 404:
message = "请求地址出错";
break;
case 408:
message = "请求超时";
break;
case 500:
message = "服务器内部错误!";
break;
case 501:
message = "服务未实现!";
break;
case 502:
message = "网关错误!";
break;
case 503:
message = "服务不可用!";
break;
case 504:
message = "网关超时!";
break;
case 505:
message = "HTTP版本不受支持";
break;
default:
message = "请求失败";
}
ElMessage.error(message);
return Promise.reject(error);
}
return Promise.reject(error);
}
);
export default instance;
request.js
文件import instance from "./index";
/**
* @param {String} method 请求的方法:get、post、delete、put
* @param {String} url 请求的url:
* @param {Object} data 请求的参数
* @param {Object} config 请求的配置
* @returns {Promise} 返回一个promise对象,其实就相当于axios请求数据的返回值
*/
export const request = ({ method, url, data, config }) => {
//把大写转换成小写
method = method.toLowerCase();
if (method == "post") {
return instance.post(url, data, { ...config });
} else if (method == "get") {
return instance.get(url, {
params: data,
...config,
});
} else if (method == "delete") {
return instance.delete(url, {
params: data,
...config,
});
} else if (method == "put") {
return instance.put(url, data, { ...config });
} else {
console.error("未知的method" + method);
return false;
}
};
index.js
写请求接口import { request } from "@/service/request";
export const getLogin = (data) => {
return request({
url: "/login",
method: "get",
data,
config: {
timeout: 10000,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
},
});
};
login.vue
文件使用//导入方法
import { getLogin } from "@/api/index";
//根据需求可以通过data传入参数
getLogin(data)
.then((res) => {
console.log(res, "请求数据");
})
.catch((rej) => {
console.log(rej, "报错信息");
});
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
export default defineConfig({
base: "/",
plugins: [vue()], //注册插件
server: {
https: false, // 是否开启 https
open: true, // 是否自动在浏览器打开
port: 3000, // 端口号
hmr: true, //开启热更新
host: "0.0.0.0",
proxy: {
"/api": {
target: `http://127.0.0.1`, // 后台接口
changeOrigin: true,
secure: false, // 如果是https接口,需要配置这个参数
// ws: true, //websocket支持
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
resolve: {
//通过配置alias来定义路径的别名
alias: {
"@": path.resolve(__dirname, "src"),
},
},
build: {
outDir: "dist", // 指定输出路径
assetsDir: "assets", // 指定生成静态资源的存放路径
minify: "terser", // 混淆器,terser构建后文件体积更小
sourcemap: false, //是否构建source map 文件
terserOptions: {
compress: {
drop_console: true, // 生产环境移除console
drop_debugger: true, // 生产环境移除debugger
},
},
},
});
开发环境和生产环境一般是 2 套 url,开发环境一般不会给你线上地址去调式的也就是接口地址(baserurl)是不一样的。这个时候就要配环境变量了。新建 2 个文件,一个env.development
文件,一个.env.production
文件。
.env.development
文件为开发环境NODE_ENV = "development";
VUE_APP_MODE = "development";
VUE_APP_BASE_URL = "url";
.env.production
文件为生产环境NODE_ENV = "production";
VUE_APP_MODE = "production";
VUE_APP_BASE_URL = "url";