vue的axios配置与api封装
程序员文章站
2022-07-02 16:54:09
...
话不多少,上代码(fetch文件):
import Vue from 'vue'
import axios from 'axios'
import Store from '../vuex/store.js' //运用到Vuex可使用
const QS = require('qs')
/**
* 开发配置baseUrl
*/
// const PRIVARY_URL = '/quality' // 生产
const PRIVARY_URL = '/dev' // 开发
/**
*
* 生产配置baseUrl
*/
const PROXY_URL = '/qualitydev'
axios.defaults.baseURL = process.env.NODE_ENV === 'production' ? PROXY_URL : PRIVARY_URL
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
Vue.prototype.$baseUrls = axios.defaults.baseURL
axios.defaults.timeout = 30000
// 重新请求
axios.defaults.retry = 360
axios.defaults.retryDelay = 10000
let pending = [] // 声明一个数组用于存储每个 ajax 请求的取消函数和ajax标识
let CancelToken = axios.CancelToken
let removePending = (ever) => {
/**
* TODO: 对极短时间内相同的重复请求拦截,阻止请求(防止按钮重复点击,发出多次相同请求)
*/
for (let p in pending) {
if (pending[p].u === ever.url + '&' + ever.method + '&' + JSON.stringify(ever.params)) { // 当当前请求在数组中存在时执行函数体
// pending[p].cancle('重复操作') // 执行取消操作
pending.splice(p, 1) // 把这条记录从数组中移除
}
}
}
var vue = new Vue()
// Add a request interceptor
//请求拦截器
axios.interceptors.request.use(
config => {
//每个请求都有的默认的参数,可以是登陆之后的用户信息
const appId = 'QUALITY_WEB'
let user = (new Vue())._util.getUser()
if (user) {
const userKey = user.userKey
config.params = {
userKey,
appId,
...config.params
}
//请求头封装参数
config.headers.userId = user.id
config.headers.token = user.userKey
} else {
config.params = {
appId,
...config.params
}
}
removePending(config) // 在一个ajax发送前执行一下取消操作
config.cancelToken = new CancelToken((c) => {
// 这里的ajax标识是用请求地址&请求方式&请求参数拼接的字符串,也可以选择其他的一些方式
pending.push({ u: config.url + '&' + config.method + '&' + JSON.stringify(config.params), cancle: c })
})
return config
},
error => {
return Promise.reject(error)
}
)
// Add a response interceptor
//响应拦截
axios.interceptors.response.use(
response => { // 如果返回的数据中status不为1,则全局警告
// ------------------------------------------------------------------------------------------
removePending(response.config) // 在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
// ------------------------------------------------------------------------------------------
if (response.data && response.data.status !== 1) {
if (response.data.message) {
myMessage.warning(response.data.message)
}
// 登录失效
if (response.data.status === 0) {
Store.commit('SET_USER', null)
Store.commit('screen_boo', false)
}
}
vue.$loading.hide()
return response
},
error => { // 返回状态码不为200时候的错误处理
// var RetryNetwork = function () {
// let config = error.config
// // If config does not exist or the retry option is not set, reject
// if (!config || !config.retry) return Promise.reject(error)
// // Set the variable for keeping track of the retry count
// config.__retryCount = config.__retryCount || 0
// // Check if we've maxed out the total number of retries
// if (config.__retryCount >= config.retry) {
// // Reject with the error
// return Promise.reject(error)
// }
// // Increase the retry count
// config.__retryCount += 1
// // Create new promise to handle exponential backoff
// let backoff = new Promise(resolve => {
// setTimeout(() => {
// resolve()
// }, config.retryDelay || 3000)
// })
// return backoff.then(function () {
// // check config.url and then remove the baseUrl from cinfig.url
// let reg = new RegExp(config.baseURL)
// config.url = config.url.replace(reg, '')
//
// return axios(config)
// })
// }
// vue.$loading.button()
if (error.message === '重复操作') {
// myMessage.error('请勿多次重复操作')
setTimeout(() => {
vue.$loading.hide()
}, 1000)
}
// 有一种可能是断网了
if (!error.response && error.message !== '重复操作') { // 超时
myMessage.error('断网--请求超时, ::NET-DISCONNECT')
// RetryNetwork()
setTimeout(() => {
vue.$loading.hide()
}, 1000)
}
if (error && error.response && error.response.status) {
switch (error.response.status) {
case 400:
myMessage.error('请求错误')
break
case 401:
myMessage.error('未授权,请登录')
break
case 403:
myMessage.error('拒绝访问')
break
case 404:
myMessage.error('请求路径出错: 404 NOT FOUND')
// RetryNetwork()
break
case 408:
myMessage.error('请求超时, ::CODE 408')
break
case 500:
myMessage.error('服务器内部错误')
break
case 501:
myMessage.error('服务未实现')
break
case 502:
myMessage.error('网关错误')
break
case 503:
myMessage.error('服务不可用')
break
case 504:
myMessage.error('网关超时, ::SERVER 504')
// RetryNetwork()
break
default:
myMessage.error('未知错误', error.response.status)
break
}
setTimeout(() => {
vue.$loading.hide()
}, 1000)
}
return Promise.reject(error)
}
)
function transformRequest (data, options) {
let temp = data
// 把一个参数对象格式化为一个字符串
if (!options.isJson) {
temp = QS.stringify(data)
}
// 上传用formData封装
if (options.isUpload) {
let formData = new FormData()
for (let key in data) {
formData.append(key, data[key])
}
temp = formData
}
return temp
}
export default axios(url = '', params = {}, method = 'get', options = { isUpload: false, isJson: false }) => {
if (!params.hideLoading) {
vue.$loading.show()
}
method = method.toLowerCase()
if (method === 'get') {
let paramArr = []
for (let [key, value] of Object.entries(params)) {
paramArr.push(key + '=' + value)
}
if (paramArr.length > 0) {
url += '?' + paramArr.join('&').replace(/#/g, '%23')
}
return new Promise((resolve, reject) => {
axios
.get(url)
.then(
response => {
resolve(response.data)
},
err => {
reject(err)
}
)
.catch(error => {
reject(error)
})
})
} else if (method === 'post') {
let config = {}
if (options.isUpload) {
config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
}
// should we use type:'application/x-www-form-urlencoded' to send the data?
params = transformRequest(params, options)
return new Promise((resolve, reject) => {
axios
.post(url, params, config)
.then(
response => {
resolve(response.data)
},
err => {
reject(err)
}
)
.catch(error => {
reject(error)
})
})
} else if (method === 'put') {
return new Promise((resolve, reject) => {
axios
.put(url, params)
.then(
response => {
resolve(response.data)
},
err => {
reject(err)
}
)
.catch(error => {
reject(error)
})
})
} else if (method === 'delete') {
return new Promise((resolve, reject) => {
axios
.delete(url)
.then(
response => {
resolve(response.data)
},
err => {
reject(err)
}
)
.catch(error => {
reject(error)
})
})
} else {
let error = '传递的参数错误'
return Promise.reject(error)
}
}
api层级封装(index文件):
import fetch from './fetch'
// 教师端 首页
import teacherHome from './xxxx'
// 教师端 项目化学习方案定义
import teacherLearn from './xxxxx'
// 教师端 项目化学习课程实例
import teacherCourse from './xxxxx'
// 教师端 实践活动
import teacherPractica from './xxxxxx'
// 教师端 日常评价
import teacherEvaluation from './xxxxxxx'
// 教师端 学生个体评价
import teacherIndividual from './xxxxxx'
// 教师端 平台入口
import teacherPlatform from './xxxxxxxx'
// 教师端 权限管理
import teacherAuthority from './xxxxxxx'
// 导入数据
import guidedData from './xxxxxxxx'
// 学生端
import studentCourse from './xxxxxxx'
// 教师端综评管理
import teacherMament from './xxxxxx.js'
// 教师端学习任务
import teacherStudyTask from './xxxxxxxx.js'
// 教师端体质健康
import teacherHealth from './xxxxxxx.js'
import teacherCreateRecords from './xxxxxxxxxxx'
export default {
login (deviceId, account, password) {
return fetch(`/xxxxxx`, { deviceId, account, password }, 'get')
},
smsUpdatePhone (id, deviceId, phone, zone, verifyCode, system, appId) { // 绑定手机号
return fetch('newUser/xxxxxxx', {id, deviceId, phone, zone, verifyCode, system, appId}, 'get')
},
sendMsg (phone, zone, system) { // 发送短信
return fetch('user/xxxxx', {phone, zone, system}, 'get')
},
smsLogin (deviceId, phone, zone, verifyCode, system) { // 手机号登录
return fetch('/newUser/xxxx', {deviceId, phone, zone, verifyCode, system}, 'get')
},
getToken (bucketType, fileType) {
return fetch('file/xxxx', { bucketType, fileType }, 'post')
},
qnUpload (key, token, file) {
return fetch('https://upload.qiniu.com', { key, token, file }, 'post', { isUpload: true })
},
findGradeSubjects () {
return fetch('/school/check/xxxxxxx', {}, 'get')
},
findSchoolInfo () {
return fetch('schoolInfo/check/xxxxxxxx', { }, 'get')
},
systemlogin (systemUserId) {
return fetch('userSystemInfo/xxxxxxx', {systemUserId}, 'post', { isUpload: true })
},
...teacherHome,
...teacherLearn,
...teacherCourse,
...teacherPractica,
...teacherEvaluation,
...teacherIndividual,
...teacherPlatform,
...teacherAuthority,
...guidedData,
...studentCourse,
...teacherMament,
...teacherStudyTask,
...teacherHealth,
...teacherCreateRecords
}
某一个页面接口文件:
import fetch from './fetch'
export default {
// 任务实例
getCourseTask (type, time) {
return fetch('course/check/xxxxx', {type, time}, 'get')
},
// 开课获取课程列表的接口
getCourseList (subject) {
return fetch('course/check/xxxxx', {subject}, 'get')
},
// 根据年级学科,获取教师名单
getGradeSubject (grade, subject, hideLoading = true) {
return fetch('user/check/xxxxxxxx', {grade, subject, hideLoading}, 'get')
},
// 学生导入
inputStudent (students, grades) {
return fetch('course/check/xxxxxxxx', {students, grades}, 'post', {isUpload: true})
},
// 开课请求
startCourse (courseId, ownerId, teacherIds, groupCount, studentIds, errorList) {
return fetch('course/check/xxxxxxxx', {courseId, ownerId, teacherIds, groupCount, studentIds, errorList}, 'post', {isJson: true})
}
在main.js中全局注册:
...
import axios from '@/http'
...
Vue.prototype.$http = axios
...
上一篇: vue-axios简单使用
下一篇: Java垃圾收集算法