目录
前提
vue3和vue2axios封装差不多,对报错信息做了封装,错误处理进行了改进。
目录
utils
- request.js axios封装
- api.js 接口文件
- prompt.js 异常消息提示
- dictionary 接口请求数据统一处理
prompt.js 文件-异常消息提示封装
//提示框
import { ElMessage } from 'element-plus'
//数据类型,表示独一无二,用来做属性名,能保证不会与其他的属性名冲突
const prompt = Symbol('prompt')
export default class Prompt {
success (options, single = true) {
options.type = 'success'
this[prompt](options, single)
}
warning (options, single = true) {
options.type = 'warning'
this[prompt](options, single)
}
info (options, single = true) {
options.type = 'info'
this[prompt](options, single)
}
error (options, single = true) {
options.type = 'error'
this[prompt](options, single)
}
[prompt] (options, single) {
if (single) {
if (document.getElementsByClassName('el-message').length === 0 || document.getElementsByClassName('el-message')[0].style.display === 'none') {
ElMessage(options)
}
} else {
ElMessage(options)
}
}
}
dictionary.js文件
-
请求数据统一处理
// 请求头-内容类型
export const ContentType = {
JSON: 'application/json;charset=UTF-8',
FORM: 'application/x-www-form-urlencoded;charset=UTF-8',
UPLOAD: 'multipart/form-data',
STREAM: 'application/octet-stream;charset=UTF-8'
}
// 令牌键值
export const TokenKey = {
TOKEN: 'token',
ACCESS: 'access'
}
// 本地存储类型
export const StorageType = {
COOKIE: 'cookie',
SESSION: 'sessionStorage',
LOCAL: 'localStorage'
}
// 请求成功状态码
export const SuccessCode = {
ZERO: 0,
TWO_HUNDRED: 200
}
// 请求 mapping
export const RequestMapping = {
SLIPPER: '/slipper',
API: '/api'
}
// 双向绑定名
export const ModelBinding = {
MODEL_VALUE: 'update:modelValue',
MODEL_EVENT: 'update:modelEvent'
}
// 主题模式
export const ThemeMode = {
DARK: 'dark',
LIGHT: 'light'
}
request.js文件
- axios请求拦截器
- axios响应拦截器
import axios from 'axios'
import router from '../router'
// import qs from "qs"
import Prompt from './prompt.js'
import { ContentType,SuccessCode } from './dictionary'
//异常消息提示
const prompt = message => {
new Prompt().warning({
message: message,
type: 'warning',
duration: 3000
})
}
//code处理
const codeHandle = (code, message) => {
switch (code) {
case 4001:
prompt(message)
store.dispatch('logout')
router.replace({
name: 'login'
})
break
case 401:
router.replace({
name: '401'
})
break
case 403:
router.replace({
name: '403'
})
break
case 404:
router.replace({
name: '404'
})
break
case 500:
router.replace({
name: '500'
})
break
default:
prompt(message)
break
}
}
//axios请求拦截器
axios.interceptors.request.use(
config => {
return config
},
error => {
console.log(error) // for debug
return Promise.reject(error)
}
)
//axios响应拦截器
axios.interceptors.response.use(
response => {
//判断头部
if (response.headers['content-type'] === ContentType.STREAM) {
return response.data || null
}
//正常返回code码之后的处理
const SUCCESS_CODE = [SuccessCode.ZERO, SuccessCode.TWO_HUNDRED]
if (!SUCCESS_CODE.includes(code)) {
codeHandle(code, message)
return null
}
return response || null
},
error => {
if (error && error.response) {
switch (error.response.status) {
case 400:
console.log('错误请求')
break
case 401:
console.log('未授权,请重新登录')
break
case 403:
console.log('拒绝访问')
break
case 404:
console.log('请求错误,未找到该资源')
break
case 405:
console.log('请求方法未允许')
break
case 408:
console.log('请求超时')
break
case 411:
console.log('需要知道长度')
break
case 413:
console.log('请求的实体太大')
break
case 414:
console.log('请求的URL太长')
break
case 415:
console.log('不支持的媒体类型')
break
case 500:
console.log('服务器端出错')
break
case 501:
console.log('网络未实现')
break
case 502:
console.log('网络错误')
break
case 503:
console.log('服务不可用')
break
case 504:
console.log('网络超时')
break
case 505:
console.log('http版本不支持该请求')
break
default:
console.log(`连接错误${ error.response.status }`)
}
} else {
console.log('连接到服务器失败')
router.replace({
name: '500'
})
}
return Promise.reject(error)
}
)
//post
export function post(url, params) {
return new Promise((resolve, reject) => {
axios({
url: url,
method: 'post',
data: params,
timeout: 1000 * 60,
headers: {
'Content-Type': 'application/json;charset=utf-8',
// 'token': Dcookie.getCookie('token'),
}
})
.then(res => {
if (res.data.code == 1000) {
prompt(res.data.msg)
localStorage.clear();
router.push({
path: "/"
});
} else {
resolve(res.data);
}
})
.catch(err => {
reject(err)
});
});
}
api.js文件
- 引用request.js文件中接口函数post
- 进行接口统一管理
//接口统一管理
import { post } from './request.js'
//登录
export const userLogin = params => post('/api/user/login', params);
//退出
export const logout = params => post('/api/user/logout', params);
//角色列表
export const roleList = params => post('/power-dev/role/list', params);
//角色添加
export const roleInsert = params => post('/power-dev/role/insert', params);
引用
引用api文件中接口函数menuList,传入入参
额外说明方法和函数的区别:
1)函数是一段代码,通过名字来进行调用。它能将一些数据(参数)传递进去进行处理,然后返回一些数据(返回值),也可以没有返回值。所有传递给函数的数据都是显式传递的。函数和对象无关。
2)方法也是一段代码,也通过名字来进行调用,但它跟一个对象相关联。
3)方法是特殊的函数,可以说是函数的子集。
4)方法常常是和类有关的,是面向对象语言中会用到的,需要通过对象或类调用。
5)函数是指一段可以直接被其名称调用的代码块,它可以传入一些参数进行处理并返回一些数据,所有传入函数的数据都是被明确定义。
引用代码:
import {
menuList
} from "@/utils/api.js";
//获取表格列表数据
const getAllListLink = () => {
let params = {
pageNum: data.curPage,
pageSize: data.pageSize,
}
menuList(params).then(res => {
if (res.code == 0) {
data.dataCount = res.data.total
if (res.data.total != 0) {
data.historyData = res.data.list;
} else {
data.dataText = "暂无数据";
}
} else if (res.code !== 0) {
data.dataText = "暂无数据";
ElMessage({
showClose: true,
message: res.msg,
type: 'error',
})
}
})
};