vue3+ts Axios封装与使用

创建完vue3 项目后

新版本:动态控制是否显示加载动画。是否需要判断重复请求。https://www.cnblogs.com/lovejielive/p/17676856.html

一,安装Axios与Element Plus

Axios安装

npm install axios

Element Plus 安装

官网入口:https://element-plus.gitee.io/zh-CN/

npm install element-plus --save

二,在src 目录下创建 api 文件夹和 utils 文件夹

api 文件夹下 封装 Axios封装 与 请求配置

utils 文件夹下 operate.ts 配置接口地址 与其他全局ts

Axios封装

api文件夹下 创建 request-wrapper.ts Axios封装

/*
 * @description: 请求封装
 * @Author: Jay
 * @Date: 2022-06-08 11:41:36
 * @LastEditors: Jay
 * @LastEditTime: 2022-06-08 15:29:38
 */
// 导入axios
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
// 使用element-ui ElMessage做消息提醒  ElLoading加载
import { ElMessage, ElLoading } from "element-plus";
//请求头
import operate from '@/utils/operate';

//加载配置
let loadingInstance: any,
    requestNum: number = 0,
    loading: boolean = true;

//加载动画
const addLoading = () => {
    // 防止重复弹出
    requestNum++;
    if (requestNum == 1) {
        loadingInstance = ElLoading.service({ fullscreen: true });
    }
}

// 关闭 加载动画
const cancelLoading = () => {
    requestNum--;
    // 关闭 加载动画
    if (requestNum === 0) loadingInstance?.close();
}

//请求配置
export const createAxios = (
    config?: AxiosRequestConfig,
): AxiosInstance => {
    const instance = axios.create({
        //请求头
        baseURL: operate.baseUrl(),
        // baseURL: '/api',
        //超时配置
        timeout: 1000,
        //跨域携带cookie
        withCredentials: true,
        // 自定义配置覆盖基本配置
        ...config,
    });

    // 添加请求拦截器
    instance.interceptors.request.use(
        function (config: any) {
            // console.log("请求拦截器config:", config);
            //加载动画
            if (loading) addLoading();

            //判断是否有token 根据自己的需求判断
            let token = config.token;
            console.log("判断是否有token", token)
            if (token != undefined) {
                //如果要求携带在参数中
                config.params = Object.assign({}, config.params, token)
                // 如果要求携带在请求头中
                // config.headers = Object.assign({}, config.headers, operate.uploadParameters())
            }
            return config;
        },
        function (error) {
            // 请求错误
            return Promise.reject(error)
        }
    )

    // 添加响应拦截器
    instance.interceptors.response.use(
        function (response) {
            // console.log("响应拦截器response:", response);
            // 关闭加载 动画
            if (loading) cancelLoading();
            //返回参数
            return response.data;
        },
        function (error) {
            // 关闭加载 动画
            if (loading) cancelLoading();
            /***** 接收到异常响应的处理开始 *****/
            if (error && error.response) {
                // 1.公共错误处理
                // 2.根据响应码具体处理
                switch (error.response.status) {
                    case 400:
                        error.message = '错误请求'
                        break;
                    case 401:
                        error.message = '未授权,请重新登录'
                        break;
                    case 403:
                        error.message = '拒绝访问'
                        break;
                    case 404:
                        error.message = '请求错误,未找到该资源'
                        window.location.href = "/NotFound"
                        break;
                    case 405:
                        error.message = '请求方法未允许'
                        break;
                    case 408:
                        error.message = '请求超时'
                        break;
                    case 500:
                        error.message = '服务器端出错'
                        break;
                    case 501:
                        error.message = '网络未实现'
                        break;
                    case 502:
                        error.message = '网络错误'
                        break;
                    case 503:
                        error.message = '服务不可用'
                        break;
                    case 504:
                        error.message = '网络超时'
                        break;
                    case 505:
                        error.message = 'http版本不支持该请求'
                        break;
                    default:
                        error.message = `连接错误${error.response.status}`
                }
            } else {
                // 超时处理
                if (JSON.stringify(error).includes('timeout')) {
                    error.message = '服务器响应超时,请刷新当前页'
                } else {
                    error.message = '连接服务器失败'
                }
            }
            //提示
            ElMessage.error(error.message)
            /***** 处理结束 *****/
            return Promise.resolve(error.response)
        }
    )

    return instance;
}
Axios封装

api文件夹下 创建 api.ts 接口配置

/*
 * @description: 请求接口 配置
 * @Author: Jay
 * @Date: 2022-06-08 10:41:36
 * @LastEditors: Jay
 * @LastEditTime: 2022-06-08 14:29:38
 */
//导入 Axios 请求
import { createAxios } from './request-wrapper'
const request = createAxios();
//其他配置
// import operate from '@/utils/operate';

// get 请求
export const exportGet = (params: any): Promise<any> =>
    request.get("/api/search/get/web", { params });


// post 请求
export const exportPost = (data: any) =>
    //请求 token 添加
    // request.post("/export", Object.assign(data, { token: operate.isToken() }));
    request.post("/export", data);


/*
请求配置与使用

* POST 请求 方式
    export const 名字 = (data: any) =>
        request.post("接口", data, {
            直接为空
            注:只能配置 AxiosRequestConfig 里有的参数名 可不用配置
        });

* GET 请求 方式
    export const 名字 = (params: any): Promise<any> =>
        request.get("接口", { params });

*使用 方法
   *引入
        import {
            名字
        } from "../api/api"
    *生命周期中 请求
        名字({请求参数}).then((res) => {
            console.log(res)
        })
*/
接口配置

开始请求

<script lang="ts">
  import {
    exportGet,
    exportPost
  } from "../api/api"
  import {
    defineComponent,
    onMounted
  } from "vue";
  
 export default defineComponent({
    setup() {
      onMounted(() => {
          //get 请求
          exportGet({
              csrf_token: '5555'
          }).then((res) => {
             console.log(res)
          })

          // post 请求
          exportPost({
             csrf_token: '5555'
          }).then((res) => {
             console.log(res)
         })
     })

      return {};
    },
  });
</script>
View Code

测试 结果:

三,全局配置JS

operate.ts 创建

/*
 * @description: 自定义 ts
 * @Author: Jay
 * @Date: 2022-06-08 13:22:07
 * @LastEditors: Jay
 * @LastEditTime: 2022-06-08 14:35:07
 */
// vuex 数据
import store from '../store/index'

export default {
    //接口地址
    baseUrl: function () {
        // console.log(process.env.NODE_ENV)
        if (process.env.NODE_ENV == "development") {
            //开发环境
            return "development";
        } else {
            //正式环境
            return "production";
        }
    },

    //获取用户token
    isToken: function () {
        if (store.state.Authorization != '') {
            return store.state.Authorization
        }
        return false;
    },

    /*
        格式化时间 加上时分秒
        num: 后台时间格式
        type: 'YY-MM-DD'年月日 ,'HH-MM-SS'时分秒 ,不传 年月日时分秒
    */
    happenTime: function (num: any, type: String) {
        let date = new Date(num * 1000);
        //时间戳为10位需*1000,时间戳为13位的话不需乘1000
        let y: any = date.getFullYear();
        let MM: any = date.getMonth() + 1;
        MM = MM < 10 ? ('0' + MM) : MM; //月补0
        let d: any = date.getDate();
        d = d < 10 ? ('0' + d) : d; //天补0
        let h: any = date.getHours();
        h = h < 10 ? ('0' + h) : h; //小时补0
        let m: any = date.getMinutes();
        m = m < 10 ? ('0' + m) : m; //分钟补0
        let s: any = date.getSeconds();
        s = s < 10 ? ('0' + s) : s; //秒补0
        if (type === 'YY-MM-DD') {
            //年月日
            return y + '-' + MM + '-' + d;
        } else if (type === 'HH-MM-SS') {
            //时分秒
            return h + ':' + m + ':' + s;
        } else {
            //全部
            return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s;
        }
    },

    //性别
    formSex: function (set: String | Number) {
        const status: Object = {
            "0": "男",
            "1": "女"
        }
        let key: keyof Object;
        for (key in status) {
            //console.log(key, status[key])
            if (key == set) {
                return status[key];
            }
        }
        return '未知'
    }
}
operate.ts 创建

operate.ts 全局配置

在mian.ts 中

//全局 js
import operate from "./utils/operate"
app.config.globalProperties.$operate = operate

在页面中使用

<script lang="ts">
  import {
    getCurrentInstance,
    onMounted
  } from "vue";
  
 export default defineComponent({
    setup() {
       //等于 vue this.
      const {
        proxy
      } = getCurrentInstance() as any;
      /*
        as any 在最后 加上这个 就不会 报下面的错误
        类型“ComponentInternalInstance | null”上不存在属性“proxy”。
      */
      
      onMounted(() => {
          console.log("性别为:",proxy.$operate.formSex(0))
      })

      return {};
    },
  });
</script>

最后结果

 

posted @ 2022-06-10 16:18  虚乄  阅读(1501)  评论(0编辑  收藏  举报