在项目的src文件夹下新建api文件夹,用于保存跟网络相关的文件
本次封装需要安装vantui、axios、vueX、md5.js
项目结构如下:
http.js封装axios的普通配置,连接超时时间、请求前后的判断与添加头部信息(token)
base.js封装接口的域名,方便域名更改时做统一的处理
user.js封装用户相关的请求数据
index.js对外统一暴露请求的地址
http.js文件如下
/**
* axios封装
* 请求拦截、响应拦截、错误统一处理
*/
import axios from 'axios';
import router from '../router';
import store from '../store/index';
// 这里需要安装vantui组件库 若没有安装vantui则将下面的Toast换成自己对应的弹窗组件即可
import { Toast } from 'vant';
/**
* 提示函数
* 禁止点击蒙层、显示一秒后关闭
*/
const tip = msg => {
Toast({
message: msg,
duration: 1000,
forbidClick: true
});
}
/**
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
*/
const toLogin = () => {
router.replace({
path: '/LoginPage',
query: {
redirect: router.currentRoute.fullPath
}
});
}
/**
* 请求失败后的错误统一处理
* @param {Number} status 请求失败的状态码
*/
const errorHandle = (status, other) => {
// 状态码判断
switch (status) {
// 401: 未登录状态,跳转登录页
case 401:
toLogin();
break;
// 403 token过期
// 清除token并跳转登录页
case 205:
tip('登录过期,请重新登录');
localStorage.removeItem('token');
// store.commit('LoginPage', null);
setTimeout(() => {
toLogin();
}, 1000);
break;
// 404 token验证失败
case 202:
tip('身份验证失败,请重新登录');
localStorage.removeItem('token');
// store.commit('LoginPage', null);
setTimeout(() => {
toLogin();
}, 1000);
break;
case 403:
tip('身份验证成功,但无权限访问');
// store.commit('LoginPage', null);
setTimeout(() => {
toLogin();
}, 1000);
break;
default:
console.log(other);
}}
// 创建axios实例
var instance = axios.create({ timeout: 1000 * 12});
// 设置post请求头
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
/**
* 请求拦截器
* 每次请求前,如果存在token则在请求头中携带token
*/
instance.interceptors.request.use(
config => {
// 登录流程控制中,根据本地是否存在token判断用户的登录情况
// 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token
// 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码
// 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。
let token = window.sessionStorage.getItem("appToken");
//const token = store.state.token;
token && (config.headers.token = token);
return config;
},
error => Promise.error(error))
// 响应拦截器
instance.interceptors.response.use(
// 请求成功
res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),
// 请求失败
error => {
const { response } = error;
if (response) {
// 请求已发出,但是不在2xx的范围
errorHandle(response.status, response.data.message ?? response.data.msg);
return Promise.reject(response);
} else {
// 处理断网的情况
// eg:请求超时或断网时,更新state的network状态
// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
// 关于断网组件中的刷新重新获取数据,会在断网组件中说明
if (!window.navigator.onLine) {
store.commit('changeNetwork', false);
} else {
return Promise.reject(error);
}
}
});
export default instance;
base.js文件如下:(有点乱,不过也大概是这么一个意思)
/**
* 接口域名的管理
*/
const base = {
// sq: 'https://localhost:44369', //本地开发时的测试地址
// sq:'http://192.168.5.1:4436', //本地服务器
sq:'http://www.hj0819.top:44369', //阿里云服务器 ,发布地址
bd: 'http://xxxxx22222.com/api',
ip: 'http://pv.sohu.com',
test: 'https://jsonplaceholder.typicode.com/posts/'
}
export default base;
user.js文件如下:
/**
* article模块接口列表
*/
import base from "./base"; // 导入接口域名列表
import axios from "./http"; // 导入http中创建的axios实例
import qs from "qs"; // 根据需求是否导入qs模块
//导入md5加密模块 不知为什么全局挂载的有问题
import md5 from "js-md5";
const user = {
// 检查用户名是否可用
LoginName(params) {
return axios.get(`${base.sq}/api/Verify/LoginName`, {
params: params,
});
},
// 检查手机号是否可用
verifyPhone(params) {
return axios.get(`${base.sq}/api/Verify/GetPhone`, {
params: params,
});
},
// post提交 登录
login(params) {
//md5加密
params.LoginPassword = md5(params.LoginPassword);
return axios.post(`${base.sq}/api/LoginPage/Login`, qs.stringify(params));
},
// 注册登录用户
AddLogin(params) {
params.LoginPassword = md5(params.LoginPassword);
return axios.post(
`${base.sq}/api/LoginPage/AddLogin`,
qs.stringify(params)
);
},
//修改用户密码 通过注册手机号码定位用户
PatchPWD(params) {
params.LoginPassword = md5(params.LoginPassword);
return axios.patch(
`${base.sq}/api/LoginPage/PatchPWD`,
qs.stringify(params)
);
},
//获取用户的详情数据
GetUserData() {
return axios.get(`${base.sq}/api/UserInfo/getUserData`);
},
//获取用户的ip地址
GetUserIP() {
return axios.post(`apis/cityjson?ie=utf-8`, {});
},
//上一个接口访问不了 改为下面的这个
GetUserIPNew() {
return axios.get(`http://myip.ipip.net/`);
},
//修改用户基础资料
patchUserData(params) {
return axios.patch(
`${base.sq}/api/UserInfo/patchUserData`,
qs.stringify(params)
);
},
// 添加收货地址
AddArea(params) {
return axios.post(`${base.sq}/api/UserInfo/addArea`, qs.stringify(params));
},
//获取用户的收货地址
GetUserArea() {
return axios.get(`${base.sq}/api/UserInfo/getArea`);
},
//修改用户的收货地址
patchUserArea(params) {
return axios.patch(
`${base.sq}/api/UserInfo/patchArea`,
qs.stringify(params)
);
},
//修改用户的收货地址为删除状态
deleteArea(params) {
return axios.patch(
`${base.sq}/api/UserInfo/deleteArea`,
qs.stringify(params)
);
},
};
export default user;
index.js文件如下:
/**
* api接口的统一出口
*/
// 用户 接口
import user from "./user";
// 导出接口
export default {
user,
// ……
};
main.js中做全局挂载
import Vue from 'vue'
import './plugins/axios'
import App from './App.vue'
import router from './router'
import api from "./api/index"; // 导入api接口
import store from './store'
// 将api挂载到vue的原型上
Vue.prototype.$api = api;
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
使用:
get无参:
//获取用户的信息
async getUserData() {
await this.$api.user
.GetUserData()
.then(res => {
//console.log(res);
if (res.data.code !== 200) {
return;
}
this.userData = res.data.data;
//console.log(this.userData);
})
.catch(res => {
return this.$message.error("网络连接失败");
});
},
get有参:
await this.$api.code.getCode(
{
phone : this.phone,
codeType : this.codeType
}
).then(res =>{
// console.log(res);
if(res.data.code != 200){
return this.$message.error('发送失败,请稍后再试!')
}
// 如果发送成功 取出服务器返回的验证码
this.authCode = res.data.msg
}).catch(err => {
return this.$message.error("是不是姿势不对,换个优雅的姿势吧");
});
post、put、patch差不多如下:
this.$refs.editUserRef.validate(async result => {
if (!result) {
console.log("验证不通过");
this.$message.error("信息有误");
return false;
} else {
await this.$api.user
.patchUserData({
//这里是参数列表
CustomerName: this.editUserData.CustomerName,
IdentityCardNo: this.editUserData.IdentityCardNo,
CustomerEmail: this.editUserData.CustomerEmail,
Gender: this.editUserData.Gender,
Birthday: this.editUserData.Birthday,
Name: this.editUserData.name,
Phone: this.editUserData.phone
})
.then(res => {
Toast.clear();
if (res.data.code !== 201) {
return this.$message.error(res.data.msg);
} else {
this.$message.success("修改信息成功");
return this.$router.push("/detailPage");
}
})
.catch(err => {
Toast.clear();
return this.$message.error("网络异常,请稍后重试");
});
}
有半年多了,忘了原文是哪篇了,大概记得好像是简书看到的
若有侵权请联系删除