博客
关于我
vue-axios的总结及项目中的常见封装方法。
阅读量:518 次
发布时间:2019-03-08

本文共 9796 字,大约阅读时间需要 32 分钟。

前言

  我们知道 vue 2.0版本开始推荐使用 axios 来完成前端 ajax 请求,axios 是一个基于Promise 的 http 库,可以用在浏览器和 node.js 中,axios 成为vue全家桶的一个重要部分,对前后端接口请求起着必不可少的作用,本文主要总结一下 axios 的一些小知识点和项目中常见的需要封装的方法。

正文

  1.axios 是什么?

  axios 是一个基于 Promise 的 http 库,可以用于浏览器和 node.js 中,在浏览器中创建 XMLHttpRequest 对象(基于ajax的一种封装),然后调用该对象的一些方法实现对后端数据接口的请求,在 node.js 中用于创建 http 请求,支持 Promise Api,可以使用 async/await 语法糖书写,便于拦截请求和响应,并对请求和响应的数据进行处理,自动转换 JSON 数据格式,同事用于客户端支持防御 XSRF。且目前主流浏览器都支持该库。

  常见的安装方式有以下两种:

  (1)使用 cdn 方式,代码中直接引入下面脚本即可,这种方式适用于小型项目,比如学习的小 demo 等。

 

  (2)使用 npm 方式,直接在命令行中添加即可。

npm install axios

 

  2.axios 常见用法?

  axios中常用的请求配置如下,只有指定的url是必须项,其他存在默认配置项,method不特殊指定,默认方法为 get 。

  {    url: '/user',   // `url` 是用于请求的服务器 URL     method: 'get',   // default `method` 是创建请求时使用的方法    baseURL: 'https://some-domain.com/api/',   // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL    headers: {'X-Requested-With': 'XMLHttpRequest'},   // `headers` 是即将被发送的自定义请求头    params: {      ID: 12345    },   // 必须是一个无格式对象(plain object)或 URLSearchParams 对象,`params` 是即将与请求一起发送的 URL 参数    timeout: 1000,   // 如果请求话费了超过 `timeout` 的时间,请求将被中断,`timeout` 指定请求超时的毫秒数(0 表示无超时时间)    withCredentials: false,   // default `withCredentials` 表示跨域请求时是否需要使用凭证    responseType: 'json',   // default `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'    responseEncoding: 'utf8', // default    onUploadProgress: function (progressEvent) {   // `onUploadProgress` 允许为上传处理进度事件  // Do whatever you want with the native progress event    },    onDownloadProgress: function (progressEvent) {   // `onDownloadProgress` 允许为下载处理进度事件  // 对原生进度事件的处理    },  }

  (1)get 请求

 

axios.get('url',{params:{        //这里是请求参数    }})    .then(res=>{     //这里是响应后操作    })    .catch(err=>{     //异常捕获    })

 

  (2)post 请求

axios.post('url',{          name:xxx//参数      },{          headers:xxxx,//请求头信息    })    .then(function(res){          //处理成功的函数 相当于success    })    .catch(function(error){          //错误处理 相当于error    })

  (3)all、spread 并发请求

axios.all([    axios.get('url'),    axios.get('url',{params:{type:'sell',page:1}})    ])    .then(axios.spread((res1,res2)=>{        //返回结果为一个数组    }))

  all()方法入参为一个数组,数组元素是每一项请求,回调函数 .then() 的参数也是一个数组,里面的每一项元素表示前面请求的返回结果,使用了 axios.spread作为该回调函数的参数时,其res1,res2分别代表前面每一项请求的返回结果。

  综上这些方法都只使用于小型项目中,或者学习小 demo 中,在工作开发中遇到处理的请求接口较多,

 

  3.axios 在项目中的常见用法?

  (1)小型项目中常见封装方法,灵活性较高。

  首先创建 axios.js 文件

import originAxios from 'axios'    export default  function axios(option){        return new Promise((resolve,reject)=>{            //创建axios实例            const instance=originAxios.create({                baseURL:'/api',                timeout:5000,                headers:''            });            //传入对象进行网络请求            instance(option)            .then(res=>{                resolve(res)            })            .catch(err=>{                reject(err)            })        })    }

  然后在需要发送请求接口的地方引入

import {axios} from './axios.js'    axios({method:"get",url:"url",params:{...}})    .then(res=>{        //请求数据后操作    })    .catch(err=.{        //错误处理    })

 

  (2)针对不同请求类型进行二次封装。

/* *url:请求的url       *params:请求的参数       *config:请求时的header信息       *method:请求方法 */      const request = function ({ url, params, config, method }) {        // 如果是get请求 需要拼接参数        let str = "";        if (method === "get" && params) {          Object.keys(params).forEach((item) => {            str += `${item}=${params[item]}&`;          });        }        return new Promise((resolve, reject) => {          axios[method](            str ? url + "?" + str.substring(0, str.length - 1) : url,            params,            Object.assign({}, config)          )            .then(              (response) => {                resolve(response.data);              },              (err) => {                if (err.Cancel) {                } else {                  reject(err);                }              }            )            .catch((err) => {              reject(err);            });        });      };

  具体使用同上。

  (3)基于请求响应拦截进行封装,实际项目开发中常用。

  axios 提供的拦截器,用于每次发送请求和得到响应后进行响应的处理。比如在请求拦截中可以在页面中添加 loading 动画,某些请求要求用户必须登录,判断用户是否有token,如果没有就跳转到登录页面等,也可以对请求参数进行序列化操作等 config.data = qs.stringfy(config.params) 等。同样,响应拦截也可以对响应的数据进行过滤,包括响应失败的拦截,可以根据响应状态码进行不同的操作等。具体方法如下:

  首先在工具方法文件夹中创建 request.js 文件。这里搭配了token用于判断用户状态,element-ui 组件处理一些错误报错提示。该文件封装暴露了get、post、文件上传方法。

import axios from "axios";      import store from "../store";      import { Message, MessageBox } from "element-ui";      let baseURL = "http://127.0.0.1:3000/";      // 创建axios实例      const service = axios.create({        baseURL: baseURL,        timeout: 5000, // 请求超时时间        headers: { "Content-Type": "application/json;charset=UTF-8" },      });      // axios.defaults.withCredentials = true; // 若跨域请求需要带 cookie 身份识别      axios.defaults.headers.post["Access-Control-Allow-Origin-Type"] = "*"; // 允许跨域      const err = (error) => {        if (error.response) {          let data = error.response.data;          const token = store.getters.token;          switch (error.response.status) {            case 403:              Message({                message: data.message,                type: "error",                duration: 5 * 1000,              });              break;            case 500:              if (token && data.message == "Token失效,请重新登录") {                MessageBox.confirm(                  "很抱歉,登录已过期,请重新登录",                  "确定登出",                  {                    confirmButtonText: "重新登录",                    cancelButtonText: "取消",                    type: "warning",                  }                ).then(() => {                  store.dispatch("Logout").then(() => {                    window.location.reload(); // 为了重新实例化vue-router对象 避免bug                  });                });              }              break;            case 404:              Message({                message: data.message,                type: "error",                duration: 5 * 1000,              });              break;            case 504:              Message({                message: data.message,                type: "error",                duration: 5 * 1000,              });              break;            case 401:              Message({                message: data.message,                type: "error",                duration: 5 * 1000,              });              if (token) {                store.dispatch("Logout").then(() => {                  setTimeout(() => {                    window.location.reload();                  }, 1500);                });              }              break;            default:              Message({                message: data.message,                type: "error",                duration: 5 * 1000,              });              break;          }        }        return Promise.reject(error);      };      // request拦截器      service.interceptors.request.use(        (config) => {          const token = store.getters.token;          if (store.getters.token) {            config.headers["X-Token"] = token;//这里要注意在判断用户状态时候,请求头添加x-token格式问题,大写分开。          }          return config;        },        (error) => {          // Do something with request error          console.log(error); // for debug          Promise.reject(error);        }      );      // respone拦截器      service.interceptors.response.use((response) => {        console.log("response.data", response.data);        return response.data;      }, err);      /*       *  get请求       *  url:请求地址       *  params:参数       * */      export function get(url, params = {}) {        return new Promise((resolve, reject) => {          console.log("process.env.BASE_API", process.env.BASE_API);          service({            url: url,            method: "get",            params: params,          })            .then((response) => {              resolve(response);            })            .catch((error) => {              reject(error);            });        });      }      /*       *  post请求       *  url:请求地址       *  params:参数       * */      export function post(url, params = {}) {        return new Promise((resolve, reject) => {          service({            url: url,            method: "post",            data: params,  //这里注意下请求数据放在query params还是body中。          })            .then((response) => {              resolve(response);            })            .catch((error) => {              reject(error);            });        });      }      /*       *  文件上传       *  url:请求地址       *  params:参数       * */      export function fileUpload(url, params = {}) {        return new Promise((resolve, reject) => {          console.log("@@@@@@@@@@@params", params);          service({            url: url,            method: "post",            data: params,            headers: { "Content-Type": "multipart/form-data" },          })            .then((response) => {              resolve(response);            })            .catch((error) => {              reject(error);            });        });      }      export default {        get,        post,        fileUpload,      };

 

  然后创建api文件夹,如果接口过多可以对接口进行模块化管理,比如我这 api 下面创建 login.js 文件。

import { get, post,fileUpload } from "../utils/request";// 登录export const login = (params) => {  return get("/user/login", { ...params });};// 查询用户信息export const getUserInfo = (params) => {  return get("/user/userInfo", { ...params });};// 上传音频文件export const addRadioApi = (params, file) => {  return fileUpload("/radio/addRadio", { params, file });};

  最后在你的vue文件中就可以使用了,login.vue中使用如下:

import { login } from "../../api/login";      login({ name: "123", password: "123456" })        .then((res) => {          //登录请求后操作        })        .catch((error) => {          //异常处理        });

总结

  以上就是本文的全部内容,希望给读者带来些许的帮助和进步,方便的话点个关注,小白的成长踩坑之路会持续更新一些工作中常见的问题和技术点。

 

转载地址:http://fryiz.baihongyu.com/

你可能感兴趣的文章
centos7一步一步搭建docker jenkins 及自定义访问路径重点讲解
查看>>
MySQL 1064 You have an error in your SQL syntax 错误解决办法
查看>>
【Flink】Flink 底层RPC框架分析
查看>>
MySQL错误日志(Error Log)
查看>>
oracle使用DBMS_RANDOM包生成随机数据
查看>>
C++高精度模板
查看>>
解决:angularjs radio默认选中失效问题
查看>>
windows环境下安装zookeeper(仅本地使用)
查看>>
缓冲区溢出实例(一)--Windows
查看>>
Badboy录制脚本时,提示脚本错误的解决方法
查看>>
PHP一句话木马小总结与SQL语句写一句话木马
查看>>
关于计数排序
查看>>
Python中字符串前添加r ,b, u, f前缀的含义
查看>>
Hadoop学习笔记—Yarn
查看>>
JSONPath小试牛刀之Snack3
查看>>
Jenkins - 部署在Tomcat容器里的Jenkins,提示“反向代理设置有误”
查看>>
2017年前端框架、类库、工具大比拼
查看>>
wxWidgets源码分析(1) - App启动过程
查看>>
wxWidgets源码分析(3) - 消息映射表
查看>>
wxWidgets源码分析(5) - 窗口管理
查看>>