VUE中使用AXIOS包装API代理

VUE中使用AXIOS包装API代理

0. 背景

在VUE开发过程,与后端接口交互时,可以简单几句代码就剋调用后端POST或者GET请求. 实际效果就是,前端定义一个对象

javascript 复制代码
{
  getPageList: 'GET /pagelist',
  commitData: 'POST /savedata',
  getDetail: 'GET /detail/{id}',
}

然后在业务代码中就可以调用getPageList方法,实际效果就是发送一个GET请求,请求地址为/pagelist 常用场景如下:

  • api.getPageList("gameName=地心侠士&gameType=小游戏') 会转换成GET请求,参数在URL上 /pagelist?gameName=地心侠士&gameType=小游戏
  • api.commitData({gameName:"地心侠士",gameType:"小游戏"}) 会转换成POST请求,参数通过JOSN提交 /savedata
  • api.getDetail({id:1}) 会转换成GET请求,参数在URL上 /detail/1

1. 整合全局axios配置

整合axios主要是配置一些全局的请求,响应,以及请求头,请求超时配置等.全局配置代码request.js如下:

javascript 复制代码
import axios from 'axios';
import loading from './loading';
const ENV = import.meta.env;
const { VITE_GLOB_API_URL } = ENV;
let req = axios.create({
  baseURL: VITE_GLOB_API_URL || '',
  timeout: 30000,
  params: {'g.type': '1'},
  headers:{'g.type': '1'},
});
// 请求拦截 公众号 小满小慢
req.interceptors.request.use((cfg) => {
  loading.showLoading();
  return cfg;
});
// 响应拦截 公众号 小满小慢
req.interceptors.response.use(
  (resp) => {
    loading.hideLoading();
    if (resp.data.code && resp.data.code != '0') {
      // 全局拦截错误信息
      loading.showError(resp.data.message);
      return Promise.reject(resp.data);
    }
    return resp;
  },(error) => {
    loading.hideLoading();
    if (error.response && error.response.data) {
      loading.showError(error.response.data.message);
    }
    return Promise.reject(error);
  },
);
export default {
  request: req.request, 
};

2. 创建API请求包装器

请求包装器主要有以下作用

  • 请求参数处理
  • 通用接口暴露

实际效果可以把 GET /pagelist 暴露成一个可以调用的方法 ,创建API请求包装器apiconvert.js如下:

javascript 复制代码
import req from './request.js';
export function convertApi(apis) {
  const ENV = import.meta.env;
  const { VITE_GLOB_API_URL } = ENV;
  const api = {};
  for (const key in apis) {
    const apiInfos = apis[key].split(' ');
    const [method, apiUrl] = apiInfos;
    let base = VITE_GLOB_API_URL;
    if (key == 'ajax') base = '/';
    api[key] = (data) => {
    return new Promise((resolve, reject) => {
      let targetUrl = apiUrl;
      if (method === 'GET' && data && typeof data === 'string') {
        // get请求参数处理 公众号 小满小慢
        data = encodeURI(data);
        const index = targetUrl.indexOf('?');
        if (index === -1) {
          data = `?${data}`;
        }
        targetUrl = `${targetUrl}${data}`;
        data = null;
      }
      if (/{\w+}/.test(targetUrl)) {
        targetUrl = targetUrl.replace(/{(\w+)}/gi, function (match, p) {
          return data[p] || '0'; 
        });
        console.log(`change url:${targetUrl}`);
      }
      req.request({ method: method, url: targetUrl, data: data,baseURL: base})
        .then((res) => resolve(res.data))
        .catch((error) => {
          reject(error);
        });
    });
    };
  }
  return api;
}
// 暴露一个通用接口
const api = convertApi({
  ajax: 'GET /commonDataProc',
});

export default api;

3. 使用API请求包装器

实际的业务接口可以通过键值对的方式配置,然后通过convertApi方法进行转换,转换后的接口可以调用. 如下:

  • 'GET /pagelist'
  • 'POST /savedata'

实际业务接口biz_api.js 定义如下

javascript 复制代码
import commapi, { convertApi } from '@/assets/js/apiconvert';
const api = convertApi({
  // 这里可以扩展业务接口
  getPageList: 'GET /pagelist',
});
// 合并通用接口
Object.assign(api, commapi);
export default api;

4. 使用业务接口

实际业务代码中,通过import api from '@/assets/js/biz_api'引入业务接口,然后调用业务接口即可.

javascript 复制代码
import api from './biz_api.js'
const data = ref([]);
const loadingStatus = ref(true);
async function getPages() {
  const res = await api.getPageList();
  let arr = [];
  for (let i in res) {
    arr.push(res[i]);
  }
  data.value = arr;
  loadingStatus.value = false;
}
onMounted(() => {
  getPages()
});

5. 总结

通过以上封装后,前端调用后端的API清晰明了.api定义在单独的文件,也可以自由组合. 从设计上来说,主要使用了两层代理转换. 所有还是印证那句话,一层代理解决不了问题,那就再加一层. 以上仅为个人项目落地总结,若有更优雅的方式,欢迎告知.微信公众号:小满小慢 私信或者直接留言都可以. 原文地址 mp.weixin.qq.com/s/aqHVyq_I3...

相关推荐
0和1的舞者10 小时前
Spring AOP详解(一)
java·开发语言·前端·spring·aop·面向切面
web小白成长日记10 小时前
在Vue样式中使用JavaScript 变量(CSS 变量注入)
前端·javascript·css·vue.js
QT 小鲜肉10 小时前
【Linux命令大全】001.文件管理之which命令(实操篇)
linux·运维·服务器·前端·chrome·笔记
C_心欲无痕10 小时前
react - useImperativeHandle让子组件“暴露方法”给父组件调用
前端·javascript·react.js
BullSmall12 小时前
支持离线配置修改及删除操作的实现方案
前端
全栈前端老曹12 小时前
【前端路由】Vue Router 嵌套路由 - 配置父子级路由、命名视图、动态路径匹配
前端·javascript·vue.js·node.js·ecmascript·vue-router·前端路由
EndingCoder13 小时前
安装和设置 TypeScript 开发环境
前端·javascript·typescript
张雨zy13 小时前
Vue 项目管理数据时,Cookie、Pinia 和 LocalStorage 三种常见的工具的选择
前端·javascript·vue.js
五月君_13 小时前
Nuxt UI v4.3 发布:原生 AI 富文本编辑器来了,Vue 生态又添一员猛将!
前端·javascript·vue.js·人工智能·ui
!执行13 小时前
遇到 Git 提示大文件无法上传确实让人头疼
前端·github