<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div class="container" id="app">
<h3 class="text-center">Vue新闻</h3>
<div class="columns medium-3" v-for="result in results">
<div class="card">
<div class="card-divider">
{{ result.title }}
</div>
</div>
<div class="card-section">
<p>{{ result.abstract }}</p>
</div>
</div>
</div>
<script src="app.js"></script>
const vm = new Vue({
el: '#app',
data: {
results: []
},
mounted() {
axios.get("https://api.nytimes.com/svc/topstories/v2/science.json?api-key=jOVhhQ5IFj9gqNq6TabKzud3IewKTFUh")
.then(response => {
this.results = response.data.results
})
}
});
使项目更加简洁,可复用。设置一个getPosts作为应用程序的一个方法
const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";
const Apikey = "jOVhhQ5IFj9gqNq6TabKzud3IewKTFUh";
function buildUrl(url) {
return NYTBaseUrl + url + ".json?api-key=" + Apikey;
}
const vm = new Vue({
el: '#app',
data: {
results: []
},
mounted() {
this.getPosts('science');
},
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;
}
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>最大的新闻app</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css">
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div class="container" id="app">
<h3 class="text-center">Vue新闻</h3>
<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>
</div>
<script src="app.js"></script>
</body>
</html>
通过引入计算属性对API获得的原始结果进行一些修改,从而对视图的外观进行一些更改
const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";
const Apikey = "jOVhhQ5IFj9gqNq6TabKzud3IewKTFUh";
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";
function buildUrl(url) {
return NYTBaseUrl + url + ".json?api-key=" + Apikey;
}
Vue.component('new-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";
});
//将数据分组
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: [],
loading: true,
sections: SECTIONS.split(','), //create an array of the sections
section: 'home', //set default section
title: ''
},
mounted() {
this.getPosts('home');
},
methods: {
getPosts(section) {
let url = buildUrl(section);
axios.get(url).then(response => {
this.loading = false;
this.results = response.data.results;
let title = this.section !== 'home' ? "Top stories in '" + this.section + "' Today" : "Top stories today";
this.title = title + "(" + response.data.num_results + ")";
}).catch(error => {
console.log(error);
});
}
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>最大的新闻app</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css">
<link rel="stylesheet" href="app.css">
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div class="container" id="app">
<h3 class="text-center">Vue新闻</h3>
<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="large-6 columns">
<a @click="getPosts(section)" class="button expanded">我要看新闻</a>
</div>
</div>
</form>
</section>
<h5 v-if="!loading" class="text-center uppercase">{{title}}</h5>
<div v-if="loading" class="loader">
<img src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.16.1/images/loader-large.gif" alt="loader">
</div>
<new-list v-if="!loading" :results = "results"></new-list>
</div>
<script src="app.js"></script>
</body>
</html>
.container {
padding: 20px 0
}
.column:last-child:not(:first-child),
.columns:last-child:not(:first-child) {
float: left;
}
.main_heading {
margin: 10px 0 30px;
}
.callout {
margin-bottom: 40px;
}
select {
text-transform: capitalize;
}
.loader {
text-align: center;
padding: 40px;
}
.uppercase {
text-transform: uppercase;
}
- 403(Forbidden):服务器已经理解请求,但是拒绝执行它。
- 401(unauthorized)未经许可的。当前请求需要用户验证