当前位置:   article > 正文

vue3 全局配置Axios实例_axios在vue中全局实用

axios在vue中全局实用

目录

前言

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境。它提供了一种简单、一致的 API 来处理HTTP请求,支持请求和响应的拦截、转换、取消请求等功能。关于它的作用:

  1. 发起 HTTP 请求: Axios 提供了丰富的 API,使得在浏览器和 Node.js 中发起 HTTP 请求变得非常容易。可以发送 GET、POST、PUT、DELETE 等不同类型的请求。

  2. Promise 风格: Axios 使用 Promise 风格的 API,使得在异步请求中更容易处理数据和错误。可以使用 .then() 处理成功的响应,使用 .catch() 处理错误。

  3. 拦截请求和响应: 可以在请求和响应被发送或接收之前进行拦截处理。这使得在请求发送前或响应返回后可以进行一些全局的处理,比如添加请求头、处理错误等。

  4. 自动转换 JSON 数据: Axios 在接收到响应数据时,会自动将 JSON 字符串转换为 JavaScript 对象。这样可以方便地处理和操作服务器返回的 JSON 数据。

  5. 取消请求: Axios 允许你创建一个取消请求的令牌,以便在需要时取消尚未完成的请求。这在处理组件销毁或用户导航时非常有用,可以避免不必要的请求。

  6. 全局配置: 可以配置全局的默认值,例如基础URL、超时时间等,以便在整个应用程序中使用相同的设置。

  7. 处理请求和响应数据: 可以在请求和响应时对数据进行转换和处理。这包括序列化请求数据、解析响应数据等。

  8. 上传和下载进度: Axios 提供了上传和下载进度的事件,可以监视请求和响应的进度。这对于实时显示进度条等功能非常有用。

总体而言,Axios是一个强大而灵活的工具,可以简化和优化HTTP请求的处理,是前端开发中常用的网络请求库之一,并且当在Vue.js 3项目中使用Axios时,可以通过全局设置来配置Axios实例,以便在整个应用程序中共享相同的请求和响应逻辑,比如500或者401时,系统的一些操作。

配置Axios实例

前提,需要先安装axios:npm install axios

如下:

开始配置,先在项目的一个文件夹下某创建一个文件,里面进行Axios 实例配置,通常在src/utils下,一般内容有:

  1. import axios from 'axios';
  2. // 创建 Axios 实例
  3. const service = axios.create({
  4. baseURL: process.env.VUE_APP_BASE_URL, // 使用环境变量配置 baseURL
  5. timeout: 5000, // 设置请求超时时间
  6. });
  7. // 请求拦截器
  8. service.interceptors.request.use(
  9. (config) => {
  10. // 在请求发送前可以进行一些配置,例如添加认证信息等
  11. config.headers['X-Auth-Token'] = 'your_token'; // 示例:添加认证信息
  12. return config;
  13. },
  14. (error) => {
  15. return Promise.reject(error);
  16. }
  17. );
  18. // 响应拦截器
  19. service.interceptors.response.use(
  20. (response) => {
  21. // 在响应返回后,可以进行一些处理,例如判断是否需要更新令牌等
  22. // ...
  23. return response;
  24. },
  25. (error) => {
  26. // 处理响应错误
  27. // ...
  28. return Promise.reject(error);
  29. }
  30. );
  31. export default service;

上面是比较基础的,可以在此基础上进行自定义的操作,比如我下面这种:

axios-req.ts

  1. import axios from 'axios'
  2. import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
  3. import { useBasicStore } from '@/store/basic'
  4. //使用axios.create()创建一个axios请求实例
  5. const service = axios.create()
  6. let loadingInstance: any = null //loading实例
  7. let tempReqUrlSave = ''
  8. let authorTipDoor = true
  9. const noAuthDill = () => {
  10. authorTipDoor = false
  11. ElMessageBox.confirm('请重新登录', {
  12. confirmButtonText: '重新登录',
  13. closeOnClickModal: false,
  14. showCancelButton: false,
  15. showClose: false,
  16. type: 'warning'
  17. }).then(() => {
  18. useBasicStore().resetStateAndToLogin()
  19. authorTipDoor = true
  20. })
  21. }
  22. //请求前拦截
  23. service.interceptors.request.use(
  24. (req: any) => {
  25. const { token, axiosPromiseArr }: any = useBasicStore()
  26. //axiosPromiseArr收集请求地址,用于取消请求
  27. req.cancelToken = new axios.CancelToken((cancel) => {
  28. tempReqUrlSave = req.url
  29. axiosPromiseArr.push({
  30. url: req.url,
  31. cancel
  32. })
  33. })
  34. //设置token到header
  35. if (token) req.headers['X-Auth-Token'] = token
  36. //如果req.method给get 请求参数设置为 ?name=xxx
  37. if ('get'.includes(req.method?.toLowerCase()) && !req.params) req.params = req.data
  38. //req loading
  39. // @ts-ignore
  40. if (req.reqLoading ?? true) {
  41. loadingInstance = ElLoading.service({
  42. lock: true,
  43. fullscreen: true,
  44. // spinner: 'CircleCheck',
  45. text: '数据载入中...',
  46. background: 'rgba(0, 0, 0, 0.1)'
  47. })
  48. }
  49. return req
  50. },
  51. (err) => {
  52. //发送请求失败
  53. Promise.reject(err)
  54. }
  55. )
  56. //请求后拦截
  57. service.interceptors.response.use(
  58. (res: any) => {
  59. //取消请求
  60. useBasicStore().remotePromiseArrByReqUrl(tempReqUrlSave)
  61. if (loadingInstance) {
  62. loadingInstance && loadingInstance.close()
  63. }
  64. //download file
  65. if (res.data?.type?.includes("sheet")) {
  66. return res
  67. }
  68. const { code, msg } = res.data
  69. const successCode = [0,200,20000]
  70. const noAuthCode = [401,403]
  71. if (successCode.includes(code)) {
  72. return res.data
  73. } else {
  74. //authorTipDoor 防止多个请求 多次alter
  75. if (authorTipDoor) {
  76. if (noAuthCode.includes(code)) {
  77. noAuthDill()
  78. } else {
  79. // @ts-ignore
  80. if (!res.config?.isNotTipErrorMsg) {
  81. ElMessage.error({
  82. message: msg,
  83. duration: 2 * 1000
  84. })
  85. } else {
  86. return res
  87. }
  88. return Promise.reject(msg)
  89. }
  90. }
  91. }
  92. },
  93. //响应报错
  94. (err) => {
  95. //取消请求
  96. useBasicStore().remotePromiseArrByReqUrl(tempReqUrlSave)
  97. if (loadingInstance) {
  98. loadingInstance && loadingInstance.close()
  99. }
  100. ElMessage.error({
  101. message: err,
  102. duration: 2 * 1000
  103. })
  104. return Promise.reject(err)
  105. }
  106. )
  107. //导出service实例给页面调用 , config->页面的配置
  108. export default function axiosReq(config) {
  109. return service({
  110. baseURL: import.meta.env.VITE_APP_BASE_URL,
  111. timeout: 8000,
  112. ...config
  113. })
  114. }

 之后我们可以在api文件夹下新建一个user.ts,放一些API。就像这样:

  1. import axiosReq from '@/utils/axios-req'
  2. //登录
  3. export const loginReq = (subForm) => {
  4. return axiosReq({
  5. url: '/login',
  6. method: 'post',
  7. data: subForm
  8. })
  9. }
  10. //退出登录
  11. export const loginOutReq = () => {
  12. return axiosReq({
  13. url: '/loginOut',
  14. method: 'post'
  15. })
  16. }

页面使用

这里以登录页为例

登录页面发送请求,一般会发送用户账号密码,然后获取到一个token,所以我一般这样用:

  1. import { loginReq } from '@/api/user'
  2. const loginFunc = () => {
  3. loginReq({
  4. username: subForm.keyword,
  5. password: subForm.password
  6. })
  7. .then(({ data }) => {
  8. elMessage('登录成功')
  9. basicStore.setToken(data?.token)
  10. router.push('/')
  11. })
  12. .catch((err) => {
  13. tipMessage.value = err?.msg
  14. })
  15. .finally(() => {
  16. subLoading.value = false
  17. })
  18. }

总结

如果想在Vue全局使用的话,可以用provideinject来在整个应用程序中提供和注入Axios实例。

  1. import { createApp } from 'vue';
  2. import App from './App.vue';
  3. import request from '@/utils/request';
  4. const app = createApp(App);
  5. // 提供Axios实例
  6. app.provide('request', request);
  7. app.mount('#app');

页面使用:

  1. export default {
  2.   inject: ['request'],
  3.   methods: {
  4.     fetchData() {
  5.       this.request.get('/api/data')
  6.         .then(response => {
  7.           // 处理响应数据
  8.         })
  9.         .catch(error => {
  10.           // 处理请求错误
  11.         });
  12.     },
  13.   },
  14. };

但是还是建议每个页面需要哪些API就引入哪些吧。

总结,aixos的全局配置会方便API管理,并且对于一些关于 token 处理和错误处理的逻辑,以及状态码的反馈都是比较方便的,根据项目需求来实现。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/257347
推荐阅读
相关标签
  

闽ICP备14008679号