快速構建一個使用axios的vue應用程序

這篇文章講述瞭如何快速構建一個vue程序,並使用axios從遠程獲取數據。
這是原文章的直通門css

一般狀況下,在構建JavaScript應用程序時,會從遠程獲取數據或使用API。我最近研究了一些公用API,發現有不少很酷的東西能夠用在這些獲取到的數據上。html

我將演示如何構建一個簡單的新聞app,它將顯示當天的熱門新聞,還容許用戶經過感興趣的類別進行過濾。咱們將從紐約時報API獲取數據。能夠在這裏找到本教程的完整代碼。vue

下面是最終app的效果:
圖片描述webpack

要使用本教程,你將須要瞭解基本的Vue.js知識。這是一個vue教程直達。教程將使用ES6語法。ios

項目結構

咱們將只用2個文件來保持項目簡潔:git

./app.js
./index.html

app.js包含整個app的邏輯,index.html包含整個app的界面。github

咱們從index.html開始:web

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset="utf-8">
        <title>最偉大的新聞app</title>
    </head>
    <body>
        <div class="container" id="app">
            <h3 class="text-center">Vue新聞</h3>
        </div>
    </body>
</html>

而後,在index.html的底部,在</body>標籤以前,引入Vue.jsapp.jsajax

<script src="https://unpkg.com/vue"></script>
<script src="app.js"></script>

可選地,能夠引入Foundation,以利用一些預製樣式,使咱們的界面看起來更好一點。 將其包含在<head>標籤中:json

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css">

建立一個簡單Vue應用程序

首先,咱們將在元素div#app上建立一個新的Vue實例,並使用一些測試數據來模擬新聞API的響應:

// ./app.js
const vm = new Vue({
    el: '#app',
    data: {
        results: [
            {title: '第一條新聞', abstract: '我是第一條新聞'},
            {title: '接着是第二條', abstract: '我是第二條新聞'},
            {title: '而後是第三條', abstract: '我是第三條新聞'},
            {title: '我是最後一條了', abstract: '我是第四條新聞'}
        ]
    }
});

咱們經過el參數告訴Vue要掛載的元素,並經過data參數指定咱們的app將使用哪些數據。

要在咱們的應用程序中顯示模擬數據,能夠在#app元素中寫入:

<!-- ./index.html -->
<div class="columns medium-3" v-for="result in results">
    <div class="card">
        <div class="card-divider">
            {{ result.title }}
        </div>
        <div class="card-section">
            <p>{{ result.abstract }}.</p>
        </div>
    </div>
</div>

v-for指令用於渲染咱們的列表。咱們還使用雙花括號來顯示每個result的內容。

咱們如今有一個基本的佈局結構了:
圖片描述

從API獲取數據

要使用紐約時報API,須要得到一個API密鑰。因此若是你沒有的話,點擊這裏,註冊以獲取Top Stories API的API密鑰(註冊時API一欄選擇Top Stories API)。

使用Ajax請求和處理響應

Axios是一個基於promise的HTTP客戶端,用於發送Ajax請求。它提供了簡單而豐富的API。它與fetch API很是類似,但不須要爲舊版瀏覽器添加一個polyfill,還有一些其餘的細微之處。

引入axios:

<!-- ./index.html -->
<script src="https://cdn.bootcss.com/axios/0.16.0/axios.min.js"></script>

如今,一旦咱們的Vue應用程序掛載(mounted),咱們就發送請求獲取top stories的列表:

// ./app.js
const vm = new Vue({
    el: '#app',
    data: {
        results: []
    },
    mounted() {
        axios.get("https://api.nytimes.com/svc/topstories/v2/home.json?api-key=your_api_key")
        .then(response => {
            this.results = response.data.resultes})
    }
});

注意:將your_api_key替換爲以前註冊得到的API key。

如今咱們能夠在咱們的主頁上看到新聞列表。不要擔憂不美觀的界面,咱們會在後面處理:
圖片描述

經過Vue Devtools來看看API的響應:
圖片描述

爲了使咱們的項目更加整潔,可複用,咱們將作一些小的重構,並介紹一個幫助函數來構建咱們的URL。 咱們還將註冊getPosts做爲咱們應用程序的一個方法((將其添加到vue對象的method參數中):

// ./app.js
const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";
const Apikey = "your_api_key";

function buildUrl(url) {
    return NYTBaseUrl + url + ".json?api-key=" + Apikey;
}

const vm = new Vue ({
    el: '#app',
    data: {
        results: []
    },
    mounted () {
        this.getPosts('home');
    },
    methods: {
        getPosts(section) {
            let url = buildUrl(section);
            axios.get(url).then((response) => {
                this.results = response.data.results;
            }).catch(error => {
                console.log(error);
            });
        }
    }
});

咱們能夠經過引入計算屬性(computed property)對API得到的原始結果進行一些修改,從而對咱們的視圖的外觀進行一些更改。

const vm = new Vue ({
    el: '#app',
    data: {
        results: []
    },
    mounted () {
        this.getPosts('home');
    },
    methods: {
        getPosts(section) {
            let url = buildUrl(section);
            axios.get(url).then((response) => {
                this.results = response.data.results;
            }).catch(error => {
                console.log(error);
            });
        }
    },
    computed: {
        processedPosts() {
            let posts = this.results;
            
            //添加image_url屬性
            posts.map(post => {
                let imgObj = post.multimedia.find(media => media.format === "superJumbo");
                post.image_url = imgObj ? imgObj.url : "http://placehold.it/300x200?text=N/A";
            });
            
            //將數據分組
            let i, j, chunkedArray = [], chunk = 4;
            for (i = 0, j = 0; i < posts.length; i += chunk, j++) {
                chunkedArray[j] = posts.slice(i, i + chunk);
            }
            return chunkedArray;
        }
    }
});

在上述代碼中,在計算屬性processedPosts中,咱們附加一個image_url屬性給每一個新聞對象:
咱們經過循環遍歷API的results,並經過在multimedia數組中對單個元素搜索來查找所需格式的媒體,而後將該媒體的URL賦值給image_url屬性。在媒體不可用的狀況下,咱們將默認圖片地址設置爲來自Placehold.it的圖像。

咱們還寫了一個循環來將咱們的results數組分爲四個一組,這將會處理咱們前面看到的不美觀界面。

Note: 你也可使用像Lodash這樣的庫進行分塊。

計算屬性很是適合操縱數據。每當咱們須要將results數組分組時,咱們能夠將它定義爲一個計算屬性,按照咱們的意願使用它,由於Vue會在results改動時自動更新processedPosts

計算屬性也基於它們的依賴關係進行緩存,所以只要results不改變,processedPosts屬性將返回自身的緩存值。這將有助於性能,特別是在進行復雜的數據操做時。

接下來,咱們在index.html中修改咱們的html標籤,以顯示咱們的計算結果:

<!-- ./index.html -->
<div class="row" v-for="posts in processedPosts">
    <div class="columns large-3 medium-6" v-for="post in posts">
        <div class="card">
            <div class="card-divider">
                {{ post.title }}
            </div>
            <a :href="post.url" target="_blank">
                <img :src="post.image_url">
            </a>
            <div class="card-section">
                <p>{{ post.abstract }}</p>
            </div>
        </div>
    </div>
</div>

如今咱們的app看起來美觀一些了:
圖片描述

新聞列表組件

組件用於將應用程序模塊化。「新聞列表」能夠重構爲一個組件,例如,若是咱們的app成長起來,而且決定在別的地方也使用新聞列表,組件將會使這變得很容易。

// ./app.js
Vue.component('news-list', {
    props: ['results'],
    template: `
        <section>
            <div class="row" v-for="posts in processedPosts">
                <div class="columns large-3 medium-6" v-for="post in posts">
                    <div class="card">
                        <div class="card-divider">
                        {{ post.title }}
                        </div>
                        <a :href="post.url" target="_blank"><img :src="post.image_url"></a>
                        <div class="card-section">
                            <p>{{ post.abstract }}</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    `,
    computed: {
        processedPosts() {
            //...
        }
    }
});

在上面的代碼中,咱們註冊了一個全局組件:
Vue.component(tagName,options)。建議在定義tagName時使用連字符,這樣它們不會與標準HTML標籤發生衝突。

咱們來簡單看一下其餘幾個參數:

  • props:這是一個咱們但願從父做用域傳遞給組件的數組。 咱們傳遞了results,由於咱們從主應用程序實例加載組件。

  • template:在這裏咱們定義新聞列表的html。注意,咱們將列表包裝在<section>標籤中。這是由於組件須要有一個單獨的根元素,而不是多個元素。

調整咱們的html代碼以使用咱們的新聞列表組件,並傳遞results數據:

<!-- ./index.html -->
<div class="container" id="app">
    <h3 class="text-center">Vue新聞</h3>
    <news-list :results="results"></news-list>
</div>

注意:組件也能夠建立爲單個文件(.vue文件),而後由構建工具(如webpack)解析。雖然這超出了本教程的範圍,但建議用於更大或更復雜的應用程序。

實現類別過濾

爲了使咱們的應用程序更加豐富,咱們如今能夠引入類別過濾器,以容許用戶僅顯示某些類別的新聞。

首先,咱們註冊如今應用程序裏展現的以及即將會展現的類別列表:

const SECTIONS = "home, arts, automobiles, books, business, fashion, food, health, insider, magazine, movies, national, nyregion, obituaries, opinion, politics, realestate, science, sports, sundayreview, technology, theater, tmagazine, travel, upshot, world";

const vm = new Vue({
    el: '#app',
    data: {
        results: [],
        //設置展現的類別數組
        sections: SECTIONS.split(', '),
        //設置默認的展現類別
        section: 'home',
    },
    mounted () {
        this.getPosts(this.section);
    },
    //...
});

接下來,咱們在div#app容器中添加:

<!-- ./index.html -->
<section class="callout secondary">
    <h5 class="text-center">分類</h5>
    <form>
        <div class="row">
            <div class="large-6 columns">
                <select v-model="section">
                    <option v-for="section in sections" :value="section">
                        {{ section }}
                    </option>
                </select>
            </div>
            <div class="medium-6 columns">
                <a @click="getPosts(section)" class="button expanded">我要看新聞</a>
            </div>
        </div>
    </form>
</section>

當單擊「我要看新聞」按鈕時,觸發所選分類的getPosts方法。

最終demo

我決定添加一些小的(可選的)交互,使應用程序體驗更好一些,如引入加載圖像。

能夠看看以下效果:
https://codepen.io/mengmengpr...

也能夠在此處查看實時版本。

結尾

在本教程中,咱們已經學會了如何從頭開始建立一個Vue.js項目,如何使用axios從API獲取數據,以及如何使用組件和計算屬性去處理數據。

如今咱們有一個功能齊全的基於API服務構建的Vue.js 2.0應用程序。經過引入其餘API能夠進行大量的改進。例如,咱們能夠:

  • 使用Buffer API從分類中自動排列社交媒體。

  • 使用Pocket API標記文章稍後閱讀。

  • 等等

該項目的整個代碼也託管在Github上,所以你能夠克隆,運行並進行改進。

這篇文章對於vue初學者是一個不錯的教程,它講述瞭如何快速的搭建起一個vue應用程序,其餘詳細的vue特性,能夠去官網學習以後基於本項目進行改進。

相關文章
相關標籤/搜索