vue 封装axios 以及完整使用方法

文件结构
├── build  项目构建配置
├── config  开发相关配置
├── public  打包所需静态资源
└── src
    ├── api  AJAX请求
        ├── demo.js
    └── assets  项目静态资源
        ├── icons  自定义图标资源
        └── images  图片资源
    ├── components  业务组件
    ├── config  项目运行配置
        ├── evn.js
    ├── directive  自定义指令
    ├── libs  封装工具函数
        ...
       ├── api.request.js
       ├── axios.js
    ├── locale  多语言文件
    ├── mock  mock模拟数据
    ├── router  路由配置
    ├── store  Vuex配置
    ├── view  页面文件
    └── tests  测试相关
env.js
// URL为域名、API为调的api接口路径。不同环境的域名用不同环境的接口
const env = {
  // 生产环境
  PROD_URL: ['http://******.com', 'https://****.com'],
  PROD_API: {
    HostName: '//*****.com',
    FileName: '//*****'
  },

  // 预发环境
  PRE_URL: [],
  PRE_API: {},

  // 集成测试环境
  SIT_URL: [],
  SIT_API: {},

  // 测试环境
  TEST_URL: ['http://****.com', 'https://****.com'],
  TEST_API: {
    HostName: '//****.com',
    FileName: 'http://****/UploadFile'
  },

  // 开发环境。不存在 DEV_URL。
  DEV_API: {
    HostName: '//*****.com',
    WorkName: 'http://*****/mock/zzc',
    FileName: 'http://*****/UploadFile'
  }
}

// 后台接口的域名。如模板 HostName 为网关接口、WorkName为网关的mock接口。两个不同域。
let HostName = ''
let WorkName = ''
let FileName = ''
function checkUrl(url) {
  return window.location.href.indexOf(url) === 0
}
if (env.PROD_URL.length > 0 && env.PROD_URL.some(checkUrl)) {
  // 生产环境
  HostName = env.PROD_API.HostName || ''
  WorkName = env.PROD_API.WorkName || ''
  FileName = env.PROD_API.FileName || ''
} else if (env.PRE_URL.length > 0 && env.PRE_URL.some(checkUrl)) {
  // 预发环境
  HostName = env.PRE_API.HostName || ''
  WorkName = env.PRE_API.WorkName || ''
} else if (env.SIT_URL.length > 0 && env.SIT_URL.some(checkUrl)) {
  // 集成测试环境
  HostName = env.SIT_API.HostName || ''
  WorkName = env.SIT_API.WorkName || ''
} else if (env.TEST_URL.length > 0 && env.TEST_URL.some(checkUrl)) {
  // 测试环境
  HostName = env.TEST_API.HostName || ''
  WorkName = env.TEST_API.WorkName || ''
  FileName = env.TEST_API.FileName || ''
} else {
  // 开发环境
  HostName = env.DEV_API.HostName || ''
  WorkName = env.DEV_API.WorkName || ''
  FileName = env.DEV_API.FileName || ''
}
export default {
  HostName,
  WorkName,
  FileName
}
axios.js
import axios from 'axios'
import { Message } from 'iview'
import qs from 'qs' // qs 是一个增加了一些安全性的查询字符串解析和序列化字符串的库。

class HttpRequest {
  constructor (baseUrl = baseURL) {
    this.baseUrl = baseUrl
    this.queue = {}
  }
  getInsideConfig () {
    // 全局配置
    const config = {
      baseURL: this.baseUrl,
      withCredentials: true, // 允许携带cookie(开启withCredentials后,服务器才能拿到你的cookie,当然后端服务器也要设置允许你获取你开启了才有用)
      headers: {
        //

      }
    }
    return config
  }
  destroy (url) {
    delete this.queue[url]
  }
  interceptors (instance, url) {
    // 请求拦截
    instance.interceptors.request.use(config => {
      if (config.method.toUpperCase() === 'POST' && !config.isJson && !config.headers['Content-Type']) {
        config.data = qs.stringify(config.data)
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
        // config.headers['x-dubbo-directip'] = 'dubbo://****'
      }
      // 添加全局的loading...
      // if (!Object.keys(this.queue).length) {
      //   Spin.show() // 不建议开启,因为界面不友好
      // }
      this.queue[url] = true
      return config
    }, error => {
      return Promise.reject(error)
    })
    // 响应拦截
    instance.interceptors.response.use(response => {
      this.destroy(url)
      const { data, status } = response
      if (status === 200 && data) {
        if ((data.statusCode === '302' || data.statusCode === '301') && !data.status) {
          location.href = data.message
          return Promise.reject(response)
        }
        if (data.statusCode === 'SYS000' || data.status) return data.result
        Message.error(data.message, 1)
        return Promise.reject(response)
      }
      return Promise.reject(response)
    }, error => {
      this.destroy(url)
      // addErrorLog(error.response)
      return Promise.reject(error)
    })
  }
  request (options) {
    const instance = axios.create()
    options = Object.assign(this.getInsideConfig(), options)
    // console.log(options)
    this.interceptors(instance, options.url)
    return instance(options)
  }
}
export default HttpRequest
api.request.js
import HttpRequest from '@/libs/axios'
// import config from '@/config'
import env from '@/config/env'
const axios = new HttpRequest(env.HostName)

export default axios
demo.js
import axios from '@/libs/api.request'

// 获取详情
export const getDiskFileDetail = data => {
  return axios.request({
    url: '/folderFiles/detail',
    method: 'post',
    data,
    isJson: true
  })
}

index.vue 使用
<script>
import { getDiskFileDetail } from '@/api/disk'
export default {
    methods: {
    async _getFileDetail() {
        let result = await getDiskFileDetail({
          // 需要的参数
        }) // 因为axios返回的一个promise 或者写成 getDiskFileDetail((res) =>{})
        this.detail = result || ''
      }
    }
  },
}
posted @ 2019-10-24 15:07  _skylar  阅读(1050)  评论(0编辑  收藏  举报