vue-axios-loading-api-配置

1.前言

axios多少年了依然這么流行,而且也沒什么大的更新
簡(jiǎn)單到極致,真是小而美
尤大的 官方庫(kù)vue-resource都放棄維護(hù)了,推薦用 axios
axios

特點(diǎn):

  1. 基于promise的http庫(kù)
  2. 可運(yùn)行在瀏覽器端和node.js中
  3. 攔截請(qǐng)求和響應(yīng)
  4. 取消請(qǐng)求
  5. 轉(zhuǎn)換json
  6. 客戶端防御XSRF等

2. vue里面 基礎(chǔ)使用axios

1.安裝 npm install axios

  1. 3x腳手架 也可以 vue add axios

3.基礎(chǔ)使用

  1. 新建 axios文件
  2. main.js引入 axios文件
  3. vue add axios已經(jīng)幫我們做了上述操作

組件使用

  1. 注意 這里不能 this.$http 版本不同
 const api = "/api/v1/code";
           this.axios.post(api,{test:"測(cè)試"}).then((res)=>{
               console.log("驗(yàn)證碼--",res)
               this.codeUrl = res.data.code
           })

vue.config.js配置代理

  1. 代理可以配置多個(gè)
  2. 比如你圖片服務(wù)器或者 文件服務(wù)器不同也可以配置
 devServer: {
    // port:8080,
    // host:"yzs.com",
    open: true,
    proxy:{
      "/api":{
        target:"https://xx.xx.org",
        ws:false,
        changeOrigin:true,
        pathRewrite:{
          "^/api":""
        }
      }
    }
  }

4. baseUrl配置

全局配置-方式1

  1. 這里主要就是 網(wǎng)絡(luò)請(qǐng)求的基礎(chǔ)配置
  2. 請(qǐng)求超時(shí)經(jīng)常設(shè)置
let config = {
  baseURL: "https://www.yzs.xx.",
  timeout: 60 * 1000, // Timeout
  withCredentials: true, // Check cross-site Access-Control
};
  1. 這個(gè)可以走單獨(dú)的配置文件 ,不同的環(huán)境不同的地址
  2. baseURL: process.env.baseURL || process.env.apiUrl ||""

全局配置-方式2

/ /axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

5. 某些情況下,有些個(gè)別請(qǐng)求也需要單獨(dú)配置

局部配置

  this.axios.defaults.baseURL = "http://www.yzs.com"
            const api = "/api/v1/code";
           this.axios.post(api,{test:"測(cè)試"}).then((res)=>{
               console.log("驗(yàn)證碼--",res)
               this.codeUrl = res.data.code
           })

以上配置只對(duì) 本次請(qǐng)求有效


7. 不同環(huán)境不同baseURL

if (process.env.NODE_ENV == 'development') {    
    axios.defaults.baseURL = 'https://www.baidu.com';} 
else if (process.env.NODE_ENV == 'debug') {    
    axios.defaults.baseURL = 'https://www.ceshi.com';
} 
else if (process.env.NODE_ENV == 'production') {    
    axios.defaults.baseURL = 'https://www.production.com';
}

vue配置環(huán)境變量


8. 基于element-ui的 loading配置

  1. 基于 vue add axios后的 axios文件
  2. 就是在request請(qǐng)求的時(shí)候加上loding動(dòng)畫
  3. 響應(yīng)response的時(shí)候關(guān)閉
  1. 也可以在響應(yīng)成功里面 對(duì)響應(yīng)數(shù)據(jù)做個(gè)初步處理
    比如數(shù)據(jù)結(jié)構(gòu)剝離一層
    比如根據(jù)后端的 狀態(tài)碼 統(tǒng)一做處理
import { Loading } from 'element-ui';
const _axios = axios.create(config);
var loading = null
_axios.interceptors.request.use(
  function(config) {
    loading= Loading.service({
      lock: true,
      text: 'Loading',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)'
    });
    // Do something before request is sent
    return config;
  },
  function(error) {
    // Do something with request error
    return Promise.reject(error);
  }
);

// Add a response interceptor
_axios.interceptors.response.use(
  function(response) {

    loading.close()
    // Do something with response data
    return response;
  },
  function(error) {
    // Do something with response error
    return Promise.reject(error);
  }
);


9. api拆分

大部分道友可能習(xí)慣直接在組件內(nèi)發(fā)請(qǐng)求

this.$http.post(this.$hosts.yzsm.YZS_HOST + '/companyRight/getAllCompanyByMap', params)
  1. 從各大項(xiàng)目來看比如各大框架的 admin模板,api也都是拆分的
  2. 但是從項(xiàng)目架構(gòu)角度出發(fā),這樣寫非常不方便查閱和管理
  3. 所以單獨(dú)拆分出來文件,這個(gè)想法其實(shí)和 store的拆分一樣

步驟

  1. src/api 目錄 或者assets/api目錄 這個(gè)在哪倒是無(wú)傷大雅
  2. 新建文件,一般按功能分,不按界面
    比如用戶信息相關(guān) user.js
    比如登錄注冊(cè)相關(guān) login.js
    比如城市相關(guān) city.js
    比如店鋪相關(guān) shop.js
    比如權(quán)限相關(guān) right.js
  3. 也不必非得太細(xì)
注釋必不可少

getpost 都一樣 參數(shù)根據(jù)需要傳遞

//獲取權(quán)限列表
export const getAllRights = (params)=>{
        return axios.get("/api/companyRight/getAllCompanyByMap", {params})
}
// 更新權(quán)限
export const updateRight = ()=>{
    return axios.get("/api/companyRight/updateCompanyRight")
}
// 更新管理員權(quán)限
export const updateAdmin = ()=>{
    return axios.get("/api/companyRight/updateCompanyAdmin")
}


10. api使用

1. 引入

  1. 因?yàn)榻涌谝话愣急容^多選用 別名的方式引入
import * as api from "@/api/rights.js";

如果比較少也可以 直接引入

import {updateAdmin ,updateRight ,getAllRights }  from "@/api/rights.js";
  1. 根據(jù)自己的情況選用一種就行

2. 使用

  1. 別名引入 直接 別名.屬性 調(diào)用
  2. 直接引入就直接用, 但是注意不要和 組件內(nèi)方法重名
  3. 所有還是建議使用別名的方式
methods: {
    getRightsBtn() {
      var params = {
      };
        api.getAllRights (params).then((res) => {
            if(res.data.bean  !== "2000"){
                return  this.$message.error(res.data.returnMessage)
            }
           this.listData = res.data.bean.list
            console.log("Res:",res)
        })
        .catch((err) => {
          console.log("失敗", err);
        });
    },
  },

11. 請(qǐng)求攔截

why為啥要攔截呢

  1. 有些請(qǐng)求是需要用戶登錄之后才能訪問的,或者post請(qǐng)求的時(shí)候,我們需要序列化我們提交的數(shù)據(jù)。這時(shí)候,我們可以在請(qǐng)求被發(fā)送之前進(jìn)行一個(gè)攔截,從而進(jìn)行我們想要的操作。
  2. 需要導(dǎo)入 vuex,因?yàn)檫@里面管理著我們需要的狀態(tài),比如,用戶是否登錄,用戶會(huì)員級(jí)別
_axios.interceptors.request.use(
  config => {        
//在發(fā)送請(qǐng)求之前做些什么

        // 每次發(fā)送請(qǐng)求之前判斷vuex中是否存在token        
        // 如果存在,則統(tǒng)一在http請(qǐng)求的header都加上token,這樣后臺(tái)根據(jù)token判斷你的登錄情況
        // 即使本地存在token,也有可能token是過期的,所以在響應(yīng)攔截器中要對(duì)返回狀態(tài)進(jìn)行判斷 
        const token = store.state.token;        
        token && (config.headers.Authorization = token);        
        return config;   
  },
  function(error) {
//  對(duì)請(qǐng)求錯(cuò)誤做些什么
    // Do something with request error
    return Promise.reject(error);
  }
);
  1. 這里用到的是 vuex add axios 添加后自動(dòng)生成的

12. token 簡(jiǎn)要

  1. 一般是在登錄完成之后,將用戶的token通過localStorage或者cookie存在本地
  2. 然后用戶每次在進(jìn)入頁(yè)面的時(shí)候(即在main.js中),會(huì)首先從本地存儲(chǔ)中讀取token
  3. 如果token存在說明用戶已經(jīng)登陸過,則更新vuex中的token狀態(tài)。
  4. 然后,在每次請(qǐng)求接口的時(shí)候,都會(huì)在請(qǐng)求的header中攜帶token,
  5. 后臺(tái)人員就可以根據(jù)你攜帶的token來判斷你的登錄是否過期,如果沒有攜帶,則說明沒有登錄過。
  6. 每個(gè)請(qǐng)求都攜帶token,那么要是一個(gè)頁(yè)面不需要用戶登錄就可以訪問的怎么辦呢?前端的請(qǐng)求可以攜帶token,但是后臺(tái)可以選擇不接收?。?/li>

13. token 取消

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函數(shù)接收一個(gè) cancel 函數(shù)作為參數(shù)
    cancel = c;
  })
});

// cancel the request
cancel();

14. 擴(kuò)展 -響應(yīng)攔截-配置

  1. 就是服務(wù)器返回給我們的數(shù)據(jù),我們?cè)谀玫街翱梢詫?duì)他進(jìn)行一些處理
  2. 如果后臺(tái)返回的狀態(tài)碼是200,則正常返回?cái)?shù)據(jù),
  3. 否則的根據(jù)錯(cuò)誤的狀態(tài)碼類型進(jìn)行一些我們需要的錯(cuò)誤,其實(shí)這里主要就是進(jìn)行了錯(cuò)誤的統(tǒng)一處理和沒登錄或登錄過期后調(diào)整登錄頁(yè)的一個(gè)操作。
_axios.interceptors.response.use(
  response => {   
// 對(duì)響應(yīng)數(shù)據(jù)做點(diǎn)什么

        // 如果返回的狀態(tài)碼為200,說明接口請(qǐng)求成功,可以正常拿到數(shù)據(jù)     
        // 否則的話拋出錯(cuò)誤
    res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res), 
  },
 // 服務(wù)器狀態(tài)碼不是2開頭的的情況
    // 這里可以跟你們的后臺(tái)開發(fā)人員協(xié)商好統(tǒng)一的錯(cuò)誤狀態(tài)碼    
    // 然后根據(jù)返回的狀態(tài)碼進(jìn)行一些操作,例如登錄過期提示,錯(cuò)誤提示等等
    // 下面列舉幾個(gè)常見的操作,其他需求可自行擴(kuò)展
    error => {            
// 對(duì)響應(yīng)錯(cuò)誤做點(diǎn)什么

        if (error.response.status) {            
            switch (error.response.status) {                
                // 401: 未登錄
                // 未登錄則跳轉(zhuǎn)登錄頁(yè)面,并攜帶當(dāng)前頁(yè)面的路徑
                // 在登錄成功后返回當(dāng)前頁(yè)面,這一步需要在登錄頁(yè)操作。                
                case 401:                    
                    router.replace({                        
                        path: '/login',                        
                        query: { 
                            redirect: router.currentRoute.fullPath 
                        }
                    });
                    break;

                // 403 token過期
                // 登錄過期對(duì)用戶進(jìn)行提示
                // 清除本地token和清空vuex中token對(duì)象
                // 跳轉(zhuǎn)登錄頁(yè)面                
                case 403:
                     Toast({
                        message: '登錄過期,請(qǐng)重新登錄',
                        duration: 1000,
                        forbidClick: true
                    });
                    // 清除token
                    localStorage.removeItem('token');
                    store.commit('loginSuccess', null);
                    // 跳轉(zhuǎn)登錄頁(yè)面,并將要瀏覽的頁(yè)面fullPath傳過去,登錄成功后跳轉(zhuǎn)需要訪問的頁(yè)面 
                    setTimeout(() => {                        
                        router.replace({                            
                            path: '/login',                            
                            query: { 
                                redirect: router.currentRoute.fullPath 
                            }                        
                        });                    
                    }, 1000);                    
                    break; 

                // 404請(qǐng)求不存在
                case 404:
                    Toast({
                        message: '網(wǎng)絡(luò)請(qǐng)求不存在',
                        duration: 1500,
                        forbidClick: true
                    });
                    break;
                // 其他錯(cuò)誤,直接拋出錯(cuò)誤提示
                default:
                    Toast({
                        message: error.response.data.message,
                        duration: 1500,
                        forbidClick: true
                    });
            }
            return Promise.reject(error.response);
        }
    }    
});
  1. window.navigator.onLine 可以判斷是否在線

參考資料

vue配置環(huán)境變量
vue中axios的封裝
axios
axios配置


初心

我所有的文章都只是基于入門,初步的了解;是自己的知識(shí)體系梳理;
如果能幫助到有緣人,非常的榮幸,一切為了部落的崛起;
共勉
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容