使用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,您需要獲得一個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 ,所以如果你愿意的話, 你可以克隆,運行和改進。
              關聯標簽:
              秋霞久久老子无码午夜精品,欧洲av成本人在线观看免费,亚洲精品无码国模av