美文网首页让前端飞vue
axios在vue-cli项目中的封装使用

axios在vue-cli项目中的封装使用

作者: 我是你班主任 | 来源:发表于2018-08-16 15:55 被阅读183次

    axios是一个promise实现的http库,符合最新的ES规范。我们为啥要用这个东西呢,主要有以下几个原因:

    • 从浏览器中创建 XMLHttpRequests
    • 从 node.js 创建 http 请求
    • 拦截请求和响应
    • 转换请求数据和响应数据
    • 支持 Promise API(可以配合ES7的async await使用,解决回调地狱)
    • 客户端支持防止CSRF
    • 提供了一些并发请求的接口
    • 轻量,体积小

    搞起

    要想把axios装项目,拢共分3部:

    1. IE兼容性处理
    2. 封装、配置axios
    3. 把他挂到vue的prototype上(这样就不用每个文件都引入了)

    IE兼容处理

    axios是promise实现的,提到promise,首先应该想到IE不支持,所以应该先加个垫片,给IE做下兼容性处理

    npm install --save babel-polyfill

    然后再main.js中引入

    import 'babel-polyfill'
    

    封装axios

    先安装axios

    npm install --save axios

    然后建议在src下新建一个文件夹api专门用来存放接口相关的文件和配置


    下面是请求和响应拦截等相关配置
    src/api/axios.js

    import axios from 'axios'
    import browser from '../common/browser'
    
    // 创建 axios 实例
    let http = axios.create({
      // headers: {'Content-Type': 'application/json'},
      timeout: 60000
    })
    
    // 设置 post、put 默认 Content-Type
    http.defaults.headers.post['Content-Type'] = 'application/json'
    http.defaults.headers.put['Content-Type'] = 'application/json'
    
    // 添加请求拦截器
    http.interceptors.request.use(config => {
      if (config.method === 'post' || config.method === 'put') {
        // post、put 提交时,将对象转换为string, 为处理Java后台解析问题
        config.data = JSON.stringify(config.data)
      } else if (config.method === 'get' && browser.isIE) {
        // 给GET 请求后追加时间戳, 解决IE GET 请求缓存问题
        let symbol = config.url.indexOf('?') >= 0 ? '&' : '?'
        config.url += symbol + '_=' + Date.now()
      }
      // 请求发送前进行处理
      return config
    }, error => {
      // 请求错误处理
      return Promise.reject(error)
    })
    
    // 添加响应拦截器
    http.interceptors.response.use(response => {
      let {data} = response
      return data
    }, error => {
      let info = {}
      let {status, statusText, data} = error.response
      if (!error.response) {
        info = {
          code: 5000,
          msg: 'Network Error'
        }
      } else {
        // 此处整理错误信息格式
        info = {
          code: status,
          data: data,
          msg: statusText
        }
      }
      return Promise.reject(info)
    })
    
    /**
     * 创建统一封装过的 axios 实例
     * @return {AxiosInstance}
     */
    export default function () {
      return http
    }
    

    其他配置项还有很多,具体可以查看axios中文说明


    封装常用请求方法
    src/api/index.js

    import axios from './axios'
    
    let instance = axios()
    export default {
      get (url, params, headers) {
        let options = {}
        if (params) {
          options.params = params
        }
        if (headers) {
          options.headers = headers
        }
        return instance.get(url, options)
      },
      post (url, params, headers) {
        let options = {}
        if (headers) {
          options.headers = headers
        }
        return instance.post(url, params, options)
      },
      put  (url, params, headers) {
        let options = {}
        if (headers) {
          options.headers = headers
        }
        return instance.put(url, params, options)
      },
      delete (url, params, headers) {
        let options = {}
        if (params) {
          options.params = params
        }
        if (headers) {
          options.headers = headers
        }
        return instance.delete(url, options)
      }
    }
    

    到此axios就封装好了


    接下来我们把接口的URL和调用方法也写在这个文件夹里,建议按模块划分文件夹。下面用图片网站unsplash的api举例说明,此处肯定要涉及到跨域问题,如果对跨域问题不了解,推荐一篇文章,讲的很棒。
    unsplash的做法是CORS,全称是"跨域资源共享"(Cross-origin resource sharing)跨域资源共享 CORS 详解,前端啥也不用做,正常发请求就ok了

    src/api/unsplash/url.js(这个文件存放所有模块相关URL地址)

    const baseUrl = 'https://api.unsplash.com'
    
    export default {
      // 图片列表
      photos: baseUrl + '/photos'
    }
    

    src/api/unsplash/index.js

    import api from '../index'
    import urls from './urls'
    // import { formatUrl } from '../../common/utils'
    // 这个东西是unsplash要求加在header里的验证,有兴趣的同学可以去看他的api,此处不再赘述
    const header = {
      'Authorization': 'Client-ID xxxxxxx'
    }
    
    export default {
      viewPhotos (params) {
        // return出去了一个promise
        return api.get(urls.photos, params, header)
      }
    }
    

    这些都做完之后,把所有模块的调用都整合到一个文件里,(这里拆这么细,项目比较大,模块比较多的时候就会体现出好处,方便统一管理)

    src/api/apiList.js

    // 有多少import多少
    import unsplash from './unsplash'
    
    export default {
      unsplash
    }
    

    挂到Vue的prototype

    该配的该写的都整完了,最后一步把大象装冰箱。。啊不,是把他挂prototype上

    src/api/install.js

    // 导入模块
    import apiList from './apiList'
    
    const install = function (Vue) {
      if (install.installed) return
      install.installed = true
      Object.defineProperties(Vue.prototype, {
        $api: {
          get () {
            return apiList
          }
        }
      })
    }
    
    export default {
      install
    }
    

    最后把这个install.js在main.js里引一下,再use一下就ok了

    import 'babel-polyfill'
    import Vue from 'vue'
    import api from './api/install'
    import App from './App'
    import router from './router'
    import store from './store'
    
    Vue.use(api)
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,
      template: '<App/>',
      components: { App }
    })
    

    贴一下刚才建的项目目录



    接下来我们就可以愉快地使用了

    随便找个页面

    <template>
      <div class="waterfall">
      </div>
    </template>
    
    <script>
      export default {
        name: 'waterfall',
        data () {
          return {
            photosList: []
          }
        },
        created () {
          this.getPhotos()
        },
        mounted () {
        },
        computed: {
        },
        watch: {
        },
        methods: {
          // async await 是ES7新特性,本质上是generator函数的语法糖
          async getPhotos () {
            // 这里用try catch包裹,请求失败的时候就执行catch里的
            try {
              let params = {
                page: 1,
                per_page: 1,
                order_by: 'latest'
              }
              let res = await this.$api.unsplash.viewPhotos(params)
              this.photosList = res
              console.log(res)
            } catch (e) {
              console.log(e)
            }
          }
    
        }
      }
    </script>
    
    <style lang="less">
    </style>
    

    如果报了async await的错,就还得配一下根目录的.babelrc,先安装

    npm install --save-dev babel-plugin-transform-runtime
    npm install --save-dev babel-preset-stage-0

    .babelrc

    {
      "presets": [
        ["env", { "modules": false }],
        "stage-0"
      ],
      "plugins": [[
        "transform-runtime",
        {
          "helpers": false,
          "polyfill": false,
          "regenerator": true,
          "moduleName": "babel-runtime"
        }
      ]]
    }
    

    总结

    以上就是把axios整合进项目的全部步骤,一般项目配置这些就够用了,要想玩儿的更6,还是得撸文档啊。。

    相关文章

      网友评论

      本文标题:axios在vue-cli项目中的封装使用

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