经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
详解vue中axios请求的封装
来源:jb51  时间:2019/4/8 12:18:43  对本文有异议

axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中, 也是vue官方推荐使用的http库;封装axios,一方面为了以后维护方便,另一方面也可以对请求进行自定义处理

安装

npm i axios

封装

我把axios请求封装在http.js中,重新把get请求,post请求封装了一次

首先,引入axios

import axios from 'axios'

设置接口请求前缀

一般我们开发都会有开发、测试、生产环境,前缀需要加以区分,我们利用node环境变量来作判断,

  1. if (process.env.NODE_ENV === 'development') {
  2. axios.defaults.baseURL = 'http://dev.xxx.com'
  3. } else if (process.env.NODE_ENV === 'production') {
  4. axios.defaults.baseURL = 'http://prod.xxx.com'
  5. }
  6.  

在localhost调试时,直接用开发地址一般都会有跨域的问题,所以我们还需要配置代理

本项目是vue cli3搭建的,代理配置是在vue.config.js文件中:

  1. module.exports = {
  2. devServer: {
  3. proxy: {
  4. '/proxyApi': {
  5. target: 'http://dev.xxx.com',
  6. changeOrigin: true,
  7. pathRewrite: {
  8. '/proxyApi': ''
  9. }
  10. }
  11. }
  12. }
  13. }
  14.  

这样就成功把/proxyApi 指向了 'http://dev.xxx.com',重启服务

修改一下http.js中的配置

  1. if (process.env.NODE_ENV === 'development') {
  2. axios.defaults.baseURL = '/proxyApi'
  3. } else if (process.env.NODE_ENV === 'production') {
  4. axios.defaults.baseURL = 'http://prod.xxx.com'
  5. }
  6.  

拦截器

接着设置超时时间和请求头信息

  1. axios.defaults.timeout = 10000
  2. // 请求头信息是为post请求设置
  3. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
  4.  

axios很好用,其中之一就是它的拦截器十分强大,我们就可以为请求和响应设置拦截器,比如请求拦截器可以在每个请求里加上token,做了统一处理后维护起来也方便,响应拦截器可以在接收到响应后先做一层操作,如根据状态码判断登录状态、授权。

  1. // 请求拦截器
  2. axios.interceptors.request.use(
  3. config => {
  4. // 每次发送请求之前判断是否存在token
  5. // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况,此处token一般是用户完成登录后储存到localstorage里的
  6. token && (config.headers.Authorization = token)
  7. return config
  8. },
  9. error => {
  10. return Promise.error(error)
  11. })
  12. // 响应拦截器
  13. axios.interceptors.response.use(response => {
  14. // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
  15. // 否则的话抛出错误
  16. if (response.status === 200) {
  17. if (response.data.code === 511) {
  18. // 未授权调取授权接口
  19. } else if (response.data.code === 510) {
  20. // 未登录跳转登录页
  21. } else {
  22. return Promise.resolve(response)
  23. }
  24. } else {
  25. return Promise.reject(response)
  26. }
  27. }, error => {
  28. // 我们可以在这里对异常状态作统一处理
  29. if (error.response.status) {
  30. // 处理请求失败的情况
  31. // 对不同返回码对相应处理
  32. return Promise.reject(error.response)
  33. }
  34. })
  35.  

get post的封装

httpGet: 一个参数是请求的url,一个就携带的请求参数,返回promise对象

  1. // get 请求
  2. export function httpGet({
  3. url,
  4. params = {}
  5. }) {
  6. return new Promise((resolve, reject) => {
  7. axios.get(url, {
  8. params
  9. }).then((res) => {
  10. resolve(res.data)
  11. }).catch(err => {
  12. reject(err)
  13. })
  14. })
  15. }
  16.  

httpPost: 原理和get差不多,需要注意,这里多了个data参数,post请求提交前需要对它进行序列号操作,这里是通过transformRequest做处理;另外两个参数url,params和get请求的一样;

  1. // post请求
  2. export function httpPost({
  3. url,
  4. data = {},
  5. params = {}
  6. }) {
  7. return new Promise((resolve, reject) => {
  8. axios({
  9. url,
  10. method: 'post',
  11. transformRequest: [function (data) {
  12. let ret = ''
  13. for (let it in data) {
  14. ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
  15. }
  16. return ret
  17. }],
  18. // 发送的数据
  19. data,
  20. // url参数
  21. params
  22.  
  23. }).then(res => {
  24. resolve(res.data)
  25. })
  26. })
  27. }
  28.  

如何使用

我把所有的接口调用都在api.js文件中

先引入封装好的方法,再在要调用的接口重新封装成一个方法暴露出去

  1. import { httpGet, httpPost } from './http'
  2. export const getorglist = (params = {}) => httpGet({ url: 'apps/api/org/list', params })
  3.  

在页面中可以这样调用:

  1. // .vue
  2. import { getorglist } from '@/assets/js/api'
  3.  
  4. getorglist({ id: 200 }).then(res => {
  5. console.log(res)
  6. })

这样可以把api统一管理起来,以后维护修改只需要在api.js文件操作即可。

完整代码
最后贴上完整代码

  1. // http.js
  2. import axios from 'axios'
  3.  
  4. // 环境的切换
  5. if (process.env.NODE_ENV === 'development') {
  6. axios.defaults.baseURL = '/proxyApi'
  7. } else if (process.env.NODE_ENV === 'production') {
  8. axios.defaults.baseURL = 'http://prod.xxx.com'
  9. }
  10.  
  11. // 请求拦截器
  12. axios.interceptors.request.use(
  13. config => {
  14. token && (config.headers.Authorization = token)
  15. return config
  16. },
  17. error => {
  18. return Promise.error(error)
  19. })
  20.  
  21. axios.defaults.timeout = 10000
  22.  
  23. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
  24.  
  25. // 响应拦截器
  26. axios.interceptors.response.use(response => {
  27. if (response.status === 200) {
  28. if (response.data.code === 511) {
  29. // 未授权调取授权接口
  30. } else if (response.data.code === 510) {
  31. // 未登录跳转登录页
  32. } else {
  33. return Promise.resolve(response)
  34. }
  35. } else {
  36. return Promise.reject(response)
  37. }
  38. }, error => {
  39. // 我们可以在这里对异常状态作统一处理
  40. if (error.response.status) {
  41. // 处理请求失败的情况
  42. // 对不同返回码对相应处理
  43. return Promise.reject(error.response)
  44. }
  45. })
  46.  
  47. // get 请求
  48. export function httpGet({
  49. url,
  50. params = {}
  51. }) {
  52. return new Promise((resolve, reject) => {
  53. axios.get(url, {
  54. params
  55. }).then((res) => {
  56. resolve(res.data)
  57. }).catch(err => {
  58. reject(err)
  59. })
  60. })
  61. }
  62.  
  63. // post请求
  64. export function httpPost({
  65. url,
  66. data = {},
  67. params = {}
  68. }) {
  69. return new Promise((resolve, reject) => {
  70. axios({
  71. url,
  72. method: 'post',
  73. transformRequest: [function (data) {
  74. let ret = ''
  75. for (let it in data) {
  76. ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
  77. }
  78. return ret
  79. }],
  80. // 发送的数据
  81. data,
  82. // url参数
  83. params
  84.  
  85. }).then(res => {
  86. resolve(res.data)
  87. })
  88. })
  89. }
  90.  
  1. // api.js
  2. import { httpGet, httpPost } from './http'
  3. export const getorglist = (params = {}) => httpGet({ url: 'apps/api/org/list', params })
  4.  
  5. export const save = (data) => {
  6. return httpPost({
  7. url: 'apps/wechat/api/save_member',
  8. data
  9. })
  10. }
  1. // .vue
  2. <script>
  3. import { getorglist } from '@/assets/js/api'
  4. export default {
  5. name: 'upload-card',
  6. data() {},
  7. mounted() {
  8. getorglist({ id: 200 }).then(res => {
  9. // console.log(res)
  10. })
  11. },
  12. }
  13. </script>

为什么还要多封装一层promise,不直接返回axios。
我在这里统一做个说明:
当然可以直接返回axios.get().then(res=>res.data),写法更简洁些;个人编程习惯,感觉resolve(res.data)写法更优雅些,这个就见仁见智了,所以正文对这点先做保留。这篇笔记也是提供一个思路,仅供参考。小伙伴可以根据自己实际业务需求来选择。

以上所述是小编给大家介绍的vue中axios请求的封装详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对w3xue网站的支持!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号