項目實戰-Api的解決方案

問題

  • vue-cli3 下環境變量切換問題
    調用遠程api時候,但願本地開發使用內網IP地址(開發人員本地版本),部署後使用部署版本
  • 封裝 axios
  • api 管理

解決方案

  • 環境變量切換
    vue-cli3 中,環境變量是經過 '.env.XXX' 的隱藏文件來配置的,可在 環境變量和模式 中找到解決方案。
    因此就直接項目狀況,創建了兩個文件:html

    • .envvue

      # 全部環境
      # 網絡請求公用地址
      VUE_APP_API=
    • .env.developmentios

      # 開發環境
      # 網絡請求公用地址
      VUE_APP_API=http://api.youproject.com/
  • 封裝 axios
    對axios進行封裝,包括基礎設置,錯誤處理,跨域請求的基礎設置vue-cli

    // @/plugin/axios
    import axios from 'axios'
    import router from '@/router'
    import { Toast } from 'vant'
    
    // 建立一個 axios 實例
    const service = axios.create({
      baseURL: process.env.VUE_APP_API,
      timeout: process.env.NODE_ENV === 'development' ? 120000 : 30000 // 請求超時時間 30s
    })
    
    service.defaults.headers.get['Content-Type'] = 'application/json'
    service.defaults.headers.put['Content-Type'] = 'application/json'
    service.defaults.headers.post['Content-Type'] = 'application/json'
    service.defaults.headers.delete['Content-Type'] = 'application/json'
    
    // 響應攔截器
    service.interceptors.response.use(
      function (response) {
        /* 
          返回的數據約定
          {
            code: 0, // 99 token 無效
            message: "",
            success: true,
            data: {} // 返回的數據
          }
        */
        // dataAxios 是 axios 返回數據中的 data
        const dataAxios = response.data
        // 這個狀態碼是和後端約定的
        const { code, success, message } = dataAxios
        // 根據 code 進行判斷
        if (code === undefined) {
          // 直接返回數據的狀況
          return dataAxios
        } else if (!code) {
          if (success) {
            if (dataAxios.data === null || dataAxios.data === undefined) {
              return true
            } else {
              return dataAxios.data
            }
          } else {
            Toast.fail(message)
            return null
          }
        } else {
          // 有 code 表明這是一個後端接口 能夠進行進一步的判斷
          switch (code) {
            case 0:
            case 200:
              // [ 示例 ] code === 0/200 表明沒有錯誤
              return dataAxios.data
            case 99:
              Toast.fail('token無效,請從新登陸')
              router.replace({
                name: 'Unauthorized'
              })
              break
            default:
              Toast.fail(`${dataAxios.code} - ${dataAxios.message}`)
          }
        }
      },
      function (error) {
        if (error && error.response) {
          switch (error.response.status) {
            case 400: error.message = '請求錯誤' break
            case 401: error.message = '受權錯誤,請登陸' break
            case 403: error.message = '拒絕訪問' break 
            case 404: error.message = `請求地址出錯: ${error.response.config.url}` break 
            case 408: error.message = '請求超時' break 
            case 422: error.message = '驗證出錯' break 
            case 500: error.message = '服務器內部錯誤' break 
            case 501: error.message = '服務未實現' break 
            case 502: error.message = '網關錯誤' break 
            case 503: error.message = '服務不可用' break 
            case 504: error.message = '網關超時' break 
            case 505: error.message = 'HTTP版本不受支持' break
          }
        }
        Toast.clear()
        Toast.fail(error.message)
        return Promise.reject(error)
      }
    )
    
    export default service
  • api 管理
    在實際項目中,我指望的是api能放在一個統一的地方進行管理,這樣在有大變化的時候不用多個文件去查找修改,在編碼的時候也方便不少,代碼也會清晰點,實現以下json

    // src/api/index.js
    import common from './common'
    // ...
    export default {
      common,
      // ...
    }
    
    // src/api/common.js
    import axios from '@/plugin/axios'
    
    export default {
      getCurrentUserInfo () {
        return axios.get('/api/common/getCurrentUserInfo.json')
      },
    }

    如何使用呢:axios

    // src/main.js
    import Vue from 'vue'
    import api from './api'
    
    Vue.prototype.$api = api
    
    // src/views/business.vue
    // ...
    this.$api.common.getCurrentUserInfo().then(res => {
      // ...
    })
    // ...
相關文章
相關標籤/搜索