這篇文章講述瞭如何快速構建一個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.js
和app.js
:ajax
<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
)。
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特性,能夠去官網學習以後基於本項目進行改進。