Http.js
import Vue from "vue";
import axios from "axios";
import router from "@/router/router";
// import qs from "querystring";
import { getSession, Ddebounce, removeSession } from "@/utils/utils.js";
// loading对象
let loading = null;
// 当前正在请求的数量
let needLoadingRequestCount = 0;
// 显示loading
function showLoading() {
if (needLoadingRequestCount === 0 && !loading) {
loading = Vue.prototype.$loading({
lock: true,
text: "请求中,请稍等...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)"
});
}
needLoadingRequestCount++;
}
// 隐藏loading
function hideLoading() {
needLoadingRequestCount--;
needLoadingRequestCount = Math.max(needLoadingRequestCount, 0);
if (needLoadingRequestCount === 0) {
toHideLoading();
}
}
let toHideLoading = Ddebounce(() => {
loading && loading.close();
loading = null;
}, 500, false);
const service = axios.create({
baseURL: "http://xxx.com", // 默认的地址
timeout: 30000, // 请求超时时间
headers: {},
});
// 请求拦截器
service.interceptors.request.use(
config => {
config.headers = Object.assign(config.headers, { "ADMIN-TOKEN": getSession('token') || "" })
// 判断当前请求是否设置了不显示 Loading
if (config.headers.showLoading !== false) {
showLoading(config.headers.loadingTarget);
}
// 返回图片流方式处理
if (config.url.includes("/login/captcha")) {
config.responseType = "arraybuffer"
}
if (config.method.toLocaleLowerCase() === "get" || config.method.toLocaleLowerCase() === "delete") {
config.params = config.data;
}
return config;
},
error => {
// 判断当前请求是否设置了不显示 Loading
if (error.config.headers.showLoading !== false) {
hideLoading();
}
return Promise.reject(error);
}
);
// 返回拦截器
service.interceptors.response.use(
config => {
// 判断当前请求是否设置了不显示 Loading
if (config.headers.showLoading !== false) {
hideLoading();
}
// 签名过期情况处理
if (config.data.code === 10100) {
removeSession("token");
router.push("/login");
}
return config;
},
error => {
// 判断当前请求是否设置了不显示 Loading
if (error.config.headers.showLoading !== false) {
hideLoading();
}
return Promise.reject(error);
}
);
// 挂载请求
Vue.prototype.$axios = service;
// 请求统一处理
function requst(options) {
return new Promise((resolve, reject) => {
options
.then(res => {
// 返回图片流方式处理
if (res.config.url.includes("/login/captcha")) {
resolve('data:image/png;base64,' + btoa(new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), '')))
} else {
if (res.data?.code == 0) {
resolve(res.data);
} else {
reject(res.data.msg || res.data.Msg || "加载数据超时,请稍后重试");
}
}
})
.catch(error => {
if (error.message.includes(`timeout of ${error.config.timeout}ms exceeded`)) {
reject("加载数据超时,请稍后重试");
} else {
reject(error);
}
});
});
}
// get.post.put.del.patch请求方法提取
const get = (url, params, showLoading = true) => {
return requst(service.get(url, { data: params }, { headers: { showLoading } }));
};
const post = (url, params, showLoading = true) => {
return requst(service.post(url, params, { headers: { showLoading } }));
};
const put = (url, params, showLoading = true) => {
return requst(service.put(url, params, { headers: { showLoading } }));
};
const del = (url, params, showLoading = true) => {
return requst(
service.delete(url, { data: params }, { headers: { showLoading } })
);
};
const patch = (url, params, showLoading = true) => {
return requst(service.patch(url, { data: params }, { headers: { showLoading } }));
};
export default requst;
export { get, post, put, del, patch };
Login.Request.js
// 根据模块封装
import { get, post } from "../Http";
export default {
/**
* @method 获取登录图像验证码
* @param {*} key 随机数
*/
getCodeImage: params =>
get(`/login/captcha?key=${params}`, "", false),
/**
* @method 获取图形验证码
* @param {*} key 随机数
*/
checkLoginCode: params =>
get(`/login/check`, params, false),
/**
* @method 登录验证
* @param {*} name 登录名
* @param {*} password 密码
* @param {*} code 验证码
*/
login: params =>
post(`/login`, params, false),
/**
* @method 退出登录
* @param {*}
*/
logout: params =>
post(`/logout`, params, false),
}
Login.vue 测试
<template>
<div class="login-wrap">
<div class="ms-login">
<div class="ms-title">{{ adminTitle }}</div>
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="0px" class="ms-content">
<el-form-item prop="username">
<el-input v-model="form.name" placeholder="请输入用户名称" clearable></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
placeholder="请输入密码"
v-model="form.password"
show-password
clearable
maxlength="20"
show-word-limit
></el-input>
</el-form-item>
<el-form-item label prop="code">
<div class="disflex flexdr">
<el-input placeholder="请输入验证码" v-model="form.code" clearable></el-input>
<el-image @click="refreshCode" :src="codeImage" alt class="codeImage">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</div>
</el-form-item>
<div class="login-btn">
<el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
</div>
</el-form>
</div>
</div>
</template>
<script>
import LoginAjax from "@/utils/https/modules/Login.request.js";
import { generateString, setSession } from "@/utils/utils.js";
export default {
data() {
return {
adminTitle: "xxx 用户后台",
form: {
name: "",
password: "",
code: ""
},
rules: {
name: [{ required: true, message: "请输入用户名称", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
code: [{ required: true, message: "请输入验证码", trigger: "blur" }]
},
codeImage: "",
codeKey: generateString("xxxxxxxxxxx")
};
},
methods: {
// 刷新验证码
async refreshCode() {
try {
this.codeImage = "";
this.codeKey = generateString("xxxxxxxxxx");
this.codeImage = await LoginAjax.getCodeImage(this.codeKey);
} catch (error) {
this.$message.error(error);
}
},
// 登录
submitForm(formName) {
this.$refs[formName].validate(async valid => {
if (valid) {
try {
const { data, msg } = await LoginAjax.login({
key: this.codeKey,
...this.form
});
setSession("xxxtoken", data);
this.$message.success(msg);
this.$router.push("/activity");
} catch (error) {
this.refreshCode();
this.form.code = "";
return false;
}
} else {
return false;
}
});
}
},
mounted() {
this.$nextTick(() => {
this.refreshCode();
});
}
};
</script>
<style lang="scss" scoped>
// ...
</style>