vue 封装axios网络请求(记录)

在项目的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("网络异常,请稍后重试");
      });
  }

有半年多了,忘了原文是哪篇了,大概记得好像是简书看到的

若有侵权请联系删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值