Vue学习笔记之18-网络请求模块的封装

常见的网络请求模块, 以及它们的优缺点对比

  • 传统Ajax请求
    • 缺点: 配置和调用方式等非常混乱
    • 真实开发中真的很少直接使用, 而是使用Jquery-Ajax
  • Jquery-ajax
    • 相对于传统的Ajax非常好用
    • 但是我们在整个vue的开发中都是不需要使用Jquery的
    • 那么就意味着为了方便我们进行一个网络请求, 特意引用了一个jQuery, 这显然不合理, Vue的代码才一万多行, jQuery的代码就一万多行了
    • 完全没有必要为了使用网络请求就引用jQuery这个框架
  • 官方在Vue1.x的时候, 推出了Vue-resource
    • Vue-resource的体积相对于jQuery小很多
    • 而且Vue-resource是Vue官方推出的
    • 但是在Vue2.0以后, Vue-resource就不再更新了
    • 这就意味着如果继续使用Vue-resource的话对项目的开发和维护都存在很大的隐患
  • axios
    • 在尤雨溪宣布不再更新vue-resource的时候, 推荐使用axios
    • 所以就选axios了
    • vue作者都让你选这个了, 你还想啥呢?
    • 可能你会说, 尤雨溪只是个写轮子的, 他懂个P的vue(/滑稽)

axios的基本使用

  • 安装axios 在项目根目录下, 命令行输入
    • npm install axios --save (运行时依赖)
  • 导入axios, 直接通过 axios() 使用, 并不需要使用Vue.use(axios) 来install, 因为axios本身并不是vue中的模块, vue并不具有axios的install方法
  • axios支持多种请求方式
    • axios(config)
    • axios.request(config)
    • axios.get(url[, config])
    • axios.delete(url[, config])
    • axios.head(url[, config])
    • axios.post(url[, data[, config]])
    • axios.put(url[, data[, config]])
    • axios.patch(url[, data[, config]])
  • 但是我们一般使用第一个 axios(config) 因为这个灵活, 可以在config里面设置请求方式
  • axios的特点: axios() 在网络请求完成后会返回一个Promise对象, 所以我们可以在axios() 后直接使用then() 和catch()
  • 请看下列代码实例
// axios 是不需要使用 Vue.use() 方法, 因为axios并不是vue中的模块
import axios from "axios"

// axios有很多种请求方式, 默认的请求方式为get请求
axios({
  // 提问这里为什么没有跨域问题?
  // 因为在后端已经处理过跨域了
  url : "请求的url",
  // 可以通过 method 属性来指定请求方式
  method : "post",

  // 如果使用get请求的话, 如果带有参数的话, 需要拼接到url上, 这样会导致url很长, 所以axios提供了一个parmas对象, 用于参数的拼接
  params : {
    type : "pop",
    page : 1
  }
}).then((res) => {
  // axios 在网络请求操作完成之后会返回一个 new Promise 对象, 所以这里可以使用then 和catch
  console.log(res);
}).catch((err) => {
  console.log(err);
})

axios处理并发请求

  • 如果我们需要多个axios请求完成后, 再进行下一步的操作
  • axios提供了一个 axios.all() 方法, 用于处理这种需求
  • 这个方法里面传入一个数组, 数组中传入axios请求
  • 在axios请求都完成后, axios.all() 方法会调用then(), then()中传入一个函数, 函数中有一个result参数
  • result是一个数组, 数组中第一个数据即是第一个axios请求返回的数据, 依此类推
  • 如果想要将各个返回的数据分开的话, then() 中还可以传入一个 axios.spread() 方法, 方法中传入一个函数
  • 该函数的参数就是对应的axios请求返回的数据
  • 看以下实例代码
// axios处理并发请求
import axios from "axios"
axios.all([
  axios({
    url : ""
  }),
  axios({
    url : "",
    params : {
      type : "pop",
      page : 5
    }
  })
])
/* .then((result => {
  // 这里的result是一个数组, 里面按顺序存放了各个axios请求返回的数据
  console.log(result);
  console.log(result[0]);
  console.log(result[1]);
})) */
.then(axios.spread((res1, res2)=> {
  // 通过 axios.spread() 将各个axios请求返回的数据, 分开
  console.log(res1);
  console.log(res2);
}))
.catch(err => {
  console.log(err);
})

axios设置全局配置信息

  • 其实我们的请求中有很多东西都是相同的, 比如url中的baseURL, 和设置的请求超时时间等等
  • 如果我们每次请求都要重写这些config, 这样代码就很重复了
  • 所以我们会将固定的参数抽取出来
  • axios提供了一个 defaults 对象用于进行全局配置
  • 看以下代码实例
import axios from "axios";
axios.defaults.baseURL = "" // 这里设置了baseURL
axios.defaults.timeout = 5000  // 这里设置了请求超时时间
axios.all([
  axios({
    url : "/home/multidata"
  }),
  axios({
    url : "/home/data",
    params : {
      type :"pop",
      page : 2
    }
  })
]).then(axios.spread((res1, res2)=> {
  // 通过 axios.spread() 将各个axios请求返回的数据, 分开
  console.log(res1);
  console.log(res2);
}))
.catch(err => {
  console.log(err);
})

常见的axios配置项

  • 请求地址
    • url: ‘/user’,
  • 请求类型
    • method: ‘get’,
  • 请根路径
    • baseURL: ‘http://www.mt.com/api’,
  • 请求前的数据处理
    • transformRequest:[function(data){}],
  • 请求后的数据处理
    • transformResponse: [function(data){}],
  • 自定义的请求头
    • headers:{‘x-Requested-With’:‘XMLHttpRequest’},
  • URL查询对象 (注意只有get请求方式才用params)
    • params:{ id: 12 }
  • 查询对象序列化函数
    • paramsSerializer: function(params){ }
  • request body (注意只用post请求方式才用这个)
    • data: { key: ‘aa’},
  • 超时设置s
    • timeout: 1000,
  • 跨域是否带Token
    • withCredentials: false,
  • 自定义请求处理
    • adapter: function(resolve, reject, config){},
  • 身份验证信息
    • auth: { uname: ‘’, pwd: ‘12’},
  • 响应的数据格式 json / blob /document /arraybuffer / text / + stream
    • responseType: ‘json’,

创建axios实例

  • 在实际开发中, 很有可能会遇到这种状况
  • 网络请求的baseURL是不一样的, 或者说不同的网络请求设置的请求超时时间是不一样的
  • 这个时候, 如果我们还是使用全局配置的 axios.default 就无法正确地请求正确的数据了
  • 所以我们要创建axios实例
  • 创建axios实例, 通过axios.create创建
  • 看以下代码实例
// 比如这里的网络请求, 需要设置的请求超时时间为 5000毫秒
const instans1 = axios.create({
  // 在这里设置配置
  baseURL : "",
  timeout : 5000
})
// 在这里使用axios实例
// 与全局中使用axios基本一致
instans1({
  url : "/home/multidata"
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

// 比如这里需要设置请求超时时间为10000
const instans2 = axios.create({
  baseURL : "",
  timeout : 10000
})
// 在这里使用instans2进行网络请求
instans2({
  url : "/home/data",
  params : {
    type :"pop",
    page : 2
  }
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

axios的封装

  • 如果我们没有把axios封装到一个文件中, 而是在需要用到axios的组件中都引用axios
  • 那么如果在未来的某一天, axios突然宣布不再更新
  • 那我们的项目想要使用另外的替代品将会变得十分困难, 因为我们每个组件都依赖了axios
  • 为了降低我们各个组件对axios的依赖性
  • 我们要将axios封装在一个独立的文件中
  • 封装过程及引用方法请看下列示例代码
// 创建文件 src/network/request.js

// 引入axios
import axios from "axios"

// 创建axios实例并导出
// 基本使用
export function request(config) {
  const instans = axios.create({
    baseURL : "",
    timeout : 5000
  })
  instans(config)
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    console.log(err);
  })
}
// 如何使用
import request from "./network/request"
request({
  url : "/home/multidata"
})


// 2. 通过组件传入一个函数, 然后回调这个函数返回数据给组件
export function request(config,success,error) {
  const instans = axios.create({
    baseURL : ""
  })
  instans(config)
  .then(res => {
    success(res)
  })
  .catch(err => {
    error(err)
  })
}
// 如何使用
import request from "./network/request"
request(
  {
    url: "/home/multidata",
  },
  (res) => {
    console.log(res);
    this.res = res;
  }
);

// 2.1 通过组件传入一个函数, 然后回调这个函数返回数据给组件的另外一种形式
export function request(config) {
  const instans = axios.create({
    baseURL : ""
  })
  instans(config.baseConfig)
  .then(res => {
    config.success(res)
  })
  .catch(err => {
    config.error(err)
  })
}
// 使用方法
request({
  baseConfig: {
    url: "/home/multidata",
  },
  success: function (res) {
    console.log(res);
  },
  error: function (err) {
    console.log(err);
  },
});

// 3. 实际上, 我们并不会使用以上的两种方法, 而是使用 Promise来返回数据
export function request(config) {
  const instans = axios.create({
    baseURL : ""
  })
  return new Promise((resolve, reject) => {
    instans(config)
    .then((res) => {
      resolve(res)
    })
    .catch(err => {
      reject(err)
    })
  })
}
// 使用方法
request({
    url: "/home/multidata",
  })
  .then((res) => {
    this.res = res;
  })
  .catch((err) => {
    console.log(err);
  });


// 3.1 实际上, 我们也不会像上面那样, 因为axios本身就返回一个Promise, 没有必要再包一层
export function request(config) {
  const instans = axios.create({
    baseURL : ""
  })
  return instans(config)
}
// 使用方法
request({
  url: "/home/multidata",
})
.then((res) => {
  this.res = res;
})
.catch((err) => {
  console.log(err);
});

axios拦截器的使用

  • axios提供了拦截器, 用于我们再发送每次请求或者得到相应数据后, 进行对应的处理
  • 拦截器分为: 请求拦截器 interceptors.request 和 响应拦截器 interceptors.response
  • 请求拦截器主要用法
    • 1.当发送网络请求的时候, 在页面中添加一个loading组件, 作为动画
    • 2.某些请求是要求用户必须登陆的, 这是请求拦截器就可以判断请求是否带有token(令牌), 如果没有token就跳转到login页面
    • 3.对请求的参数进行序列化, 就是对请求的参数做一些修改或者添加一些参数
  • 响应拦截器主要用法
    • 1.响应的成功拦截中,主要是对数据进行过滤
    • 2.响应失败的拦截中, 跨域根据status判断报错的错误码, 跳转到不同的错误提示页面
  • 拦截器使用注意事项, 使用拦截器后, 一定要将数据 return 出去, 否则, 拦截器会把数据拦截住
  • 基本使用方法看下列代码
export function request(config) {
  const instans = axios.create({
    baseURL : ""
  })
  // 使用拦截器
  // 请求拦截器
  instans.interceptors.request.use(config => {
    console.log(config);
    return config  // 将数据在return出去
  }, err => {
    console.log(err);
  })

  // 响应拦截器
  instans.interceptors.response.use(res => {
    console.log(res);
    return res.data  // 将数据进行过滤, 只返回data
  }, err => {
    console.log(err);
  })

  // 发送真实的网络请求
  return instans(config)
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值