快速构建一个使用axios的vue应用程序(转)
英文原文:https://www.sitepoint.com/fetching-data-third-party-api-vue-axios/
译文:https://segmentfault.com/a/1190000009192118
通常情况下,在构建JavaScript应用程序时,会从远程获取数据或使用API。我最近研究了一些公用API,发现有很多很酷的东西可以用在这些获取到的数据上。
我将演示如何构建一个简单的新闻app,它将显示当天的热门新闻,还允许用户通过感兴趣的类别进行过滤。我们将从纽约时报API获取数据。可以在这里找到本教程的完整代码。
下面是最终app的效果:
要使用本教程,你将需要了解基本的Vue.js知识。这是一个vue教程直达。教程将使用ES6语法。
项目结构
我们将只用2个文件来保持项目简洁:
./app.js
./index.html
app.js
包含整个app的逻辑,index.html
包含整个app的界面。
我们从index.html
开始:
<!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
:
<script src="https://unpkg.com/vue"></script>
<script src="app.js"></script>
可选地,可以引入Foundation,以利用一些预制样式,使我们的界面看起来更好一点。 将其包含在<head>标签中:
<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上,因此你可以克隆,运行并进行改进。
快速构建一个使用axios的vue应用程序(转)的更多相关文章
- 快速构建一个简单的单页vue应用
技术栈 vue-cli webpack vux,vux-loader less,less-loader vue-jsonp vue-scroller ES6 vue-cli:一个vue脚手架工具,利用 ...
- 快速构建一个vue项目
首先介绍一下命令行构建一个vue项目步骤: 1.下载安装node.js(直接运行安装包根据步骤安装完),打开命令行输入:node -v ,出现版本号即安装成功. 2.命令行界面输入:cnpm inst ...
- 【jQuery插件】用jQuery Masonry快速构建一个pinterest网站布局(转)
[jQuery插件]用jQuery Masonry快速构建一个pinterest网站布局 时间:2011年03月21日作者:愚人码头查看次数:29,744 views评论次数:25条评论 前段时间领导 ...
- springboot:快速构建一个springboot项目
前言: springboot作为springcloud的基础,springboot的热度一直很高,所以就有了这个springboot系列,花些时间来了解和学习为自己做技术储备,以备不时之需[手动滑稽] ...
- 快速构建一个 Springboot
快速构建一个 Springboot 官网:http://projects.spring.io/spring-boot/ Spring Boot可以轻松创建可以“运行”的独立的,生产级的基于Spring ...
- 从实体框架核心开始:构建一个ASP。NET Core应用程序与Web API和代码优先开发
下载StudentApplication.Web.zip - 599.5 KB 下载StudentApplication.API.zip - 11.5 KB 介绍 在上一篇文章中,我们了解了实体框架的 ...
- Kubernetes实战 - 从零开始搭建微服务 1 - 使用kind构建一个单层架构Node/Express网络应用程序
使用kind构建一个单层架构Node/Express网络应用程序 Kubernetes实战-从零开始搭建微服务 1 前言 准备写一个Kubernetes实战系列教程,毕竟cnblogs作为国内最早的技 ...
- 看了这一张GIF图你就明白什么回事了,必看的经典!--快速构建一个请假流程
下面介绍一下FSBPM构建一个请假单流程 1.数据模型的构建 输入业务中需要的数据项即可,比如[申请人,开始时间,结束时间,请假天数,请假理由,附件上传..........] 2.自定义流程 审批节点 ...
- [开源]快速构建一个WebApi项目
项目代码:MasterChief.DotNet.ProjectTemplate.WebApi 示例代码:https://github.com/YanZhiwei/MasterChief.Project ...
随机推荐
- django项目settings.py的基础配置
一个新的django项目初始需要配置settings.py文件: 1. 项目路径配置 新建一个apps文件夹,把所有的项目都放在apps文件夹下,比如apps下有一个message项目,如果不进行此项 ...
- Super expression must either be null or a function, not undefined
按照之前买的用JavaScript开发移动应用的例子来编写的,然后报了这个错.我的头部声明是这样的 var React = require('react-native'); var { Text, V ...
- docker进程分析
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/TM6zNf87MDG7Bo/article/details/80970541 序言 闷热. ...
- tensorflow简单记录summary方法
虽然tf官方希望用户把 train , val 程序分开写,但实际开发中,明显写在一起比较简单舒服,但在保存数据到 summary 时, val 部分和 train 部分不太一样,会有一些问题,下面讨 ...
- [原]win10下编译lua5.3.4
1.下载lua源码http://www.lua.org/ftp/ 2.打开vs2012工具命令提示 3.cd 到lua源码的src目录 4.依次执行以下代码 cl /MD /O2 /c /DLUA_B ...
- 【Dubbo 源码解析】06_Dubbo 服务调用
Dubbo 服务调用 根据上图,可以看出,服务调用过程为: Consumer 端的 Proxy 调用 Cluster 层选择集群中的某一个 Invoker(负载均衡) Invoker 最终会调用 Pr ...
- Centos7 启动脚本
Centos7 启动脚本 启动脚本.如果进程已存在,输出错误信息后退出: #! /bin/bash PIDS=`ps -ef | grep '/usr/bin/node ./index.js' | g ...
- Windows上使用telnet测试端口号
之前测试服务器某一端口开启开启情况一般在服务器上使用 netstat –ano|findstr "端口号"命令查看. 但是有时候端口在服务器上开通了,但是客户端并不一定可以访问到 ...
- Golang etcd服务注册与发现
//sevice.go package discovery import ( "context" "errors" "sync" " ...
- 【CF471E】MUH and Lots and Lots of Segments 扫描线+并查集+线段树+set
[CF471E]MUH and Lots and Lots of Segments 题意:给你平面上n条水平或竖直的,端点在整点处的线段.你需要去掉一些线段的一些部分,使得剩下的图形:1.连通,2.无 ...