《程序猿入职必会(7) · 前端请求工具封装》

CSDN 2024-08-17 13:03:01 阅读 80

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗

🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

写在前面的话前端请求工具封装封装思路实例 Demo细节说明

总结陈词

CSDN.gif

写在前面的话

前篇博文介绍了,前后端分离实战项目中,关于统一返回结果的封装。

本篇博文就接着介绍一下,前端 Axios 插件封装思路,以及对于这一返回封装结果的接受处理。

加油,程序猿,保持住Tempo,开干,玩的就是真实!

关联文章:

《程序猿入职必会(1) · 搭建拥有数据交互的 SpringBoot 》

《程序猿入职必会(2) · 搭建具备前端展示效果的 Vue》

《程序猿入职必会(3) · SpringBoot 各层功能完善 》

《程序猿入职必会(4) · Vue 完成 CURD 案例 》

《程序猿入职必会(5) · CURD 页面细节规范 》

《程序猿入职必会(6) · 返回结果统一封装》


前端请求工具封装

封装思路

Vue 项目中,可以使用的请求插件很多,这边选用之前已整合完毕的 Axios 展开说明,其他技术类似。

前端请求工具类应该具备哪些特性?

提取所有请求的公用部分,例如后端服务前缀、超时时间、公用请求头等具备请求前置拦截逻辑,可以针对请求头和参数进行封装,也可以做前端鉴权动作具备请求后置拦截逻辑,可以针对响应内容进行解析处理,针对不同状态码做出不同应对对外提供丰富便捷的调用方法,方便页面和组件快速使用

实例 Demo

这里先基于上述的封装思路,展示一段已实现的效果,再拆分说明。

【封装工具类】

<code>/**

* Http 请求封装工具类

* Axios是基于http客户端的promise,面向浏览器和NodeJS

* Created by LinWang on 2020/08/08.

*/

import axios from 'axios'

import qs from 'qs'

import store from '../store'

import { -- --> Message, MessageBox } from 'element-ui'

import { getToken } from '@/utils/auth'

import _ from 'lodash'

import { showFullScreenLoading, tryHideFullScreenLoading } from './loadService'

/**

* 创建Axios实例

*/

const service = axios.create({

baseURL: process.env.VUE_APP_BASE_API, timeout: process.env.TIME_OUT

})

service.all = axios.all

service.spread = axios.spread

/**

* 添加一个请求拦截器(前置)

*/

service.interceptors.request.use(config => {

showFullScreenLoading()

if (_.isObject(config.data)) {

config.data = qs.stringify(config.data, { allowDots: true })

}

config.headers['Content-Type'] = 'application/x-www-form-urlencoded' // 默认为 application/json

config.headers.operator = getToken() // 让每个请求携带自定义token,请根据实际情况自行修改

config.headers.requestId = new Date().getTime() // 请求时间点

return config

}, error => {

console.log(error)

Promise.reject(error)

})

/**

* 添加一个返回拦截器(后置处理)

*/

service.interceptors.response.use(response => {

tryHideFullScreenLoading()

const res = response.data

if (response.status !== 200 || !res.success) {

Message({

message: res.message, type: 'warning', duration: 5 * 1000

})

// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;

if (res.code === 50008 || res.code === 50012 || res.code === 50014) {

MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {

confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning'

}).then(() => {

store.dispatch('FedLogOut').then(() => {

location.reload() // 为了重新实例化vue-router对象 避免bug

})

})

}

return Promise.reject(res)

} else {

return res.data

}

}, error => {

tryHideFullScreenLoading()

console.log('err' + error)

Message({

message: error.error, type: 'warning', duration: 5 * 1000

})

return Promise.reject(error)

})

export default service

【框架整合工具类】

Tips:就main.js添加两行代码即可,$http是添加到全局,可以快速使用

import http from '@/utils/request'

Vue.prototype.$http = http

【某个实体对应 api.js - 代码生成】

import request from '@/utils/request'

export default {

getList(params) {

return request({

url: '/zyTeacherInfo/', method: 'get', params

})

},

get(params) {

return request({

url: '/zyTeacherInfo/' + params.teaCode, method: 'get', params

})

},

getPage(params) {

return request({

url: '/zyTeacherInfo/page', method: 'get', params

})

},

update(params) {

return request({

url: '/zyTeacherInfo/update', method: 'post', params

})

},

insert(params) {

return request({

url: '/zyTeacherInfo/insert', method: 'post', params

})

},

remove(params) {

return request({

url: '/zyTeacherInfo/delete', method: 'post', params

})

}

}

【页面使用示例】

// 引入api.js

import ZyTeacherInfoApi from '@/api/study/ZyTeacherInfoApi'

// 通过实体对应api.js,触发删除逻辑

handleDelete(row) {

let that = this

ZyTeacherInfoApi.remove({ teaCode: row.teaCode }).then(() => {

this.$notify({

title: '成功',

message: '删除成功',

type: 'success',

duration: 1000,

onClose() {

that.fetchData()

}

})

})

},

// 利用工具类的all方法,并联查询多个接口

this.$http.all([ZyTeacherInfoApi.getPage(this.listQuery)])

.then(this.$http.spread(function(perms) {

that.list = perms.rows

that.total = perms.total

that.listLoading = false

}))

细节说明

【基础 Axios】

整个请求工具类的核心就是 Axios。

使用 axios.create 创建一个 Axios 实例,然后设置后端服务前缀、超时时间等,这些属性都配置再项目配置文件中。

将 axios.all 和 axios.spread,添加到上述实例,方便快速复用。

代码段参考:

const service = axios.create({

baseURL: process.env.VUE_APP_BASE_API, timeout: process.env.TIME_OUT

})

service.all = axios.all

service.spread = axios.spread

【添加 Axios 请求拦截器】

利用 service.interceptors.request.use 添加请求拦截器,里面按如下步骤执行:

显示全屏 Loading 效果,这个是自己封装的,也可以采用外部插件;设置 Content-Type,按指定的入参类型组装参数;设置操作人、时间戳等其他请求头信息;

service.interceptors.request.use(config => {

showFullScreenLoading()

if (_.isObject(config.data)) {

config.data = qs.stringify(config.data, { allowDots: true })

}

config.headers['Content-Type'] = 'application/x-www-form-urlencoded' // 默认为 application/json

config.headers.operator = getToken() // 让每个请求携带自定义token,请根据实际情况自行修改

config.headers.requestId = new Date().getTime() // 请求时间点

return config

}, error => {

console.log(error)

Promise.reject(error)

})

【添加 Axios 响应拦截器】

利用 service.interceptors.request.use 添加请求拦截器,里面按如下步骤执行:

响应成功和失败,都需要关闭 Loading 效果;根据 code 状态码判断失败与否;如果是成功的话,将数据返回给调用方;如果是报错的话,返回报错信息给调用发,同时利用提示信息组件,展示提示;

service.interceptors.response.use(response => {

tryHideFullScreenLoading()

const res = response.data

if (response.status !== 200 || !res.success) {

Message({

message: res.message, type: 'warning', duration: 5 * 1000

})

// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;

if (res.code === 50008 || res.code === 50012 || res.code === 50014) {

MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {

confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning'

}).then(() => {

store.dispatch('FedLogOut').then(() => {

location.reload() // 为了重新实例化vue-router对象 避免bug

})

})

}

return Promise.reject(res)

} else {

return res.data

}

}, error => {

tryHideFullScreenLoading()

console.log('err' + error)

Message({

message: error.error, type: 'warning', duration: 5 * 1000

})

return Promise.reject(error)

})


总结陈词

此篇文章介绍了前端 Axios 插件封装思路,仅供学习参考。

Axios 官网用法很多,丰富多彩,但实战中,上述提供的示例已经覆盖了大部分常用用法了。

💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

CSDN_END.gif



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。