在沒有接觸 React、Angular、Vue 這類 MVVM 的前端框架以前,沒法拋棄 Jquery 的重要理由,除了優秀的前端 DOM 元素操做性之外,可以很是便捷的發起 http 請求也佔有很是重要的地位。html
既然咱們已經開始使用 Vue 進行前端開發,拋棄了對頁面 DOM 元素的操做,難道,爲了方便的發起 http 請求,還須要在項目中加載 jquery 或者是手動建立 http 請求嗎?前端
答案固然是不用的,做爲目前主流的前端框架,開發者、社區早已經爲咱們提供好了解決方案。隨着 Vue 做者尤雨溪宣佈再也不維護 vue-resource,轉而推薦你們使用 axios,目前在 Vue 社區中 axios 開始佔據 http 庫的主導地位,因此這一章咱們就介紹下如何使用 axios 發起 http 請求。vue
學習系列目錄地址:http://www.javashuo.com/article/p-bzzucmub-ba.htmlnode
倉儲地址(前端):https://github.com/Lanesra712/VueTrial/blob/master/chapter02-bronze/front/axios.htmljquery
倉儲地址(後端):https://github.com/Lanesra712/VueTrial/tree/master/chapter02-bronze/rear/Samplewebpack
axios 是一個基於 Promise 的 http 客戶端,能夠用於瀏覽器和 node.js。官方文檔對於 axios 庫的使用方法已經寫的很清楚了,因此這裏只介紹如何與 Vue 進行結合,從而使用 axios 發起 http 請求。ios
這一章會涉及到簡單的先後端的數據交互,做爲一名 .NETer,本篇文章將採用 ASP.NET Core Web API 做爲後端服務,你能夠根據本身的喜愛進行選擇。固然,若是你以前並無接觸事後端,不知道怎麼選擇的話,推薦你嘗試 .NET Core,示例的後端項目我也會同步放在 Github 上。git
PS:在後端模板項目上,我會添加對於 Swagger API 文檔的支持,以及在後端程序中進行配置跨域請求,從而容許後端接口能夠接受跨域請求的訪問。這些內容並不會在本篇文章中展示,若是你須要詳細瞭解,你能夠查看另外一個系列的文章(ASP.NET Core 項目實戰)那裏會介紹一些關於 ASP.NET Core 項目的開發,兩個系列相輔相成,後續全部涉及到先後端的交互開發,所有在此係列(ASP.NET Core 項目實戰)中進行呈現。github
同目前的前端發展方向相同,axios 能夠從 npm、yarn、bower 這種前端包管理工具中進行下載,同時,也提供了 cdn 連接,方便咱們在傳統的項目中進行使用。web
// 使用 npm 加載 npm install axios // 使用 bower 加載 bower install axios // 使用 yarn 加載 yarn add axios
在這篇文章中,我仍是與以前同樣,採用下載源文件的方式進行使用,在後續的前端框架搭建完成後再改用前端包管理工具進行加載。
// 使用 cdn 加載 <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
相比於 put 請求和 delete 請求,get 請求和 post 請求是咱們最經常使用的兩個方法,一個很常見的使用場景,咱們經過 get 請求來搜索數據,經過 post 請求來提交數據。
在示例的後端接口中,提供了五個接口方法,分別對應了 get、post、put、delete 這四個 HTTP 謂詞。put 和 delete 對應的接口方法這裏並無實現,這篇文章主要使用的是 get 和 post 謂詞對應的三個接口。
2.一、獲取全部的用戶數據(/api/user)
get 請求,加載所有的用戶數據,按照建立時間進行降序排列。
2.二、根據搜索條件搜索用戶數據(/api/user/query)
get 請求,根據用戶輸入框輸入的數據,從所有的用戶數據中查找出符合條件的數據,由於這裏會存在多個查詢條件,其實並不太符合 Restful 的接口設計,因此這裏我採用 ASP.NET Core 中的特性路由的方式,指定此路由爲專門的數據查詢接口。
2.三、新增用戶數據(/api/user)
post 請求,提交一條新的用戶數據,由於是採用 Restful 風格的接口設計,因此請求的地址與獲取全部的用戶數據相同,僅僅是 http 謂詞的不一樣。
最終實現的前端頁面以下所示,頁面第一次加載時會加載所有的用戶數據;當用戶點擊搜索按鈕時,會根據頂部的三個輸入框中的值,從用戶數據中進行篩選;當點擊新增按鈕時,則會根據 Name 和 Email 輸入框中的值新增一條新的用戶數據。
首先咱們須要在頁面加載的時候請求後端接口,去獲取咱們的用戶數據,這裏咱們在 Vue 實例的 methods 中定義一個 getList 方法,在這個方法中咱們去請求後端接口。
在以前學習 Vue 的生命週期鉤子函數時咱們瞭解到,在 created 鉤子函數中,對於 Vue 實例的 data 和 methods 已經初始化完成,此時,整個 Vue 實例已經初始化完成。可是,初始化完成的 Vue 實例沒有與 DOM 進行綁定。因此,若是咱們想要在頁面初始加載時就渲染出整個用戶信息表格,created 函數是可以調用 getList 方法最先的一個鉤子函數。
在 axios 中,咱們發起一個 http 請求後,在 then 回掉方法中進行請求成功後的數據處理,在 catch 回掉方法中捕獲請求失敗的信息。這裏的 then 方法就至關於咱們在 Jquery 中使用 ajax 時的 success 回調方法,而 catch 方法則是 error 回調。
axios.get('http://localhost:5000/api/user') .then(function (response) { console.log(response) }).catch(function (error) { console.log(error) })
從接口打印出的返回結果能夠看到,接口返回的 response 中包含了五部分的信息。這裏 data 屬性顯示的就是整個的用戶數據集合,在實際使用中,你須要與 http 響應狀態碼進行結合,考慮若是後端出現錯誤如何使前端知曉,從而相對友好的通知用戶。
{ // 後端接口返回的數據 data: {}, // 服務端接口返回的 HTTP 狀態碼 status: 200, // 服務端接口返回的 HTTP 狀態信息 statusText: 'OK', // 後端接口返回的響應 header 信息 headers: {}, // axios 發起的接口請求時的配置信息 config: {}, // 接口響應的請求信息 request: {} }
針對 axios 發起請求時的配置信息,咱們能夠本身進行配置。例如咱們能夠設置請求的接口域名是什麼,設置 post 請求時的 Content-Type,或者針對先後端數據交互時常用的 Jwt Token 驗證,咱們能夠在請求的 header 中添加 token 信息,從而經過後端的權限驗證。
axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
當咱們獲取到全部的用戶數據後,咱們就能夠將結果值賦值給咱們 Vue 實例中的 users 數據集合對象(這個 users 須要你事先在 Vue 實例的 data 中進行提早定義好)。
axios.get('http://localhost:5000/api/user') .then(function (response) { console.log(response) this.users = response.data }).catch(function (error) { console.log(error) })
若是你按照上面的寫法進行賦值,你會發現頁面上並無按照咱們的想法渲染出數據。既然咱們已經獲取到了後端接口返回的數據值,那麼這裏的問題就可能出如今賦值這上面。咱們能夠在 then 回調中打印 this.users 看看。
能夠看到,這裏的 this 指向的實際上是瀏覽器的 window 對象,所以咱們給 this.users 賦值最終是賦值到 window 對象上了。由於是 this 指向出了問題,因此這裏我就直接採用箭頭函數的方式進行數據賦值,最終的實現代碼以下所示。
var vm = new Vue({ el: '#app', data: { id: '', name: '', email: '', users: [] }, created() { this.getList() }, methods: { getList() { axios.get('http://localhost:5000/api/user') .then(response => { this.users = response.data }).catch(error => { console.log(error) }) } }, });
搜索按鈕的功能與獲取全部用戶信息的代碼比較類似,這裏咱們須要將搜索的參數添加到 get 請求中。從下圖的瀏覽器控制檯中能夠看到,當點擊查詢按鈕以後,咱們添加的參數會以 query 查詢字符串的方式添加到請求的 url 地址上。
var vm = new Vue({ el: '#app', data: { id: '', name: '', email: '', users: [] }, methods: { search() { axios.get('http://localhost:5000/api/user/query', { params: { id: this.id, name: this.name, email: this.email, } }).then(response => { this.users = response.data }).catch(error => { console.log(error) }) } }, });
與 get 請求類似,使用 axios 發起 post 請求也是在 then 回掉方法中獲取接口返回值,在 catch 回掉方法中捕獲錯誤信息。
var vm = new Vue({ el: '#app', data: { id: '', name: '', email: '', users: [] }, methods: { getList() { axios.get('http://localhost:5000/api/user') .then(response => { this.users = response.data }).catch(error => { console.log(error) }) }, add() { axios.post('http://localhost:5000/api/user', { name: this.name, email: this.email, }).then(response => { console.log(response) this.getList() }).catch(error => { console.log(error) }) } }, });
就像咱們使用 jquery 發起 ajax 請求同樣,咱們可使用 $.ajax/$.post 方法去發起一個 get/post 請求,也能夠在 $.ajax 方法中經過指定請求的 type 類型來肯定咱們是以 get 請求仍是 post 請求的方式執行,在 axios 中也提供了類似的功能。
// get 請求 axios({ method: 'get', url: 'http://localhost:5000/api/user' }) // post 請求 axios({ method: 'post', url: 'http://localhost:5000/api/user', data: { name: this.name, email: this.email, } });
整個前端頁面完整的示例代碼以及實現的效果以下所示。
<div id="app"> <div class="card border-info mb-3" style="margin-top: 20px;"> <div class="card-header text-info"> <b>用戶信息</b> </div> <div class="card-body text-info form-inline"> <div class="form-row"> <div class="form-group"> <div class="input-group mb-2 mr-sm-2"> <div class="input-group-prepend"> <div class="input-group-text text-info"> Id </div> </div> <input type="text" class="form-control" id="id" v-model="id" autocomplete="off"> </div> </div> <div class="form-group"> <div class="input-group mb-2 mr-sm-2"> <div class="input-group-prepend"> <div class="input-group-text text-info"> Name </div> </div> <input type="text" class="form-control" id="name" v-model="name" autocomplete="off"> </div> </div> <div class="form-group"> <div class="input-group mb-2 mr-sm-2"> <div class="input-group-prepend"> <div class="input-group-text text-info"> Email </div> </div> <input type="email" class="form-control" id="email" v-model="email" autocomplete="off"> </div> </div> <div class="form-group"> <a class="btn btn-info" href="#" role="button" @click="search">搜索</a> <a class="btn btn-success" href="#" role="button" @click="add">新增</a> </div> </div> </div> </div> <table class="table table-striped table-bordered table-hover text-info"> <thead class="thead-inverse"> <tr> <th>Id</th> <th>Name</th> <th>Email</th> <th>Created On</th> </tr> </thead> <tbody> <tr v-for="item in users" :key="item.id"> <td scope="row">{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.email}}</td> <td>{{item.createdTime}}</td> </tr> </tbody> </table> </div> <script> var vm = new Vue({ el: '#app', data: { id: '', name: '', email: '', users: [] }, created() { this.getList() }, methods: { getList() { axios.get('http://localhost:5000/api/user') .then(response => { this.users = response.data }).catch(error => { console.log(error) }) }, search() { axios.get('http://localhost:5000/api/user/query', { params: { id: this.id, name: this.name, email: this.email, } }).then(response => { this.users = response.data }).catch(error => { console.log(error) }) }, add() { axios.post('http://localhost:5000/api/user', { name: this.name, email: this.email, }).then(response => { console.log(response) this.getList() }).catch(error => { console.log(error) }) } }, }); </script>
在先後端分離的項目中,咱們通常採用 Jwt token 的方式進行權限控制。前端在獲取數據以前,須要從後端獲取到 token 令牌。當前端獲取到後端回傳的 token 信息後,咱們須要將此 token 信息保存下來,此後全部的請求都須要在請求的 header 信息中添加此 token 信息。那麼,能不能有一種方式能夠在觸發後端驗證以前,統一的進行 token 信息校驗,當判斷沒有包含 token 信息以後,前端直接跳轉到登陸頁面。
在 axios 中,咱們能夠將此類操做放置到攔截器中。你能夠將 axios 中的攔截器當作是 ASP.NET Core 中的 Filters 過濾器,例如,這裏的需求,咱們徹底能夠將獲取到的 token 信息置於 request 請求攔截器中,在發起的每一次 http 請求時去校驗是否包含 token 信息,當沒有包含 token 信息時,就能夠直接跳轉到登陸頁面。
這裏由於我並無實現後端 token 驗證,因此這裏就只是進行一個演示,你能夠從瀏覽器的控制檯中看到只要咱們發起一個 http 請求,就會輸出的咱們打印的信息。
// request 請求攔截 axios.interceptors.request.use(function (request) { // 對 request 進行攔截 if(true){ console.log('跳轉到登陸頁面') } return request; }, function (error) { // 在錯誤請求時進行操做 return Promise.reject(error); });
既然有針對發起 request 請求時的攔截器,毫無疑問,對於獲取到接口返回的 response 信息,咱們一樣可使用攔截器進行攔截。例如,在定義 restful 接口時,咱們通常會根據 http 響應狀態碼去反映接口的調用是否成功。在每個經過 axios 發起請求的 then 回掉方法中,咱們都須要對獲取到響應狀態碼進行判斷,判斷接口的調用是否成功。
當咱們使用攔截器後,咱們徹底能夠在針對 response 的攔截器中進行統一的判斷。例如,當調用接口不成功時,http 響應狀態碼爲 400,同時返回錯誤信息,咱們徹底能夠在攔截器中進行判斷,當全部的接口響應狀態碼爲 400 時,彈出後端返回的錯誤信息。
// response 請求攔截 axios.interceptors.response.use(function (response) { // 對 response 進行攔截 switch (response.status) { case 200: console.log('接口訪問成功') break case 400: console.log('提示錯誤信息') break case 401: console.log('重定向到登陸頁面') break } return response; }, function (error) { // 在錯誤請求時進行操做 return Promise.reject(error); });
這篇文章主要是簡單介紹如何使用 axios 去實現發起一個 http 請求。至此,在現階段的 Vue 學習使用中,對於一些基礎知識點就已經完成了一個初步的梳理,接下來,從下一章開始,我會從 0 開始經過 Vue CLI 去搭建一個前端的項目模板,由於本身並非一個前端開發人員,我的的關注點還在於 .NET Core 後端,因此這裏可能並不會涉及到 webpack 相關的知識點。同時,一些在以前的學習中沒有涉及到的知識點也會在後續的文章中進行補充。以後,就像開篇時所說的那樣,Vue.js 牛刀小試 和 ASP.NET Core 項目實戰 相輔相成,後期的關注點將聚焦於如何經過 ASP.NET Core 和 Vue 進行先後端開發,歡迎持續關注~~~