使用Vue.js和Axios從第三方API獲取數據 — SitePoint
小編:管理員 64閱讀 2022.08.19
- 快速提示:如何在JavaScript中排序對象數組 使用Vue.js,可以逐步地構建圍繞其中一個服務的應用程序,并在幾分鐘內就可以開始向用戶提供內容服務。
我將演示如何構建一個簡單的新聞應用程序,它可以顯示當天的熱門新聞文章,并允許用戶按照他們的興趣類別進行過濾,從紐約時報API獲取數據。您可以在這里找到本教程的完整代碼。
下面是最終應用的外觀:

要學習本教程,您將需要一些非?;镜腣ue.js的知識。 您可以在這里找到一個很棒的“入門指南”。 我還將使用ES6語法,您可以到這里進一步學習: https://www.sitepoint.com/tag/es6/。
項目結構為了保持簡單,我們只使用2個文件:
./app.js ./index.html復制
app.js將包含我們應用程序的所有邏輯,index.html 文件將包含我們應用程序的主視圖。
我們先在 index.html 中寫一些基本的標記:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>The greatest news app ever</title> </head> <body> <div class="container" id="app"> <h3 class="text-center">VueNews</h3> </div> </body> </html>復制
然后,在index.html的底部導入 Vue.js和app.js,就在標簽之前:
<script src="https://unpkg.com/vue"></script> <script src="app.js"></script>復制
可選的,我們還可以導入Foundation,以利用一些預先創建的樣式,來使我們的視圖看起來更好一點。
<link rel="stylesheet" >復制創建一個簡單的 Vue App
首先,我們將在div#app 元素上創建一個新的 Vue 實例,并使用一些測試數據來模擬新聞API的響應:
// ./app.js const vm = new Vue({ el: '#app', data: { results: [ {title: "the very first post", abstract: "lorem ipsum some test dimpsum"}, {title: "and then there was the second", abstract: "lorem ipsum some test dimsum"}, {title: "third time's a charm", abstract: "lorem ipsum some test dimsum"}, {title: "four the last time", abstract: "lorem ipsum some test dimsum"} ] } });復制
我們通過el選項告訴 Vue 要掛載的目標元素,并通過data選項指定我們的應用程序用到的數據。
要在我們的應用程序視圖中顯示這些模擬數據,我們可以在#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 指令用于渲染我們的 results 列表。 我們使用雙花括號來顯示每一項的內容。 您可以在 Vue 模板語法 這里閱讀更多內容 我們現在已經完成了基本的布局工作:

要使用 紐約時報API,您需要獲得一個API密鑰。所以如果你還沒有,請到這里:https://developer.nytimes.com/signup ,注冊并獲取一個熱點事件API的API密鑰。
創建Ajax請求和處理響應Axios是一個基于 Promise 的HTTP客戶端,用于創建 Ajax請求,并且非常適合我們的應用。它提供了一些簡單而豐富的API。 它與fetch API非常相似,但不需要為舊版瀏覽器額外的添加一個polyfill,另外還有一些很巧妙的地方。 導入axios:
<!-- ./index.html --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script>復制
現在,一旦我們的Vue應用被掛載 - mounted到頁面,我們就可以創建home部分獲取熱點事件列表的請求:
// ./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.results}) } });復制
記住: 將your_api_key替換為之前獲取的實際API密鑰。
現在我們可以在我們的應用主頁上看到新聞列表。不要擔心扭曲的視圖,我們之后再說:

來自紐約時報 API 的響應通過 Vue Devtools 查看起來像下面這樣:

提示: 獲取 Vue Devtools,來使Vue應用調試更加簡單。 為了使我們的工作更加整潔,可重用,我們將做一些小小的重構,并創建一個輔助函數來構建我們的URL。我們還將注冊getPosts作為我們應用程序的一個方法,將其添加到methods對象中:
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); }); } } });復制
通過引入 計算屬性 對API獲取的原始results來進行一些修改,然后對我們的視圖進行一些更改。
// ./app.js 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; // Add image_url attribute 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"; }); // Put Array into Chunks 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數組分組成4塊。這將改善我們前面看到的扭曲的視圖。
注意:您也可以輕松地使用Lodash等庫進行分塊
計算屬性非常適合操縱數據。而不用創建一個方法,并且每次在我們需要將我們的帖子數組分塊時,我們可以簡單地將它定義為一個計算屬性,并根據需要使用它,因為Vue會隨時自動更新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>復制
現在應用程序看起來更好了:

組件 可用于使應用程序的更加模塊化,并且擴展了HTML。 新聞列表可以重構為一個組件,例如,如果應用程序增長,并且可能會在其他地方的使用新聞列表,那將很容易實現。
// ./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() { 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"; }); // Put Array into Chunks 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; } } }); 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); }); } } });復制
在上面的代碼中,我們使用以下的語法注冊了全局組件:Vue.component(tagName, options)。建議在定義標簽名稱時使用連字符,因此它們不會與任何當前或將來的標準HTML標簽發生沖突。
下面介紹一些其他選項如下:
- Props: 它包含可能從父作用域傳遞到當前組件組件數據的數組。我們添加了results,因為我們想要從主程序實例加載它。
- Template: 這里是我們定義的新聞列表的html結構。請注意,我們將html包裝在反引號中。這是因為組件需要有一個單獨的根元素,而不是多個元素(這將由我們的div.row迭代創建)。 調整我們的標記以使用我們的news-list組件,并傳遞’results’數據,如下所示:
<!-- ./index.html --> <div class="container" id="app"> <h3 class="text-center">VueNews</h3> <news-list :results="results"></news-list> </div>復制
注意: 組件也可以創建為單文件組件(.vue文件),然后由構建工具解析,如webpack。 雖然這超出了本教程的范圍,但建議在更大或更復雜的應用程序中使用。 更進一步,您可以決定甚至將每篇文章做成一個單獨的組件,使我們的應用更加模塊化。
實現分類過濾器為了使我們的應用程序更加豐富,我們現在可以引入分類過濾器,以便用戶選擇顯示某些特定類別的新聞。
首先,我們將在我們的應用程序中注冊 sections 列表和當前正在查看的部分:
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"; // From NYTimes const vm = new Vue({ el: '#app', data: { results: [], sections: SECTIONS.split(', '), // 從SECTIONS創建一個數組 section: 'home', // 設置默認的 section為 home }, mounted () { this.getPosts(this.section); }, // .... });復制
接下來,我們可以將它添加到我們的div#app容器中:
<!-- ./index.html --> <section class="callout secondary"> <h5 class="text-center">Filter by Category</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">Retrieve</a> </div> </div> </form> </section>復制
當單擊“Retrieve”按鈕時,我們通過偵聽“click”事件來觸發所選部分的getPosts方法,語法如下:@click。
最終改進和演示我決定添加一些小的(可選的)效果,使應用程序體驗更好一些,如引入加載圖片。
您可以在下面的CodePen中看到一個演示(有限的功能):
查看 codepen VueJS and NYTimes News App by SitePoint (@SitePoint) on CodePen.
也可以查看在線的版本 here.
結論在本教程中,我們已經學會了如何從頭開始創建Vue.js項目,如何使用axios從API獲取數據,以及如何處理響應、操作組件和計算屬性的數據。
現在我們已經有一個功能齊全的Vue.js 2.0的應用程序,它圍繞著 API 服務構建。 通過插入其他API可以進行大量的改進。例如,我們可以:
- 使用Buffer API自動從類別中排列社交媒體帖子
- 使用Pocket API,來標記閱讀后的帖子 這個項目的完整代碼在Github上托管的https://github.com/sitepoint-editors/vuejs-news ,所以如果你愿意的話, 你可以克隆,運行和改進。
相關推薦
- Vue3(二)工程化開發方式做項目 工程化的開發方式這是開發中、大型項目的必備技能,網上資料也很多,這里只是一個簡單的綜合性的介紹。包括vue的全家桶、建立項目的幾種方式、UI庫的簡單使用等??梢院蜕弦黄腸nd方式做項目做一下對比。node.js,npm、cnpm、yarnnode.js執行 npm run serve ,…
- Hibernate Criterion 在查詢方法設計上能夠靈活的依據Criteria的特點來方便地進行查詢條件的組裝.Hibernate設計了CriteriaSpecification作為Criteria的父接口,以下提供了Criteria和DetachedCriteria.Criteria和DetachedCriteria的主要差別在于創建的形式不一樣,Criteria是在線的,所…