【Vue 牛刀小試】:第十五章 - 傳統開發模式下的 axios 使用入門

系列目錄地址

前言

        在沒有接觸 React、Angular、Vue 這類 MVVM 的前端框架以前,沒法拋棄 Jquery 的重要理由,除了優秀的前端 DOM 元素操做性之外,可以很是便捷的發起 http 請求也佔有很是重要的地位。javascript

        既然咱們已經開始使用 Vue 進行前端開發,拋棄了對頁面 DOM 元素的操做,難道,爲了方便的發起 http 請求,還須要在項目中加載 jquery 或者是手動建立 http 請求嗎?html

        答案固然是不用的,做爲目前主流的前端框架,開發者、社區早已經爲咱們提供好了解決方案。隨着 Vue 做者尤雨溪宣佈再也不維護 vue-resource,轉而推薦你們使用 axios,目前在 Vue 社區中 axios 開始佔據 http 庫的主導地位,因此這一章咱們就介紹下如何使用 axios 發起 http 請求。前端

        倉儲地址(前端):Chapter02-Bronze Use Axios To Make HTTP Requestvue

        倉儲地址(後端):Chapter02-Bronze ASP.NET Core Sample APIjava

乾貨合集

        axios 是一個基於 Promise 的 http 客戶端,能夠用於瀏覽器和 node.js。官方文檔對於 axios 庫的使用方法已經寫的很清楚了,因此這裏只介紹如何與 Vue 進行結合,從而使用 axios 發起 http 請求。node

        這一章會涉及到簡單的先後端的數據交互,做爲一名 .NETer,本篇文章將採用 ASP.NET Core Web API 做爲後端服務,你能夠根據本身的喜愛進行選擇。固然,若是你以前並無接觸事後端,不知道怎麼選擇的話,推薦你嘗試 .NET Core,示例的後端項目我也會同步放在 Github 上。jquery

        PS:在後端模板項目上,我會添加對於 Swagger API 文檔的支持,以及在後端程序中進行配置跨域請求,從而容許後端接口能夠接受跨域請求的訪問。這些內容並不會在本篇文章中展示,若是你須要詳細瞭解,你能夠查看個人我的主頁上關於 ASP.NET Core 項目開發的內容,兩個系列相輔相成,後續全部涉及到先後端的交互開發,ASP.NET Core 相關的文章中進行呈現。webpack

        1、加載ios

        同目前的前端發展方向相同,axios 能夠從 npm、yarn、bower 這種前端包管理工具中進行下載,同時,也提供了 cdn 連接,方便咱們在傳統的項目中進行使用。git

// 使用 npm 加載
npm install axios

// 使用 bower 加載
bower install axios

// 使用 yarn 加載
yarn add axios
複製代碼

        在這篇文章中,我仍是與以前同樣,採用下載源文件的方式進行使用,在後續的前端框架搭建完成後再改用前端包管理工具進行加載。

// 使用 cdn 加載
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
複製代碼

        2、get & post

        相比於 put 請求和 delete 請求,get 請求和 post 請求是咱們最經常使用的兩個方法,一個很常見的使用場景,咱們經過 get 請求來搜索數據,經過 post 請求來提交數據。

        在示例的後端接口中,提供了五個接口方法,分別對應了 get、post、put、delete 這四個 HTTP 謂詞。put 和 delete 對應的接口方法這裏並無實現,這篇文章主要使用的是 get 和 post 謂詞對應的三個接口。

        一、獲取全部的用戶數據(/api/user)

        get 請求,加載所有的用戶數據,按照建立時間進行降序排列。

        二、根據搜索條件搜索用戶數據(/api/user/query)

        get 請求,根據用戶輸入框輸入的數據,從所有的用戶數據中查找出符合條件的數據,由於這裏會存在多個查詢條件,其實並不太符合 Restful 的接口設計,因此這裏我採用 ASP.NET Core 中的特性路由的方式,指定此路由爲專門的數據查詢接口。

        三、新增用戶數據(/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 指向
        能夠看到,這裏的 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 請求傳參
        與 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>
複製代碼

實現效果

        3、 攔截器

        在先後端分離的項目中,咱們通常採用 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 相關的知識點。同時,一些在以前的學習中沒有涉及到的知識點也會在後續的文章中進行補充。以後,就像開篇時所說的那樣,後期的關注點將聚焦於如何經過 ASP.NET Core 和 Vue 進行先後端開發,歡迎持續關注~~~

佔坑

        做者:墨墨墨墨小宇
        我的簡介:96年生人,出生於安徽某四線城市,畢業於Top 10000000 院校。.NET程序員,槍手死忠,喵星人。於2016年12月開始.NET程序員生涯,微軟.NET技術的堅決堅持者,立志成爲雲養貓的少年中面向谷歌編程最厲害的.NET程序員。
        我的博客:yuiter.com
        博客園博客:www.cnblogs.com/danvic712

相關文章
相關標籤/搜索