房产中介管理软件第8课:通用request请求及loading

前端离不开请求,使用axios请求后端,设计了通用的request和loading

一、建立api.js文件用于存放接口路径

api.js存放所有的接口地址

const BASE_URL = process.env.VUE_APP_API_BASE_URL

module.exports = 
{ 
  // 通用操作类
  COMMON_SMS_SEND:  `${BASE_URL}/Tool/SMS/Send`,
  COMMON_SMS_CHECK:  `${BASE_URL}/Tool/SMS/Check`,

  // 实用工具
  LOGIN_CAPTCHACODE_GET: `${BASE_URL}/Tool/CaptchaCode`,

  // 登录服务接口
  LOGIN_RESETPASSWORD_CHECKNAME: `${BASE_URL}/Agent/ResetPassword/CheckName`,
  LOGIN_RESETPASSWORD_RESET: `${BASE_URL}/Agent/ResetPassword/Reset`,



  LOGIN: `${BASE_URL}/Login`,  
}

二、建立loading.js用于加载中和关闭加载的显示,代码来自于网上

/**
 * 全局loading效果:合并多次loading请求,避免重复请求
 * 当调⽤⼀次showLoading,则次数+1;当次数为0时,则显⽰loading
 * 当调⽤⼀次hideLoading,则次数-1; 当次数为0时,则结束loading
 */
import { ElLoading } from "element-plus";
// 定义⼀个请求次数的变量,⽤来记录当前页⾯总共请求的次数
let loadingRequestCount = 0;
// 初始化loading
let loadingInstance;
// 显⽰loading的函数并且记录请求次数 ++
const showLoading = (loadingtext) => {
  if (loadingRequestCount === 0) {
    // 全局实现loading效果,不⽤每个页⾯单独去v-loading
    // loading样式
    loadingInstance = ElLoading.service({
      lock: true,
      text: (loadingtext === undefined || loadingtext == '' ? '加载' : loadingtext) + "中……",
      background: 'rgba(0, 0, 0, 0.7)'
    });
  }
  loadingRequestCount++;
};
// 隐藏loading的函数,并且记录请求次数 --
const hideLoading = () => {
  if (loadingRequestCount <= 0) return;
  loadingRequestCount--;
  if (loadingRequestCount === 0) {
    loadingInstance.close();
  }
};
export { showLoading, hideLoading };

三、建立request.js用于通用的get和post请求

里面暂时缺少守卫代码和token鉴权代码,后期添加

/*
  页面:数据请求类
*/
import axios from 'axios'
import { Array } from 'core-js'
import { ElNotification } from 'element-plus'
import { showLoading, hideLoading } from "@/utils/loading";

// 请求超时时间
axios.defaults.timeout = 50000
// 携带 cookie,对目前的项目没有什么作用,因为是 token 鉴权
axios.defaults.withCredentials = true;
// 默认 post 请求,使用 application/json 形式
axios.defaults.headers.post["Content-Type"] = "application/json";

// http method
const METHOD =
{
  GET: 'get',
  POST: 'post'
}

/**
 * axios请求
 * @param {*} vm     当前组件
 * @param {*} title  请求标题
 * @param {*} url    请求地址
 * @param {*} method POST/GET
 * @param {*} params 请求参数
 * @param {*} config 其他配置
 * @returns 
 */
async function request(vm, title, url, method, params, config) {
  // 检查Url是否正确
  if (typeof (url) == "undefined") {
    ElNotification({ type: 'error', title: "请求失败", message: "请求地址不存在(" + url + ")!" });
    return
  }
  // 判断参数是否字符串
  if (typeof (params) == "undefined")
    params = null
  else {
    // 判断参数是否数组
    if (params instanceof Array)
      url = format(url, params)
    else
      if ([params] instanceof Array)
        url = format(url, [params])
  }
  if ((typeof (title) == "undefined") || (title == ""))
    title = "加载"

  if (title != "HIDE") {
    showLoading(title);
  }


  let tips = (title != 'HIDE' ? title : '加载');
  let resp;
  if (method == METHOD.POST)
    resp = axios.post(url, params, config)
  else
    resp = axios.get(url, { params, ...config })

  resp.then(res => {
    const result = res.data
    const retmessage = result.message
    const retcode = result.code;

    if (typeof (retcode) != "undefined") {
      if (retcode == 3001)
        ElNotification({ type: 'warning', title: title + "提示", message: retmessage });
      else {
        if (retcode != 2000)
          ElNotification({ type: 'error', title: tips + "失败(" + retcode + ")", message: retmessage });
      }
    }
  })
  resp.catch(err => {
    const { response } = err
    if ((typeof (response) == "undefined") || (response.status != 401))
      ElNotification({ type: 'error', title: tips + "失败", message: err.toString() == "Error: Network Error" ? "网络不可用或服务器未开启" : err.toString() });
  })
  resp.finally(() => {
    if (title != "HIDE") {
      //此处采⽤延时处理是合并loading请求效果,避免多次请求loading关闭⼜开启
      setTimeout(() => {
        hideLoading();
      }, 200);
    }
  })
  return resp
}

/**
 * 格式化字符串
 * @param obj 
 * @returns 
 */
function format(url, args) {
  if (!url || !args)
    return url
  return url.replace(/{(\d+)}/g, function (match, number) {
    return typeof args[number] !== 'undefined' ? args[number] : match
  })
}

/**
* GET 请求
* @param {*} vm 
* @param {*} title 
* @param {*} url 
* @param {*} params 
* @returns 
*/
async function httpGet(vm, title, url, params, config) {
  return request(vm, title, url, METHOD.GET, params, config)
}

/**
 * POST  请求
 * @param {*} vm 
 * @param {*} title 
 * @param {*} url 
 * @param {*} params 
 * @returns 
 */
async function httpPost(vm, title, url, params, config) {
  return request(vm, title, url, METHOD.POST, params, config)
}

export {
  METHOD,
  request,
  httpGet,
  httpPost
}

四、在main.js文件中把方法开放为全局方法

import {httpGet, httpPost} from '@/utils/request'

//全局方法
app.config.globalProperties.$httpGet = httpGet;
app.config.globalProperties.$httpPost = httpPost;

五、方法调用演示

// 加载数据
this.$httpPost(this,'重置',this.$API.LOGIN_RESETPASSWORD_RESET,restPasswordData).then(res => 
{  
   if (res.data.code != 2000) { return; }     
   this.$success("密码重置成功,您可以使用新密码登录了");
   this.closeDialog();  
}) 

(本文完)

posted @ 2022-09-22 15:30  RandyTech  阅读(46)  评论(0编辑  收藏  举报