axios请求拦截器和响应拦截器,封装naive-ui的 Loading Bar加载条和useMessage消息提示

接之前的博客设计从0开始边做边学,用vue和python做一个博客,非规范化项目,怎么简单怎么弄,跑的起来有啥毛病解决啥毛病(三),目前已经完成了基本的功能demo,但是请求接口不可能每个页面每个请求都写完整的axios请求,所以怎么把请求简单化,就涉及到的axios的封装了。

由原先页面中的请求:

js 复制代码
axios.get('/api/article/' + id)
    .then(function (response) {
      console.log(response);
      artcleinfo.content = response.data.data.content
      artcleinfo.title = response.data.data.title
    })
    .catch(function (error) {
      console.log(error);
    });

变成这样:

js 复制代码
getarticle(id).then(res=>{
  console.log(res)
  artcleinfo.content = res.data.content
  artcleinfo.title = res.data.title
})

开始封装axios

首先在src下新建一个request文件夹用来存放请求等相关文件,然后文件夹下新建一个http.js 在这个文件中去把axios请求的一些公用逻辑封装到一起。

首先引入axios

js 复制代码
import axios from 'axios'; // 引入axios

然后写一个get函数和post函数

js 复制代码
export function get(url, params){
	return new Promise((resolve, reject) =>{
		axios.get(url, {
			params: params
		}).then(res => {
			resolve(res.data);
		}).catch(err =>{

			reject(err.data)
	})
})}

export function post(url, params) {
	return new Promise((resolve, reject) => {
		 axios.post(url,params)
		.then(res => {
			resolve(res.data);
		})
		.catch(err =>{
			reject(err.data)
		})
	});
}

这个时候如果页面引入这个get请求也是可以正常请求的。

js 复制代码
import get from '/src/request/http.js'

get('/api/article/',1).then(res=>{
  console.log(res)
})

但是每个接口可能不止用一次,页面中这样写的话万一之后接口改了,每个页面还需要去找,去改,费时费力,所以就需要把接口全都放在一起去管理维护,然后页面中调用就好。

新建一个api.js文件在request目录下。

js 复制代码
/// api.js
import { get, post } from './http'

export const getarticle = (params) => {
    return get('/api/article', params)
}

然后页面中就可以直接使用封装的这个函数getarticle 进行数据的请求了。

js 复制代码
getarticle(id).then(res=>{
  console.log(res)
})

这样就明朗多了

请求拦截和消息提示

虽然封装了请求,但是请求时会有一个请求和回复数据的时间问题,这个过程如果页面没有变化,那会不知道是否请求成功,是否开始请求,所以就涉及到发送请求之前对页面做些加载图标这些代表请求正在发送,然后请求回来的内容时候,页面提示请求成功或者失败或者异常信息等。

请求拦截器

axios有一个叫做请求拦截器的东西,就是每次发起请求之前可以写点东西放进去,然后每次请求之前都会执行一下,一般是请求之前判断token是否存在,或者请求的路径是否有权限等等

js 复制代码
axios.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么,加token头、请求路由权限判断、等等等等
    return config;
  },
  function (error) {
    // 请求错误时做些什么
    return Promise.reject(error);
  }
);

响应拦截器

既然请求之前可以拦截处理那么,请求成功回复的内容也可以进行拦截处理,把一些请求体内不需要的数据可以剔出去,然后只把data数据留到页面。在这个位置可以对返回来的数据的异常进行处理,比如请求回来的数据找不到数据404,没有权限403等等,再或者前后端有数据AES加密等等,只要是对返回数据进行统一操作的,都在这个响应拦截器中进行。

js 复制代码
axios.interceptors.response.use(
  function (response) {
    // 对响应数据做些什么,比如数据解密、数据转码等等
    return response;
  },
  function (error) {
    // 对响应错误做些什么,比如400报错事后给页面个提示,登录失效跳转登录页面等等
    return Promise.reject(error);
  }
);

Loading Bar加载条和useMessage消息提示

请求既然可以拦截了,那么就用naiveui的Loading Bar加载条对请求的是否正常和异常进行显示一下

就这种在浏览器顶部一个条条,跟随者请求加载来变化。

然后请求结果是否成功或者异常会有一个文字的弹窗提醒来说明,这块用到naiveui的useMessage消息提示

该说不说这个NaiveUi的全局配置对比element复杂的不是亿点点。。。

但是弄明白了之后,也就那么回事。

配置message这些的全局api

先不用管官网说的那些杂七杂八,什么全局api什么的,直接新建一个message.vue

然后里面这样写,因为我不会Ts,就按Js这个写法能用就行。

js 复制代码
<template>
  <div></div>
</template>
<script setup>
import { createDiscreteApi } from 'naive-ui'


const { message, notification, dialog, loadingBar } = createDiscreteApi(
    ['message', 'dialog', 'notification', 'loadingBar']
)

window.$message = message;
window.$notification = notification;
window.$dialog = dialog;
window.$loadingBar = loadingBar;

</script>

然后第二步,根据官网说的需要把用到这些消息的内容框起来,那就直接把APP.VUE包起来

js 复制代码
<script setup>
import message from "./components/message.vue";
</script>
<template>
  <n-message-provider>
   <RouterView />
    <message></message>
  </n-message-provider>
</template>
<style>

这个n-message-provider是必须的东西,用这个包上才能用这个message,然后把咱们写的全局挂载message组件也放在这,就能实现全局使用这个消息提示了。

axios挂载加载条

js 复制代码
// 请求拦截
axios.interceptors.request.use(
    config => {
        window.$loadingBar.start()
        return config;
    },
    error => {
        window.$loadingBar.error()
        return Promise.error(error);
    })

// 响应拦截器
axios.interceptors.response.use(
    response => {
        window.$loadingBar.finish()
        return response.data;
    },

    error => {
        window.$loadingBar.error()
        return Promise.reject(error.response);
    })

axios挂载消息提示

js 复制代码
// 响应拦截器
axios.interceptors.response.use(
    response => {
        window.$loadingBar.finish()
        window.$message.success('请求成功')
        return response.data;
    },

    error => {
        window.$loadingBar.error()
        window.$message.error('请求失败')
        return Promise.reject(error.response);
    })

目前这样就可以实现加载条和消息提示了

返回状态码

为了让不同的状态,显示不同的信息提示,所以在返回拦截中需要配置不同的状态码来返回内容

改进之后的返回拦截器:

js 复制代码
// 响应拦截器
axios.interceptors.response.use(
    response => {
        window.$loadingBar.finish()
        window.$message.success('请求成功')
        return response.data;
    },

    error => {
        window.$loadingBar.error()
        window.$message.error('请求失败')
        if (error.response.status ) {
            switch (error.response.status) {
                case 401:
                    window.$message.error('未登录')
                    router.push('/login')
                    break;
                case 403:
                    window.$message.error('没有权限')
                    break;
                case 404:
                    window.$message.error('请求错误')
                    break;
                case 500:
                    window.$message.error('服务器内部错误')
                    break;
                case 504:
                    window.$message.error('网络错误')
                    break;
                default:
                    window.$message.error('未知错误')
                    break;
            }
        }
        return Promise.reject(error.response);
    })

之后就是每个状态码对应的操作,比如我在这个401状态没登录的情况下去跳转到login页面进行登录等等操作。

相关推荐
skywalk81639 分钟前
言知项目后续方向建议
开发语言·学习·编程
拾年27528 分钟前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax
拉勾科研工作室42 分钟前
区块链工程毕业论文题目【249个】
开发语言·javascript
小林ixn44 分钟前
你以为你懂 + 号?看完这篇 Bun + TS 实战,才发现以前全写错了
前端·javascript·typescript
namexingyun1 小时前
开源前端生态如何成为 AI UI 生成的“燃料“:shadcn/ui、Tailwind CSS、Storybook 技术价值全解剖
java·前端·人工智能·python·ui·开源·ai编程
z落落1 小时前
C#WinForm控件实战:Panel与单选框动态创建
开发语言·c#
ptc学习者1 小时前
python 中描述符@property property 大概的样子
开发语言·python
zmzb01031 小时前
Python课后习题训练记录Day129
开发语言·python
张忠琳2 小时前
【Go 1.26.4】Golang Map 深度解析
开发语言·后端·golang
Vertira2 小时前
如何对QT开发的软件进行打包[已解决]
开发语言·qt