1. 程式人生 > >vue+axios+promise實際開發用法

vue+axios+promise實際開發用法

axios它是基於promise的http庫,可執行在瀏覽器端和node.js中,然後作者尤雨溪也是果斷放棄了對其官方庫vue-resource的維護,直接推薦axios庫,小編我也是從vue-resource轉換過來的,差別說不來,我們講一下axios在實際開發中的用法

axios特點

1.從瀏覽器中建立 XMLHttpRequests
2.從 node.js 建立 http 請求
3.支援 Promise API
4.攔截請求和響應 (就是有interceptor)
5.轉換請求資料和響應資料
6.取消請求
7.自動轉換 JSON 資料
8.客戶端支援防禦 XSRF

安裝axios和qs


npm i axios --save
npm i qs--save

建立項公共模組API

我是用vue-cli建立的專案在src->util->api.js(公共請求模組js)

引入axios和qs


import axios from 'axios'

有時候向後端傳送資料,後端無法接收,考慮使用qs模組


import qs from 'qs'

判定開發模式


if (process.env.NODE_ENV == 'development') {    

    axios.defaults.baseURL = '/api';

}else if (process.env.NODE_ENV == 'debug') {    

    axios.defaults.baseURL = 'http://v.juhe.cn';

}else if (process.env.NODE_ENV == 'production') {    

    axios.defaults.baseURL = 'http://v.juhe.cn';

}

全域性設定頭部資訊


axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

全域性設定超時時間


axios.defaults.timeout = 10000;

請求路由攔截

在請求發出去之前,可以做一些判斷,看是否是合法使用者


axios.interceptors.request.use(function (config) {
    // 一般在這個位置判斷token是否存在
    return config;
   }, function (error) {
    // 對請求錯誤做些什麼
    return Promise.reject(error);
});

響應攔截


axios.interceptors.response.use(function (response){
     // 處理響應資料
    if (response.status === 200) {            
        return Promise.resolve(response);        
    } else {            
        return Promise.reject(response);        
    }
    }, function (error){
    // 處理響應失敗
    return Promise.reject(error);
});

封裝請求方法

使用ES6模組化export匯出import匯入

在ES6前, 前端就使用RequireJS或者seaJS實現模組化, requireJS是基於AMD規範的模組化庫, 而像seaJS是基於CMD規範的模組化庫, 兩者都是為了為了推廣前端模組化的工具,現在ES6自帶了模組化,不過現代瀏覽器對模組(module)支援程度不同, 需要使用babelJS, 或者Traceur把ES6程式碼轉化為相容ES5版本的js程式碼;

get請求


export function get(url, params){    
    return new Promise((resolve, reject) =>{        
        axios.get(url, {            
            params: params        
        }).then(res => {
            resolve(res.data);
        }).catch(err =>{
            reject(err.data)        
        })    
    });
}

post請求


export function post(url, params) {
    return new Promise((resolve, reject) => {
         axios.post(url, qs.stringify(params))
        .then(res => {
            resolve(res.data);
        })
        .catch(err =>{
            reject(err.data)
        })
    });
}

實際使用

在main.js中引入js


import {get,post} from './utils/api'
//將方法掛載到Vue原型上
Vue.prototype.get = get;
Vue.prototype.post = post;

配置請求環境
這裡通過devServer請求代理
當在請求過程中有/api字串會自動轉換為目標伺服器地址(target)


devServer: {
   historyApiFallback: true,
   hot: true,
   inline: true,
   stats: { colors: true },
   proxy: {
     //匹配代理的url
     '/api': {
          // 目標伺服器地址
             target: 'http://v.juhe.cn',
             //路徑重寫
             pathRewrite: {'^/api' : ''},
             changeOrigin: true,
             secure: false,
           }
      },
    disableHostCheck:true
   }

這是請求聚合資料的介面為列子


this.get('/toutiao/index?type=top&key=祕鑰',{})
    .then((res)=>{
        if(res.error_code===0){
            resolve(res);
        }else{
            //這裡丟擲的異常被下面的catch所捕獲
            reject(error);
        }
    })
    .catch((err)=>{
        console.log(err)
    })

返回資料

使用promise
1.比如使用者想請求url1介面完後再調url2介面


    var promise = new Promise((resolve,reject)=>{
        let url1 = '/toutiao/index?type=top&key=祕鑰'
        this.get(url,{})
        .then((res)=>{
            resolve(res);
        })
        .catch((err)=>{
            console.log(err)
        })
    });
    promise.then((res)=>{
        let url2 = '/toutiao/index?type=top&key=祕鑰'
        this.get(ur2,{})
        .then((res)=>{
            //只有當url1請求到資料後才會呼叫url2,否則等待
            resolve(res);
        })
        .catch((err)=>{
            console.log(err)
        })
    })

Promise物件


Promise有三種狀態
pending: 等待中,或者進行中,表示還沒有得到結果
resolved: 已經完成,表示得到了我們想要的結果,可以繼續往下執行
rejected: 也表示得到結果,但是由於結果並非我們所願,因此拒絕執(用catch捕獲異常)

這三種狀態不受外界影響,而且狀態只能從pending改變為resolved或者rejected,並且不可逆(顧名思義承諾的後的東西怎麼又能返回呢)。在Promise物件的建構函式中,將一個函式作為第一個引數。而這個函式,就是用來處理Promise的狀態變化

這裡要注意,不管是then或者catch返回的都是一個新的Promise例項!而每個Primise例項都有最原始的Pending(進行中)到Resolve(已完成),或者Pending(進行中)到Reject(已失敗)的過程

Promise基本用法

Promise.all()用法


var p = Promise.all([p1, p2, p3]);

all()接受陣列作為引數。p1,p2,p3都是Promise的例項物件,p要變成Resolved狀態需要p1,p2,p3狀態都是Resolved,如果p1,p2,p3至少有一個狀態是Rejected,p就會變成Rejected狀態

Promise.race()用法


var p = new Promise( [p1,p2,p3] )

只要p1、p2、p3之中有一個例項率先改變狀態,p的狀態就跟著改變。那個率先改變的 Promise 例項的返回值,就傳遞給p的回撥函式,p的狀態就會改變Resolved狀態

Promise resolve()用法


Promise.resolve('foo')
// 等價於
new Promise(resolve => resolve('foo'))

有時需要將現有物件轉為Promise物件,Promise.resolve方法就起到這個作用.

Promise reject()用法


Promise.reject('foo')
// 等價於
new Promise(reject => reject('foo'))

Promise.reject(reason)方法也會返回一個新的 Promise 例項,該例項的狀態為rejected。但是Promise.reject()方法的引數,會原封不動地作為reject的理由,變成後續方法的引數。這一點與Promise.resolve方法不一致。

原文地址:https://segmentfault.com/a/1190000016680014