vue项目之不一样的axios封装(+防抖函数)

1,866 阅读1分钟
  • 在api目录下新建文件http.js
// 接口位置
import Api from './api.js'
import store from '@/store/store.js'
import router from "@/router/index"
import {baseUrl} from '@/config/env.js'
// 设置接口url域名和端口,超时断开连接
axios.defaults.baseURL = baseUrl
axios.defaults.timeout =  15000

// 请求拦截(请求携带token)
axios.interceptors.request.use(
    config => {
        if (store.getters.getUser.accessToken) {  // 判断是否存在token,如果存在的话,则每个http header都加上token
            config.headers.accessToken = store.getters.getUser.accessToken
        }
        return config;
    },
    err => {
        return Promise.reject(err)
})

// 响应拦截,对返回的状态码判断和进行一些操作
axios.interceptors.response.use(
    response => {
        if(response.data.status===401) {
            store.dispatch('delUser')
            router.push({path:'/login'})
        } else if (response.data.status===403) {
            router.push({path:'/error/403'})
        } else if(response.data.status===500) {
            router.push({path:'/error/500'})
        }
        if (response.status !==200 || response.data.status !==200) {
            Vue.prototype.$message({
               type: "error",
                message: response.data.errorMsg ? response.data.errorMsg : response.statusText
            })
        }
        return response
    },
    error => {
        return Promise.reject(error)
})


export default (function(){
    // 包含所有请求方法的构造函数
    function _Http(){
    }
    
    // 获取接口名字(截取接口/最后)
    http.getName = function(url){
        let list = url.split('/')
        return list[list.length-1]
    }
    
    // 包含所有请求和状态的实例对象
    function http(url = Api){
        var _httpob = new _Http()
        url.map(item => {
            let name = http.getName(item.url)
            _httpob[name+'Status'] = 1
            _httpob[name] = function(val = {}) {
               return _httpob.sendMsg(item.url,val,item.method)
            }
        })
        return _httpob
    }
    
    // axios请求的封装
    _Http.prototype.sendMsg = function(url,value = {},method ='post') {
        let name = http.getName(url)
        var status = {
            get:() => {
               return axios.get(url,{params:value}).then(res => {
                   this[name + 'Status'] = 1
                    return res
                }).catch( res => {
                    Vue.prototype.$message.warning('网络出现问题,请稍后重试')
                } )
            },
            post:() => {
                return axios.post(url,value).then(res => {
                    this[name+ 'Status'] = 1
                    return res
                }).catch( res => {
                    Vue.prototype.$message.warning('网络出现问题,请稍后重试')
                })
                
            }
        }
        if(this[name+ 'Status']) {
            this[name + 'Status'] = 0
            return status[method]()
        } else {
            return new Promise(reject => {
                reject({status:40001})
            })
        }
    } 
    
    return http
})()

这样子封装后_httpob对象里面就包含了所有请求方法和状态属性name+Status,这个属性是为了防止频繁调用接口,保证只有在接口返回response后才能再次调用

  • 接下在再api目录下新建Api.js用来存放接口,类似这样
// 接口(如果是post请求method属性可省略)
const mockApi = [
  {url:'/api/web/getEchartsData',method:'get'}
]
export default mockApi

这样不出意外_httpob里面就包含了getEchartsData(){}方法和getEchartsDataStatus属性

  • 然后在main.js里面调用http()函数
import http from '@/api/http.js'
Vue.prototype.$axios = http()
  • 最后我们就可以在组件里面直接调用getEchartsData接口了
// value:需要传递的参数
this.$axios.getEchartsData(value).then(res => {
    console.log(res)
})

大功告成,新手上路,不知道这样封装合不合适,大家多多指教哈哈