Skip to the content.

最近接手一个老项目,技术很零碎,所以项目组打算一边维护老代码一边着手重构项目。 考虑到接口不好再改动,能动的只有前端代码,像一些交互逻辑和请求方式都要兼容沿用。 这篇记录下对 axios 对二次封装,并注册到全局,方便调用。

util.js 部分

// src/assets/js/util.js

import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

/**
 * @name ajax
 * @param { String } method 'post' || 'get'
 * @param { String } url 'demo/api/abc123'
 * @param { JSON } params { id: 1, name: johnny }
 */
let ajax = (method, url, params = {}) => {
  // console.log(url, params)
  return new Promise((resolve, reject) => {
    let base_url = process.env.NODE_ENV === 'production' ? 'http://code.demo.cn/api/' : 'http://test.code.demo.cn:8080/api/'
    url = base_url + url
    let query = {
      method: method.toUpperCase(),
      url: url,
      data: params
    }

    let token = localStorage.getItem('token')
    if (token) query.headers = { token }
    
    return Vue.axios(query)
      .then(res => {
        res.status * 1 === 200 ? resolve(res.data) : reject(res.data)
      })
      .catch(err => {
        if (err.response) {
          // The request was made and the server responded with a status code
          // that falls out of the range of 2xx
          reject(err.response.data)
        } else if (err.request) {
          // The request was made but no response was received
          // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
          // http.ClientRequest in node.js
          reject(err.request)
        } else {
          // Something happened in setting up the request that triggered an Error
          reject(err)
        }
        // console.log(err.config)
      })
  })
}


let Util = {}
Util.install = Vue => {
  Vue.prototype.ajax = ajax
}

export default Util

main.js 部分

// src/main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import VueAxios from 'vue-axios'
import util from './assets/js/util.js'

Vue.use(VueAxios, axios)
Vue.use(util)

Vue.config.productionTip = false


/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

调用部分

<!-- src/components/Login.vue -->

<template>
  <div class="login-wrap">
    <!-- view code -->
  </div>
</template>

<script>
export default {
  data () {
    return {}
  },
  methods: {
    _login () { // post请求 登入
      let params = {
        username: 'johnny',
        password: '123456'
      }
      this.ajax('post', 'login', params)
        .then(res => {
          // console.log(res)
          alert('登陆成功')
          localStorage.setItem('user_info',JSON.stringify(res,null,2))
          localStorage.setItem('token',res.token)

          setTimeout(() => this.$router.push(this.$route.query.redirect || '/'), 1200)
        })
        .catch(err => {
          // console.log(err)
          alert(err.message)
        })
    },
    _getDemo () { // get请求
      this.ajax('get', 'getServerDateTime')
        .then(res => {
          console.log(res)
        })
    }
  }
}
</script>

<style lang="stylus" scoped>
/* style code */
</style>

总结

这次使用了新的方式去注册到全局,详细可参考官方文档,插件的开发和使用

之前的项目前后端约定只用 POST 请求,这次重构项目用到的请求方式比较多,所以就分开啦 emmm… 之前的请求拦截也都写在封装里,现在拆到 main.js 中单独做了封装,可以看后面一篇,如何对 http 请求做拦截。