axios封装

作者: fancheur | 来源:发表于2020-06-23 14:40 被阅读0次

    index.js------axios封装

    import { Notify } from 'vant';  //使用vant框架 
    import axios from 'axios'
    import store from '../store'  //loading
    const qs = require('qs')  
    
    const service = axios.create({ 
      baseURL: 'http://xxx', 
      timeout: 10000
    })
    
    const pending = []
    const cancelToken = axios.CancelToken
    
    //处理重复请求
    const addPending = ({ config }) => {
      const url =
        config.url + '&' + config.method + '&' + config.data
      config.cancelToken = new cancelToken(cancel => {
        if (!pending.some(item => item.url === url)) {
          pending.push({
            url,
            cancel
          })
        }
      })
    }
    const removePending = ({ config }) => {
      const url =
        config.url + '&' + config.method + '&' + config.data
      pending.forEach((item, index) => {
        if (item.url === url) {
          item.cancel('取消重复请求:' + config.url)
          pending.splice(index, 1)
        }
      })
    }
    
    //请求头预处理
    const requestHeaders = ({ config }) => {
     // 1.如果需要加时间戳  
      // const timestamp = new Date().getTime()
      // config.headers.timestamp = timestamp
      // 2.如果请求头需要加token
      // const token = localStorage.getItem('token')
      // if (token) {
      //   config.headers.token = token
      // }
    }
    
    //请求参数预处理
    const requestParams = ({ config } = {}) => {
    //登陆时数据存到localStorage
    //如果参数需要用到token则赋值
      const isLogin = JSON.parse( localStorage.getItem('userInfo') )
      const param = qs.parse(config.data)
      if(param.token !== undefined){
        param.token = isLogin && isLogin.token
        param.uid = isLogin && isLogin.uid
      }
      if ( config.method === 'post') {
        config.data = qs.stringify(param)
      }
    }
    
    //请求开始&&loading=true
    const requestStart = ({ config } = {}) => {
      requestHeaders({ config })
      requestParams({ config })
      removePending({ config })
      addPending({ config })
      store.commit('setLoading', true)
    }
    
    //请求拦截器
    service.interceptors.request.use(
      config => {
        requestStart({ config })
        return config
      },
      error => {
        Notify('请求出错')
        Promise.reject(error)
      }
    )
    
    
    //请求结束&&loading=false
    const requestEnd = ({ config } = {}) => {
      removePending({ config })
      store.commit('setLoading', false)
    }
    
    //请求结果处理
    const responseResolve = ({ status, data, config } = {}) => {
      if (status === 200) {
        switch (data.status) {
          case 'ok':
            return Promise.resolve(data.data)
          case 'relogin':
            localStorage.removeItem('userInfo')
            Notify('登录超时,请重新登录!')
            window.location.href = '#/'
            return Promise.reject(data)
          default:
            Notify(data.errormsg)
            return Promise.reject(data)
        }
      } else {
        Notify(data || '操作失败!')
        store.commit('setLoading', false)
        return Promise.reject(data.data)
      }
    }
    
    //响应拦截器
    service.interceptors.response.use(
      response => {
        const { status, data, config } = response
        requestEnd({ config, data })
        return responseResolve({ status, data, config })
      },
      error => {
        if (axios.isCancel(error)) {
          Notify('网络请求中,请不要重复操作!')
        } else {
          const { response } = error
          console.log({
            dangerouslyUseHTMLString: true,
            message: `<p>请求接口: ${
              response.config.url
            }</p><p>请求方法 : ${
              response.config.method
            }</p><p>响应状态 : ${response.status}</p><p>响应信息 : ${
              response.statusText
            }</p>`
          })
        }
        store.commit('setLoading', false)
        return Promise.reject(error)
      }
    )
    
    export default service
    
    

    api.js------接口文件

    import service from './index.js'   //引入封装好的axios
    
    let o = {
        uid: '',
        token: ''
      }
    
    //登录页面
    export const login = {
      login (id,pwd) {
        return service.post('/user/login', { id_card: id, password: pwd })
      },
      ……
    }
    
    //个人中心
    export const user = { 
      out () {
        return service.post('/user/logout', {...o})   // 在index.js里参数预处理检测到这里需要token则赋值
      },
      ……
    }
    

    单页面引入---login.vue

    <script>
    import { login } from '../service/api'
    login.login(this.uid, this.pwd).then((res)=>{
            ……
            localStorage.setItem('userInfo', JSON.stringify(res))
     })
    </script>
    

    vuex---store/index.js定义全局loading

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        loading: false
      },
      mutations: {
        setLoading (state, bool) {
          state.loading = bool
        }
      },
      actions: {
      },
      modules: {
      }
    })
    

    App.vue ------loading放app页面 这里用的是vant的loading

    <div id="app">
        <van-overlay :show="loading">
          <van-loading /> 
        </van-overlay>
        ……
    <div>
    <script>
    import { mapState, mapMutations} from 'vuex'
    export default {
      name: 'app',
      data(){
       return {
        }
      },
      computed:mapState([
        'loading'
      ]),
      methods:{
        ...mapMutations([
          'setLoading'
        ])
      }
    }
    </script>
    

    相关文章

      网友评论

        本文标题:axios封装

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