当前位置: 首页 > news >正文

05-vue3+ts中axios的封装

vue3+ts中axios的封装

安装 axios

npm install axios

一、axios 的类型解析

Axios 几个常用类型:

  • AxiosInstance: axios 实例类型
  • AxiosRequestConfig: axios 请求配置类型
  • AxiosResponse: axios 响应类型
  • AxiosError: axios 错误类型

1、AxiosRequestConfig

AxiosRequestConfig 是我们使用 axios 发送请求传递参数的类型。当然它也是我们请求拦截器里面的参数类型。

2、AxiosInstance

  • AxiosInstance 是 axios 的实例类型。
  • axios.create(config?: AxiosRequestConfig)创建出来的对象都是AxiosInstance类型!

3、AxiosResponse

  • AxiosResponse 是 axios 响应类型。
  • 我们可以在响应拦截器中获取到响应数据。
export interface AxiosResponse<T = any>  {// 后端接口数据data: T;// http状态码status: number;// 来自服务器响应的 HTTP 状态信息statusText: string;// 响应头headers: any;// 请求配置信息config: AxiosRequestConfig;// 请求request?: any;
}

4、AxiosError

AxiosError 是 axios 错误类型。可以在请求或响应拦截器中获取到错误信息。

二、封装axios

本质:axios二次封装,就是使用请求和响应拦截器!

1、步骤

  • 1.创建axios实例: axios.create(config配置对象)
  • 2.axios添加请求拦截器:主要是操作config对象:
axios.interceptors.request.use((config)=>{return config})
  • 3.响应拦截器
axios.interceptors.response.use((response)=>{return response})

2、实现代码

  • 基于restful风格,提供了相对应的方法,方便调用!
  • 在src目录下,创建api目录,创建request.ts,代码如下:
import axios from "axios";
import type { AxiosInstance, AxiosRequestConfig } from "axios";
import { base_url, TOKEN } from "@/config/com/base";
import toast from "@/config/utils/toast";
import { ElLoading } from "element-plus";
import useLoginStore from "@/store/login_store";
import cache from "@/config/utils/cache";
import router from "@/router";
/*** axios二次封装,就是使用请求和响应拦截器* --- 创建axios对象: axios.create(config配置对象)* --- 给axios添加请求拦截器:主要是操作config对象*      axios.interceptors.request.use((config)=>{return config})* --- 给axios添加响应拦截器:*      request.interceptors.response.use();* ---------------------------------------------------------* -- 定义一个Request类:两个属性*    --- 属性:instance:AxiosInstance类型*              axios的实例对象*    --- 属性:baseConfig: AxiosRequestConfig类型*              基本的配置信息:baseURL,timeout*    --- 属性:* ---------------------------------------------------------*  */// 定义一个类Request!
class Request {//axios.create()返回axios对象instance: AxiosInstance;loadingInstance: any; // 用于存储ElLoading实例的变量//axios.create(config配置对象)需要的configbaseConfig: AxiosRequestConfig = { baseURL: base_url, timeout: 5000 };constructor(config: AxiosRequestConfig) {// 还得提供额外的config配置!所以使用了Object.assign()this.instance = axios.create(Object.assign(this.baseConfig, config));//在构造器初始化时候 添加 请求拦截器: 主要操作config对象this.instance.interceptors.request.use((config: any) => {// 创建ElLoading实例并显示加载提示,这里可以配置一些加载提示的相关属性,比如文本、背景遮罩等this.loadingInstance = ElLoading.service({text: "正在加载...",fullscreen: true,background: "rgba(0, 0, 0, 0.05)",});//添加token:const userStore = useLoginStore();let token = userStore.token;if (token) {config.headers["Authorization"] = `Bearer ${token}`;}return config;},(error) => {// 请求错误,这里可以用全局提示框进行提示return Promise.reject(error);});this.instance.interceptors.response.use( // 添加响应拦截器(res: any) => {// console.log('request.ts --- 响应拦截器:'+res);// 关闭ElLoading实例,隐藏加载提示if (this.loadingInstance) {this.loadingInstance.close();}return res.data;},// 失败响应(err: any) => {// 这里是AxiosError类型,所以一般我们只reject我们需要的响应即可// 关闭ElLoading实例,隐藏加载提示if (this.loadingInstance) {this.loadingInstance.close();}console.log("拦截器--error=" + JSON.stringify(err.response.data.data));let message = "";switch (err.response.status) {case 400:message = "code = 400 :" + JSON.stringify(err.response.data.data);break;case 401:console.log("401---token认证失败---");message = err.response.data.data?.detail;// 这里可以做清空storage并跳转到登录页的操作,处理只需要清空token即可,cache.removeCache(TOKEN);router.replace("/login");// 强制刷新window.location.reload();break;case 403:message = "权限不够,拒绝访问(403)";break;case 404:message = "请求地址无效(404)";break;case 405:message = "请求方法不被允许(405)";break;case 500:message = "服务器错误(500)";break;default:message = `连接出错(${err.response.status})!`;}// 错误消息可以使用全局弹框展示出来 :比如element plus 可以使用 ElMessage// `${message},请检查网络或联系管理员!`if (err.response.data.data) {// toast.error(message + " : " + JSON.stringify(err.response.data.data));toast.error(message);} else {toast.error(message + " : " + "服务器好像没有开启");}return Promise.reject(err.response);});}// 封装get请求!public get(url: string, params?: any): Promise<any> {return this.instance.get(url, { params });}public get_by_id(url: string, id: Number): Promise<any> {return this.instance.get(url + id + "/");}// 封装post请求!保存操作public post(url: string, data: any): Promise<any> {return this.instance.post(url, data);}// 封装put请求!public put(url: string, data: any): Promise<any> {return this.instance.put(url + data.id + "/", data);}// 根据id删除的方法(资源地址,资源id)public delete_by_id(url: string, id: Number): Promise<any> {return this.instance.delete(url + id + "/");}// 根据pic删除的方法:把参数封装到params配置项中public delete_pic(url: string, params?: any): Promise<any> {return this.instance.delete(url, { params });}// 把参数封装到data配置项中public delete_selected(url: string, data?: any): Promise<any> {return this.instance.delete(url, { data });}
}
// 默认导出Request实例!
export default new Request({});

封装中使用到的其它依赖文件:

  • base.ts
import { base_url, TOKEN } from "@/config/com/base";
// 配置项目的基本信息的文件
//特别注意。图片路径最后要添加斜杠!不然图片显示失败
export const base_url: string = import.meta.env.VITE_APP_BASE_API;
export const TOKEN = "token";
  • toast.ts : 是对Elment-plus的提示信息的封装(个人选择)
import toast from "@/config/utils/toast";
// 用于封装一些全局的hook,可以单独导入某些方法使用,也可以统一导入 hook 对象,从 hook 对象中 . 具体的方法
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
/*** 封装一个全局的 message 方法,用于显示消息提示* @param message  消息内容* @param type 消息类型,默认为 success*/
export const message = (message: string) => {ElMessage({message,type: "success",});
};
/*** 封装一个全局的 notification 方法,用于显示通知*  @param message 通知内容*  @param title   通知标题,默认为 '提示'*/
export const notify = (message: string) => {ElNotification({// title,message,type: "success",});
};
export const error = (message: string) => {ElNotification({message,type: "error",});
};
/*** 封装一个全局的 confirm 方法,用于显示确认对话框* @param message 对话框内容* @param title 对话框标题,默认为 '提示'* @param [options] 对话框选项* @return Promise<boolean>*/
export const confirm = (message: string, title = "提示", options: any = {}) => {if (Object.keys(options).length == 0) {options = {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",};}return new Promise((resolve, reject) => {ElMessageBox.confirm(message, title, options).then(() => {resolve(true);}).catch(() => {reject(false);});});
};
/*** 统一导出一个 hook 方法对象,包含所有 hook 方法*/
export default {message,confirm,notify,error,
};
/*** 使用该hooks方式如下:
import hooks from "@/config/utils/index";
hooks.message('操作成功') // 成功弹出
hooks.notification('恭喜你学会了使用全局通知组件', '操作成功', { type: 'success' }) // 成功弹出
hooks.confirm('确认要删除吗?').then((res) => console.log(res)) // 成功弹出*/
  • login_store.ts : 仅给出示例代码
import useLoginStore from "@/store/login_store";
import { defineStore } from "pinia";
import { TOKEN } from "@/config/com/base";
import cache from "@/config/utils/cache";
import { ref } from "vue";
export const useLoginStore = defineStore("login", () => {const token = ref("");const login = () => {// 实现逻辑};return {token,login}
});
  • cache.ts : 这是封装的localstorage使用的工具类!
import cache from "@/config/utils/cache";
/*** 封装localStorage的使用:* import cache from "@/config/utils/cache";* cache.xxx()即可!*/
class Cache {setCache(key: string, value: any) {if (value) {localStorage.setItem(key, JSON.stringify(value));}}getCache(key: string) {const value = localStorage.getItem(key);if (value) {return JSON.parse(value);}return "";}removeCache(key: string) {localStorage.removeItem(key);}clear() {localStorage.clear();}
}
export default new Cache();

3、发送请求的示例代码:

以下代码是使用request的格式示例:

  • 发送请求即可复制格式,修改参数即可!
import request from "@/api/request";// 以下 用到的请求地址示例:
//  api_sy.user = "/sy/user/", //操作用户的url
// 表单数据
let form = reactive({id:xxxx, //修改时候传递!username: "",password: "",name: "",phone: '',is_active: true,is_staff: true,avatar: "",
})

发送get请求:

// 发送get请求
request.get(api_sy.user, params).then(resp => {console.log(resp.data)
})

发送post请求:

// 发送post请求
request.post(api_sy.user, form).then(resp => {console.log(resp.data)
})

发送put请求:

// 发送put请求
request.put(api_sy.user, form).then(resp => {console.log(resp.data)
})

发送delete请求:

// 发送delete请求
request.delete_by_id(api_sy.user, id).then(resp => {console.log(resp.data)
})
http://www.dtcms.com/a/407269.html

相关文章:

  • 升阳广州做网站公司手游传奇发布网站999
  • 企业备案网站名称怎么填做网站策划需要什么技能
  • 智能体(Agent)的记忆架构:深入解析短期记忆与长期记忆
  • Tongweb708命令行脚本使用指引(by lqw)
  • python学智能算法(三十九)|使用PyTorch模块的normal()函数绘制正态分布函数图
  • wordpress the_content() 截取盐城网站优化推广服务
  • (6) tauri之前端框架性能对比
  • 网站收录查询临沂seo网站建设费入什么科目
  • 做电商网站电商公司wordpress添加标签后哪里显示
  • 优化排名推广技术网站个人网站怎样申请
  • golang面经——context模块
  • Go基础:Go语言能用到的常用时间处理
  • ppt网站超链接怎么做网站报备流程
  • HTTP安全响应头--CSP(Content-Security-Policy)
  • 建筑网站排行榜网站界面设计专利
  • 如何开始第一个开源项目?
  • Moviechat论文阅读
  • 做电影网站算侵权吗上海建设安检站网站
  • 品牌网站模板wordpress判断是否登录
  • 门户网站建设主要内容为什么建设营销型网站
  • 双语版网站引导页常德尚一网
  • Day70 基本情报技术者 单词表05 数据结构
  • 百色高端网站建设网站建设登记表
  • Redis - Hyperloglog类型
  • 配置 Oracle Linux 8 仓库为 yum 源
  • 移动网站建设优势滁州公司做网站
  • 用网站模板 侵权 做了修改seo优化提升排名
  • Golang语言基础篇008_接口详解
  • 广州网站设计总部找北京赛车网站开发
  • 做网站需要会哪些计算机语言大学生实训网站建设心得