美文网首页
VUE自定义通用接口配置

VUE自定义通用接口配置

作者: 小碗吃不了 | 来源:发表于2019-12-21 17:20 被阅读0次

常用axios安装和引用

  • 安装axios

    npm install axios  --save-dev
    npm install vue-axios --save-dev //结合vue-axios使用
    

axios中文文档

  • 引用

    //在index.html中引用
    <script src="https://cdn.bootcss.com/vue/2.5.2/vue.js"></script>
    <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.js"></script>
    <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script>
    <script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
    <script src="/static/js/jsonlint.js"></script>  //转long类型 转义JSON
    
    
    //在入口文件main.js引入
    import axios from 'axios'
    import VueAxios from 'vue-axios'
    //依靠vue-axios插件式引用
    Vue.use(VueAxios,axios);
    this.axios.get('api/getNewsList').then((response)=>{}).catch((response)=>{})
    
    //或挂载在Vue的原型上
    Vue.prototype.$ajax= axios
    this.$ajax.get('api/getNewsList').then((response)=>{}).catch((response)=>{})
    

通用配置详细记录

  • 在根目录src下自建api文件夹(个人习惯:把统一配置单独存放)

  • 在api文件下分别新建api.js和http.js

  • 在http.js下详细配置接口

    //http.js
    import axios from 'axios';
    import Crypto from './crypto';//加密
    import Router from '../../router/index';//导入路由
    import store from "../../store" //引入vuex
    //用于存放开发、测试、正式地址,可写多个,按需使用
    let baseUrl = "http://192.168.0.156:155";
    //或在全局的 axios 设置默认值
    axios.defaults.timeout = 6000;
    //修改响应数据
    axios.defaults.transformResponse = [
      function (res) {
          //此处用于识别换行符
          res = res.replace(/%n|\\n/gm, '<br />')
         //转义emoji表情
        var reg = /\\uD83C[\\uDF00-\\uDFFF]|\\uD83D[\\uDC00-\\uDE4F]/g;
        if (reg.test(res)) {
          res = res.replace(/\\/g, "%");
            // res = res.replace(/%n/g, "");
          res = unescape(res);//unescape解码字符串,escape编码字符串使计算机上读取该字符串
      }
        // 转换long类型为string 防止溢出;
          return jsonlint.parse(res);
      }
    ]
    //请求头配置(依据实际项目配置)
    export let headersConfig = {
        'sign': escape(Crypto.encryptByDES("jU7dDd0+68" + new Date().getTime(), "k8!MZms@")),//根据项目配置加密
        'ver': '1.0.6',
        'os': 'web',
        'Content-Type': 'application/json'
    };
    //创建实例
    let MainAxios = axios.create({
      baseURL: baseUrl,
      timeout: 6000,//设置超时
    });
    /**
     * get方法,对应get请求
       * url [请求的url地址]
       * params [请求时携带的参数]
     **/
    export function Get(url, params) {
      if (!params) {
        params = ""
    }
    return new Promise(function (resolve, reject) {
      MainAxios.get(url, {
        headers: headersConfig,
        params: params //axios的get请求传参使用params
      })
      .then(res => {
        resolve(res.data);
      })
      .catch(err => {
        reject(err.data)
      })
    })
    }
    
    /**
     * post方法,对应post请求
     * @param {String} url [请求的url地址]
     * @param {Object} params [请求时携带的参数]
     */
    export function Post(url, params) {
      return new Promise((resolve, reject) => {
        if (!params) {
          params = {}
      }
      MainAxios.post(url, params, {
        headers: headersConfig
      }).then(res => {
        resolve(res.data);
      })
      .catch(err => {
        reject(err.data)
      })
    });
    }
    
     /**
      * 解决请求重复提交并进一步封装全系统重复请求拦截
     */  
    let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
    let cancelToken = axios.CancelToken; //指定用于取消请求的 cancel token
    let removeRepeatUrl = (ever) => { //声明一个方法
      for(let p in pending){
          if(pending[p].u === ever.url + '&' + ever.method) { //当前请求在数组中存在时执行函数体
              pending[p].f(); //执行取消操作
              pending.splice(p, 1); //把这条记录从数组中移除
          }
      }
    }
    
    // 请求拦截器
    MainAxios.interceptors.request.use(config => {
       //在一个ajax发送前执行一下取消操作
       removeRepeatUrl(config); 
       config.cancelToken = new cancelToken((c)=>{
           // 自定义唯一标识 f:方法简写 c:内置cancel方法
          pending.push({ u: config.url + '&' + config.method, f: c });  
       });
    
      //根据项目而定,配置token,一般在登录注册接口本地存储token
      let token = localStorage.getItem('token');
      if (token) {
          config.headers['Authorization'] = token;
      }
       return config
     }, err => {
         return Promise.reject(err)
    })
    
    // 响应拦截器
    MainAxios.interceptors.response.use(response=> {
      removeRepeatUrl(response.config);  //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
       //设置找不到默认页面
       if (response.data.status == 50001) {
        Router.push({
          path: "/NothingFind",
          replace: true,
          query: {
            title: Router.history.current.meta.title //用于设置找不到页面标题
          },
    });
      return Promise.resolve(response);
    }, err => {
      // 服务器状态码不是200的情况
      if (error.response.status) {
      switch (error.response.status) {
      // 401: 未登录
      // 未登录则跳转登录页面,并携带当前页面的路径
      // 在登录成功后返回当前页面,这一步需要在登录页操作。
      case 401:
        store.commit('del_token');
        setTimeout(() => {
          // 如果有多个接口出现401 保证只执行一次弹出登录
          if (!Router.history.current.query.lastPage) {
            Router.push({
              path: "/Login",
              replace: true,
              query: {
                lastPage: Router.history.current.path,
                query: JSON.stringify(Router.history.current.query)
              } // 将跳转的路由path作为参数,登录成功后跳转到该路由
            });
          }
        }, 600);
        break;
      // 403 token过期
      // 登录过期对用户进行提示
      // 清除本地token和清空vuex中token对象
      // 跳转登录页面
      case 403:
        // 清除token
        store.commit('del_token');
        // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
        setTimeout(() => {
          // 如果有多个接口出现403 保证只执行一次弹出登录
          if (!Router.history.current.query.lastPage) {
            Router.push({
              path: "/Login",
              replace: true,
              query: {
                lastPage: Router.history.current.path,
                query: JSON.stringify(Router.history.current.query)
              } // 将跳转的路由path作为参数,登录成功后跳转到该路由
            });
          }
        }, 600);
        break;
      // 404请求不存在
      case 404:
        console.log('网络请求不存在')
        break;
      // 其他错误,直接抛出错误提示
      default:
        console.log(error.response.data.message)
    }
      return Promise.reject(error.response);
    }
      return Promise.reject(error)
    })
    
  • 附录store关于token删除写法

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    export default Vue.prototype.$store = new Vuex.Store({
      state: {
        token: "",
      },
      getters:{},
      mutations: {
            //存储token
            set_token(state, token) {
                  state.token = token;
                  localStorage.token = token
             },
            //删除token
            del_token(state) {
              state.token = '';
              localStorage.removeItem('token')
          }
      }  
    })
    
  • 在api.js下配置接口

    import {
        Get,
        Post
    } from './http'
    
    //例如 get post请求
    let getVerificationCode = function (params) {
      return Get('/v1/usercenter/personalData/getCode', params)
    }
    let Login = function (params) {
      return Post('/v2/system/auth/loginBySMS', params)
    }
    
    export const dataApi = {
       getVerificationCode: getVerificationCode,
       Login: Login
    };
    
  • 在入口文件main.js中挂载

    import Vue from 'vue'
    import {dataApi} from '@/api/api';
    // 全局挂载Api
    Vue.prototype.$Api = {
        dataApi: dataApi,
    };
    
  • 具体使用

    //formData传参
    this.$Api.dataApi
        .Login(formData)
        .then(res => {
          console.log(res )
       })
       .catch(err => {
          console.log(err)
       });
    
图解

相关文章

网友评论

      本文标题:VUE自定义通用接口配置

      本文链接:https://www.haomeiwen.com/subject/jckenctx.html