Axios - 基于 Vue + Element 请求封装
前言
当然,其他
React
或UI
框架可作为参考。
本文基于 Axios
请求库,封装全局能通过 this(挂载到Vue实例上)
全局调用的请求(非集中式 API 管理模式 )。
其中,包含以下功能:
- baseURL
- 超时时间
- headers
- 开发环境切换
请求结果处理
// 最终全局调用方式(以POST请求为例)
// 只需关心调用成功(状态码正确)处理
this.$post(‘v1/user_admin/login’,
{ phone: ‘13191835102’, password: ‘wjb20’ })
.then((response) => {console.log(response)
})
一、安装 Axios
这里不多做介绍
npm install axios
二、新建 http.js
在
src
下新建一个utils
文件夹,创建http.js
文件,命名无所谓。该示例只封装了
POST
请求,其他请求类似。
在该文件中,写入以下代码,请根据 路径及命名 随机应变。
// axios
import axios from 'axios'
// 引入路由(对异常状态码做出跳转页面处理)
// 例如 [登录已过期]: 拦截到后跳转到登录页面
import router from '../router/index'
// 引入 elementui 提示框组件(根据你的UI框架来)
// 例如 [登录已过期]: 需要给用户弹出提示框来告知用户
import { Message, MessageBox } from 'element-ui'
// 获取token/uid(一般都会在请求携带token/uid等信息)
// [如果你的服务端接口没有做这件事那不需要]
var token = localStorage.getItem('token')
var uid = localStorage.getItem('uid')
// 开发环境切换(基本分为开发环境与线上环境)
// 用一个标识很轻松就能切换服务器接口地址
var debug = true//标识
var baseURL//baseURL
if(!debug) {
baseURL = 'https://api.xxx.com/'//线上接口
}else{
baseURL = 'https://dev.xxx.com/'//线下接口
}
// 配置请求基本信息(详见文档 | 这里只做了简单的配置)
// baseurl / 超时时间(5秒) /
axios.defaults.baseURL = baseURL
axios.defaults.timeout = 7000
/** * POST - 请求封装 * @param url * @param data * @returns Promise */
export function post(url, data = { }){
// headers(携带token)
axios.defaults.headers.common['token'] = token
// data 公共参数设置(例如token)
// 如果你的服务端接口没有规定则不需要以下操作
// [每次请求接口 data 数据必须携带的参数]
// data.uid = uid
// data.token = token
// data.model = 'Browser'
// data.platform = 'H5'
return new Promise((resolve, reject) => {
axios.post(url, data)
// 请求成功回调
.then(response => {
// 拿到结果先对状态码进行对应处理(调用下方函数)
// 传入状态码给处理函数即可(code)
serveCode(response.data.code)
// ok(正常返回)
resolve(response.data);
},
// 请求失败回调
err => {
// 请求失败后(做一个弹出框提示用户)
// 当然也可以做其他操作
Message({
showClose: true,
duration: '10000',
message: '请求失败(可能是网络问题)',
type: 'error'
})
reject(err)
})
})
}
/** * GET - 请求封装(与POST请求一样 | axios.get) * @param url * @param data * @returns Promise */
// ...
/** * DELETE - 请求封装(与POST请求一样 | axios.delete) * @param url * @param data * @returns Promise */
// ...
/** * 状态码处理 * @param {Number} code - 状态码 * @return void */
function serveCode(code) {
switch(code){
// 无权限访问,请尝试重新登录
case 1001 :
// elementUI 提示框
MessageBox.alert('为了您的账号安全,请重新登录系统', '登录已过期', {
type: 'error',
confirmButtonText: '我知道了',
showClose: false,
center: true
})
// 用户点击确认框
.then(() => {
// 做一些事情...
// 例如登录已经过期了(清除缓存)
// localStorage.removeItem('token')
// localStorage.removeItem('uid')
// 最后跳转到登录页
// router.push('/login')
})
break;
// 其他状态码情况处理
// ...
}
}
三、挂载到 Vue 实例
该步骤会获得全局
this
调用请求。
打开根目录下的 main.js
,加入以下代码:
// 引入封装好的请求(注意路径)
import { post } from './utils/http'
// 如果存在多个请求封装则以下方式引入
// import { post, get } from './utils/http'
// 挂载到 Vue 实例
Vue.prototype.$post = post
// 如果存在多个请求封装则以下方式挂载
// [或者: 将这些零散的请求归类在一个对象上访问]
// [例如: this.$http.post() | this.$http.get()]
// Vue.prototype.$post = post
// Vue.prototype.$get = get
四、使用方法
this.$post('v1/user_admin/login',
{ phone: '13191835102', password: 'wjb20' })
.then((response) => {
console.log(response)
})
五、写在后面
你无需考虑,接口返回数据不正常的情况(因为出现状态码不正常的情况下会自动做出处理),当然也没有配置拦截器,主要以简洁为主。
其他示例:
import axios from 'axios'
// import qs from 'qs'//序列化post类型数据
// router
import router from '../router/index'
// alert
import { Message, MessageBox } from 'element-ui'
// data加密函数
import { createSign } from '../lib/createSign'
// 环境切换
var debug = true//标识
var baseURL//baseURL
if(debug) {
// baseURL = 'http://192.168.124.169:8080/'// 线上
// baseURL = 'http://192.168.124.7:8080/'// 线上
baseURL = "https://iot.lkxdiot.com/"
}else{
// baseURL = 'http://192.168.124.7:8080/'// 线上
baseURL = 'https://api.lkxdiot.com/'// 线下
// baseURL = "http://192.168.124.7:8080" //
}
// baseurl / 超时时间(5秒) / headers(携带token)
axios.defaults.baseURL = baseURL
axios.defaults.timeout = 7000
/** * 封装post请求 * @author 王佳斌 * @param url * @param data * @returns {Promise} */
export function post(url, data = { }, isExport = { }){
// 设置头
axios.defaults.headers.common['token'] = localStorage.getItem('token')
// 设置token
data.token = localStorage.getItem('token')
// 设置uid
data.uid = localStorage.getItem('uid')
// 设置level
data.level = localStorage.getItem('level')
data.model = "Browser"
data.platform = 'H5'
data.company_id = localStorage.getItem('company_id')
// 判断token是否为空
if(localStorage.getItem('token') != '')
{
data = createSign(localStorage.getItem('token'), data)
}
return new Promise((resolve, reject) => {
axios.post(url, data,isExport)
// success
.then(response => {
// 根据状态码进行对应处理
serveCode(response.data.code)
// ok
resolve(response.data);
},
// error
err => {
Message({
showClose: true,
duration: '10000',
message: '通信失败(可能是网络问题)',
type: 'error'
})
reject(err)
})
})
}
/** * 服务器返回-状态码处理 * @author 王佳斌 * @param {Number} code - 状态码 * @return void */
function serveCode(code) {
switch(code){
// 无权限访问,请尝试重新登录
case 1001 :
MessageBox.alert('为了您的账号安全,请重新登录系统', '登录已过期', {
type: 'error',
confirmButtonText: '我知道了',
showClose: false,
center: true
}).then(() => {
// 清除缓存(token/uid)
localStorage.removeItem('token')
localStorage.removeItem('uid')
// 跳转到登录页
router.push('/login')
})
break;
}
}
还没有评论,来说两句吧...