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;// 显示loadingfunction showLoading() { if (needLoadingRequestCount === 0 && !loading) { loading = Vue.prototype.$loading({ lock: true, text: "请求中,请稍等...", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)" }); } needLoadingRequestCount++;}// 隐藏loadingfunction 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>