更多的往往不是,建立你的JavaScript应用程序时,你会想把数据从远程源或消耗一个[ API ](https:/ /恩。维基百科。org /维基/ application_programming_interface)。我最近看了一些[公开](https://github.com/toddmotto/public-apis API),发现有很多很酷的东西,可以从这些来源的数据。

通常情况下,在构建 JavaScript 应用程序时,您希望从远程源或从API获取数据。我最近研究了一些公开的API,发现可以使用这些数据源完成很多很酷的东西。

更多来自作者的提示

使用Vue.js,可以逐步地构建围绕其中一个服务的应用程序,并在几分钟内就可以开始向用户提供内容服务。

我将演示如何构建一个简单的新闻应用程序,它可以显示当天的热门新闻文章,并允许用户按照他们的兴趣类别进行过滤,从纽约时报API获取数据。您可以在这里找到本教程的完整代码。

下面是最终应用的外观:

要学习本教程,您将需要一些非常基本的Vue.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.jsapp.js,就在</body>标签之前:

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

可选的,我们还可以导入Foundation,以利用一些预先创建的样式,来使我们的视图看起来更好一点。

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

创建一个简单的 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。 它与fetchAPI非常相似,但不需要为旧版浏览器额外的添加一个polyfill,另外还有一些很巧妙的地方

以前,vue-resource 通常用于Vue项目,但现在已经退休了

导入 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) ,所以如果你愿意的话, 你可以克隆,运行和改进。

你有没有其他有趣的想法可以通过连接到第三方API来实现?可以在评论中分享您的想法!

使用Vue.js和Axios从第三方API获取数据 — SitePoint的更多相关文章

  1. vue.js 配置axios 用来ajax请求数据

    * 用npm 安装 axios 切换到项目的根目录 npm install --save axios vue-axios * 在vue的入口文件./src/main.js 中引入axios, 添加2行 ...

  2. 使用api获取数据————小程序

    使用api获取数据----小程序 onLoad: function (options) { //打开页面即执行. let that = this; wx.request({ //建立链接 url: ' ...

  3. 百度地图API获取数据

    目前,大厂的服务范围越来越广,提供的数据信息也是比较全的,在生活服务,办公领域,人工智能等方面都全面覆盖,相对来说,他们的用户基数大,通过用户获取的信息也是巨大的.除了百度提供api,国内提供免费AP ...

  4. C# WPF从RIOT API获取数据(RIOT代表作品《英雄联盟》)

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF从RIOT API获取数据(RIOT代表作品<英雄联盟>) 阅读导航 ...

  5. vue.js使用axios

    使用axios的两种调用方式 1.安装axios $ cnpm install axios 2.在vue入口文件main.js中引入(推荐全局引入),或是在当前页面中引入(局部) import axi ...

  6. Vue.js Ajax(axios)

    Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求. Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中. Github开源地址: ht ...

  7. Vue.js 组件的三个 API:prop、event、slot

    组件的构成 一个再复杂的组件,都是由三部分组成的:prop.event.slot,它们构成了 Vue.js 组件的 API.如果你开发的是一个通用组件,那一定要事先设计好这三部分,因为组件一旦发布,后 ...

  8. C#/.NET使用HttpWebRequest、SqlBulkCopy从API获取数据批量插入DB

    小弟新手程序员一枚,代码技术和文章水平均不才.所写文章均为对自己所写所学代码的简单记录,可能对于老手程序员营养价值不高,望莫见怪. 我工作上有个需求:从某处API接口上获取数据(大约1W条而已)并插入 ...

  9. 【原创】Vue.js 中 axios 跨域访问错误

    1.假如访问的接口地址为 http://www.test.com/apis/index.php  (php api 接口) 2.而开发地址为http://127.0.0.1:8080,当axios发起 ...

随机推荐

  1. Producer Flow Control 和 vmQueueCursor

    ActiveMQ可以开启或关闭生产者流量控制Producer Flow Control ,基本原理是producer 发送一条消息会收到broker返回的ack响应,当磁盘或内存快满的时候broker ...

  2. Linux内核的三种调度策略

    一 Linux内核的三种调度策略:   1,SCHED_OTHER 分时调度策略, 2,SCHED_FIFO实时调度策略,先到先服务.一旦占用cpu则一直运行.一直运行直到有更高优先级任务到达或自己放 ...

  3. jmeter-----GUI运行和非GUI运行的区别

    gui:界面会消耗很多资源,并且运行的结果是保存在Jmeter运行的内存中.当时间一长,内存增长到一定程度,就会报错,甚至假死. 非gui:实时的将运行log文件保存到本地文件中,不会撑爆内存.并且对 ...

  4. hdu4307

    好题,详细题解在这里http://blog.csdn.net/weiguang_123/article/details/8077385 这里回顾一下: 当i和j都在一个集合里会产生新的收益,是经典题直 ...

  5. 【PAT】1004. 成绩排名 (20)

    1004. 成绩排名 (20) 读入n名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式:每个测试输入包含1个测试用例,格式为 第1行:正整数n 第2行:第1个学生的姓名 ...

  6. ServiceWorker pwa缓存

    index.js if ( navigator.serviceWorker ) { console.log("cache index") window.addEventListen ...

  7. LoadRunner截取字符串操作

    LoadRunner截取字符串操作 在使用LoadRunner winsockets协议写脚本,遇到下面问题: 在接收到的查询数据库的结果中我要取红色部份用于下面的select recv buf60 ...

  8. loadrunner中自定义查找并替换函数

    globas.h中定义 //LoadRunner中没有直接的函数支持查找并替换字符串,因此可以封装一个lr_replace函数出来: // ------------------------------ ...

  9. vscode 解决vue emmet不起作用

    现在 vscode 自带的提示已经很好用了,大部分时间自带的提示展示的 emmet 内容已经是所需的了 在首选项 设置中配置 v1.15.1 之后需要这样设置: "emmet.trigger ...

  10. Python函数-闭包的概念

    一个函数和它的环境变量合在一起,就构成了一个闭包(closure).在Python中,所谓的闭包是一个包含有环境变量取值的函数对象.环境变量取值被保存在函数对象的__closure__属性中.比如下面 ...