[code]./app.js[/code]
./index.html
app.js将包含我们应用程序的所有逻辑,
index.html文件将包含我们应用程序的主视图。
index.html中写一些基本的标记:
[code]<!DOCTYPE html>[/code]
<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,就在
</body>标签之前:
[code]<script src="https://unpkg.com/vue"></script>[/code]
<script src="app.js"></script>
[code]<link rel="stylesheet" href="https://cdnjs.cloudflare.com/a ... gt%3B[/code]创建一个简单的 Vue App
div#app元素上创建一个新的 Vue 实例,并使用一些测试数据来模拟新闻API的响应:
[code]// ./app.js[/code]
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"}
]
}
});
#app元素中写入下面的标记:
[code]<!-- ./index.html -->[/code]
<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 模板语法 这里阅读更多内容
fetchAPI非常相似,但不需要为旧版浏览器额外的添加一个polyfill,另外还有一些很巧妙的地方。
以前,
vue-resource通常用于Vue项目,但现在已经退休了。
[code]<!-- ./index.html -->[/code]
<script src="https://unpkg.com/axios/dist/a ... gt%3B
home部分获取热点事件列表的请求:
[code]// ./app.js[/code]
const vm = new Vue({
el: '#app',
data: {
results: []
},
mounted() {
axios.get("https://api.nytimes.com/svc/to ... 6quot;)
.then(response => {this.results = response.data.results})
}
});
记住: 将
your_api_key替换为之前获取的实际API密钥。
提示: 获取 Vue Devtools,来使Vue应用调试更加简单。
getPosts作为我们应用程序的一个方法,将其添加到methods对象中:
[code]const NYTBaseUrl = "https://api.nytimes.com/svc/topstories/v2/";[/code]
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); });
}
}
});
[code]// ./app.js[/code]
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等库进行分块
processedPosts计算属性的变化。
results不变,
processedPosts属性返回一个自己的缓存版本。这将有助于提升性能,特别是在进行复杂的数据操作时。
index.html中编辑我们的html来显示我们的计算结果:
[code]<!-- ./index.html -->[/code]
<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>
新闻列表可以重构为一个组件,例如,如果应用程序增长,并且可能会在其他地方的使用新闻列表,那将很容易实现。
[code]// ./app.js[/code]
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标签发生冲突。
results,因为我们想要从主程序实例加载它。
div.row迭代创建)。
news-list组件,并传递'results'数据,如下所示:
[code]<!-- ./index.html -->[/code]
<div class="container" id="app">
<h3 class="text-center">VueNews</h3>
<news-list :results="results"></news-list>
</div>
注意: 组件也可以创建为单文件组件(
.vue文件),然后由构建工具解析,如webpack。 虽然这超出了本教程的范围,但建议在更大或更复杂的应用程序中使用。
[code]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[/code]
const vm = new Vue({
el: '#app',
data: {
results: [],
sections: SECTIONS.split(', '), // 从SECTIONS创建一个数组
section: 'home', // 设置默认的 section为 home
},
mounted () {
this.getPosts(this.section);
},
// ....
});
div#app容器中:
[code]<!-- ./index.html -->[/code]
<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>
getPosts方法,语法如下:
@click。最终改进和演示
本文为 @ 21CTO 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。