vue-resource插件使用

本文的主要內容以下:javascript

  • 介紹vue-resource的特色
  • 介紹vue-resource的基本使用方法
  • 基於this.$http的增刪查改示例
  • 基於this.$resource的增刪查改示例
  • 基於inteceptor實現請求等待時的loading畫面
  • 基於inteceptor實現請求錯誤時的提示畫面

本文11個示例的源碼已放到GitHub,若是您以爲本篇內容不錯,請點個贊,或在GitHub上加個星星!html

GitHub Source前端

本文的全部示例以下:vue

各位在閱讀這篇文章的內容時,能夠先嚐試該列表的最後兩個示例,這兩個示例綜合使用了this.$http和inteceptor。java

vue-resource特色

vue-resource插件具備如下特色:git

1. 體積小github

vue-resource很是小巧,在壓縮之後只有大約12KB,服務端啓用gzip壓縮後只有4.5KB大小,這遠比jQuery的體積要小得多。ajax

2. 支持主流的瀏覽器json

和Vue.js同樣,vue-resource除了不支持IE 9如下的瀏覽器,其餘主流的瀏覽器都支持。後端

3. 支持Promise API和URI Templates

Promise是ES6的特性,Promise的中文含義爲「先知」,Promise對象用於異步計算。
URI Templates表示URI模板,有些相似於ASP.NET MVC的路由模板。

4. 支持攔截器

攔截器是全局的,攔截器能夠在請求發送前和發送請求後作一些處理。
攔截器在一些場景下會很是有用,好比請求發送前在headers中設置access_token,或者在請求失敗時,提供共通的處理方式。

vue-resource使用

引入vue-resource

<script src="js/vue.js"></script> <script src="js/vue-resource.js"></script> 

基本語法

引入vue-resource後,能夠基於全局的Vue對象使用http,也能夠基於某個Vue實例使用http。

// 基於全局Vue對象使用http
Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback); Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback); // 在一個Vue實例內使用$http this.$http.get('/someUrl', [options]).then(successCallback, errorCallback); this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

在發送請求後,使用then方法來處理響應結果,then方法有兩個參數,第一個參數是響應成功時的回調函數,第二個參數是響應失敗時的回調函數。

then方法的回調函數也有兩種寫法,第一種是傳統的函數寫法,第二種是更爲簡潔的ES 6的Lambda寫法:

// 傳統寫法
this.$http.get('/someUrl', [options]).then(function(response){ // 響應成功回調 }, function(response){ // 響應錯誤回調 }); // Lambda寫法 this.$http.get('/someUrl', [options]).then((response) => { // 響應成功回調 }, (response) => { // 響應錯誤回調 }); 

PS:作過.NET開發的人想必對Lambda寫法有一種熟悉的感受。

支持的HTTP方法

vue-resource的請求API是按照REST風格設計的,它提供了7種請求API:

  • get(url, [options])
  • head(url, [options])
  • delete(url, [options])
  • jsonp(url, [options])
  • post(url, [body], [options])
  • put(url, [body], [options])
  • patch(url, [body], [options])

除了jsonp之外,另外6種的API名稱是標準的HTTP方法。當服務端使用REST API時,客戶端的編碼風格和服務端的編碼風格近乎一致,這能夠減小前端和後端開發人員的溝通成本。

客戶端請求方法 服務端處理方法
this.$http.get(...) Getxxx
this.$http.post(...) Postxxx
this.$http.put(...) Putxxx
this.$http.delete(...) Deletexxx

options對象

發送請求時的options選項對象包含如下屬性:

參數 類型 描述
url string 請求的URL
method string 請求的HTTP方法,例如:'GET', 'POST'或其餘HTTP方法
body ObjectFormDatastring request body
params Object 請求的URL參數對象
headers Object request header
timeout number 單位爲毫秒的請求超時時間 (0 表示無超時時間)
before function(request) 請求發送前的處理函數,相似於jQuery的beforeSend函數
progress function(event) ProgressEvent回調處理函數
credientials boolean 表示跨域請求時是否須要使用憑證
emulateHTTP boolean 發送PUT, PATCH, DELETE請求時以HTTP POST的方式發送,並設置請求頭的X-HTTP-Method-Override
emulateJSON boolean 將request body以application/x-www-form-urlencoded content type發送

emulateHTTP的做用

若是Web服務器沒法處理PUT, PATCH和DELETE這種REST風格的請求,你能夠啓用enulateHTTP現象。啓用該選項後,請求會以普通的POST方法發出,而且HTTP頭信息的X-HTTP-Method-Override屬性會設置爲實際的HTTP方法。

Vue.http.options.emulateHTTP = true;

emulateJSON的做用

若是Web服務器沒法處理編碼爲application/json的請求,你能夠啓用emulateJSON選項。啓用該選項後,請求會以application/x-www-form-urlencoded做爲MIME type,就像普通的HTML表單同樣。

Vue.http.options.emulateJSON = true;

response對象

response對象包含如下屬性:

方法 類型 描述
text() string 以string形式返回response body
json() Object 以JSON對象形式返回response body
blob() Blob 以二進制形式返回response body
屬性 類型 描述
ok boolean 響應的HTTP狀態碼在200~299之間時,該屬性爲true
status number 響應的HTTP狀態碼
statusText string 響應的狀態文本
headers Object 響應頭

注意:本文的vue-resource版本爲v0.9.3,若是你使用的是v0.9.0之前的版本,response對象是沒有json(), blob(), text()這些方法的。

CURD示例

提示:如下示例仍然沿用上一篇的組件和WebAPI,組件的代碼和頁面HTML代碼我就再也不貼出來了。

GET請求

var demo = new Vue({ el: '#app', data: { gridColumns: ['customerId', 'companyName', 'contactName', 'phone'], gridData: [], apiUrl: 'http://211.149.193.19:8080/api/customers' }, ready: function() { this.getCustomers() }, methods: { getCustomers: function() { this.$http.get(this.apiUrl) .then((response) => { this.$set('gridData', response.data) }) .catch(function(response) { console.log(response) }) } } }) 

這段程序的then方法只提供了successCallback,而省略了errorCallback。
catch方法用於捕捉程序的異常,catch方法和errorCallback是不一樣的,errorCallback只在響應失敗時調用,而catch則是在整個請求到響應過程當中,只要程序出錯了就會被調用。

在then方法的回調函數內,你也能夠直接使用this,this仍然是指向Vue實例的:

getCustomers: function() { this.$http.get(this.apiUrl) .then((response) => { this.$set('gridData', response.data) }) .catch(function(response) { console.log(response) }) }

爲了減小做用域鏈的搜索,建議使用一個局部變量來接收this。

image

View Demo

JSONP請求

getCustomers: function() { this.$http.jsonp(this.apiUrl).then(function(response){ this.$set('gridData', response.data) }) } 

View Demo

POST請求

var demo = new Vue({ el: '#app', data: { show: false, gridColumns: [{ name: 'customerId', isKey: true }, { name: 'companyName' }, { name: 'contactName' }, { name: 'phone' }], gridData: [], apiUrl: 'http://211.149.193.19:8080/api/customers', item: {} }, ready: function() { this.getCustomers() }, methods: { closeDialog: function() { this.show = false }, getCustomers: function() { var vm = this vm.$http.get(vm.apiUrl) .then((response) => { vm.$set('gridData', response.data) }) }, createCustomer: function() { var vm = this vm.$http.post(vm.apiUrl, vm.item) .then((response) => { vm.$set('item', {}) vm.getCustomers() }) this.show = false } } }) 

29

View Demo

PUT請求

updateCustomer: function() { var vm = this vm.$http.put(this.apiUrl + '/' + vm.item.customerId, vm.item) .then((response) => { vm.getCustomers() }) } 

30

View Demo

Delete請求

deleteCustomer: function(customer){ var vm = this vm.$http.delete(this.apiUrl + '/' + customer.customerId) .then((response) => { vm.getCustomers() }) } 

31

View Demo

使用resource服務

vue-resource提供了另一種方式訪問HTTP——resource服務,resource服務包含如下幾種默認的action:

get: {method: 'GET'},
save: {method: 'POST'}, query: {method: 'GET'}, update: {method: 'PUT'}, remove: {method: 'DELETE'}, delete: {method: 'DELETE'}

resource對象也有兩種訪問方式:

  • 全局訪問:Vue.resource
  • 實例訪問:this.$resource

resource能夠結合URI Template一塊兒使用,如下示例的apiUrl都設置爲{/id}了:

apiUrl: 'http://211.149.193.19:8080/api/customers{/id}'

GET請求

使用get方法發送GET請求,下面這個請求沒有指定{/id}

getCustomers: function() { var resource = this.$resource(this.apiUrl) vm = this resource.get() .then((response) => { vm.$set('gridData', response.data) }) .catch(function(response) { console.log(response) }) }

View Demo

POST請求

使用save方法發送POST請求,下面這個請求沒有指定{/id}

createCustomer: function() { var resource = this.$resource(this.apiUrl) vm = this resource.save(vm.apiUrl, vm.item) .then((response) => { vm.$set('item', {}) vm.getCustomers() }) this.show = false } 

View Demo

PUT請求

使用update方法發送PUT請求,下面這個請求指定了{/id}

updateCustomer: function() { var resource = this.$resource(this.apiUrl) vm = this resource.update({ id: vm.item.customerId}, vm.item) .then((response) => { vm.getCustomers() }) } 

{/id}至關於一個佔位符,當傳入實際的參數時該佔位符會被替換。
例如,{ id: vm.item.customerId}中的vm.item.customerId爲12,那麼發送的請求URL爲:

http://211.149.193.19:8080/api/customers/12

View Demo

DELETE請求

使用remove或delete方法發送DELETE請求,下面這個請求指定了{/id}

deleteCustomer: function(customer){ var resource = this.$resource(this.apiUrl) vm = this resource.remove({ id: customer.customerId}) .then((response) => { vm.getCustomers() }) } 

View Demo

使用inteceptor

攔截器能夠在請求發送前和發送請求後作一些處理。

image

基本用法

Vue.http.interceptors.push((request, next) => {
        // ...
        // 請求發送前的處理邏輯 // ... next((response) => { // ... // 請求發送後的處理邏輯 // ... // 根據請求的狀態,response參數會返回給successCallback或errorCallback return response }) }) 

在response返回給successCallback或errorCallback以前,你能夠修改response中的內容,或作一些處理。
例如,響應的狀態碼若是是404,你能夠顯示友好的404界面。

若是不想使用Lambda函數寫法,能夠用平民寫法:

 

Vue.http.interceptors.push(function(request, next) { // ... // 請求發送前的處理邏輯 // ... next(function(response) { // ... // 請求發送後的處理邏輯 // ... // 根據請求的狀態,response參數會返回給successCallback或errorCallback return response }) }) 

示例1

以前的CURD示例有一處用戶體驗不太好,用戶在使用一些功能的時候若是網絡較慢,畫面又沒有給出反饋,用戶是不知道他的操做是成功仍是失敗的,他也不知道是否該繼續等待。

經過inteceptor,咱們能夠爲全部的請求處理加一個loading:請求發送前顯示loading,接收響應後隱藏loading。

具體步驟以下:

1.添加一個loading組件

<template id="loading-template"> <div class="loading-overlay"> <div class="sk-three-bounce"> <div class="sk-child sk-bounce1"></div> <div class="sk-child sk-bounce2"></div> <div class="sk-child sk-bounce3"></div> </div> </div> </template> 

2.將loading組件做爲另一個Vue實例的子組件

var help = new Vue({ el: '#help', data: { showLoading: false }, components: { 'loading': { template: '#loading-template', } } }) 

3.將該Vue實例掛載到某個HTML元素

<div id="help">
    <loading v-show="showLoading"></loading> </div> 

4.添加inteceptor

Vue.http.interceptors.push((request, next) => {
    loading.show = true
    next((response) => {
        loading.show = false return response }); }); 

27

View Demo

示例2

當用戶在畫面上停留時間過久時,畫面數據可能已經不是最新的了,這時若是用戶刪除或修改某一條數據,若是這條數據已經被其餘用戶刪除了,服務器會反饋一個404的錯誤,但因爲咱們的put和delete請求沒有處理errorCallback,因此用戶是不知道他的操做是成功仍是失敗了。

你問我爲何不在每一個請求裏面處理errorCallback,這是由於我比較懶。這個問題,一樣也能夠經過inteceptor解決。

1. 繼續沿用上面的loading組件,在#help元素下加一個對話框

<div id="help"> <loading v-show="showLoading" ></loading> <modal-dialog :show="showDialog"> <header class="dialog-header" slot="header"> <h1 class="dialog-title">Server Error</h1> </header> <div class="dialog-body" slot="body"> <p class="error">Oops,server has got some errors, error code: {{errorCode}}.</p> </div> </modal-dialog> </div> 

2.給help實例的data選項添加兩個屬性

var help = new Vue({ el: '#help', data: { showLoading: false, showDialog: false, errorCode: '' }, components: { 'loading': { template: '#loading-template', } } }) 

3.修改inteceptor

Vue.http.interceptors.push((request, next) => {
    help.showLoading = true
    next((response) => {
        if(!response.ok){ help.errorCode = response.status help.showDialog = true } help.showLoading = false return response }); }); 

28

View Demo

總結

vue-resource是一個很是輕量的用於處理HTTP請求的插件,它提供了兩種方式來處理HTTP請求:

  • 使用Vue.http或this.$http
  • 使用Vue.resource或this.$resource

這兩種方式本質上沒有什麼區別,閱讀vue-resource的源碼,你能夠發現第2種方式是基於第1種方式實現的。

inteceptor能夠在請求前和請求後附加一些行爲,這意味着除了請求處理的過程,請求的其餘環節均可以由咱們來控制。

相關文章
相關標籤/搜索