Building Your First App With Vue.js
Build an app for browsing Reddit posts.
A tutorial by Tutorialzine
The App
The applications' purpose is simply to fetch the feed from a number of subbreddits and display them. Here is what the end result will look like:
The code will contain
- Custom Components
- Custom Filters
The Full Code
Here is the full code of the app for you to take a look and get an idea on how things work.
Javascript
/*-----------------
Components
-----------------*/
// Parent | Subreddit component containing a list of 'post' components.
var subreddit = Vue.component('subreddit',{
template: '#subreddit',
props: ['name'],
data: function () {
return { posts: [] }
},
created: function(){
this.$http.get("https://www.reddit.com/r/"+ this.name +"/top.json?limit=3")
.then(function(resp){
this.posts=resp.data.data.children;
});
}
});
// Child | Componenet represiting a single post.
var post = Vue.component('post', {
template: "#post",
props: ['item']
});
/*-----------------
Custom filters
-----------------*/
// Filter for cutting off strings that are too long.
Vue.filter('truncate', function(value) {
var length = 60;
if(value.length <= length) {
return value;
}
else {
return value.substring(0, length) + '...';
}
});
// Filter that takes an image url and creates a CSS style.
Vue.filter('setAsBackground', function(value) {
if(value && value!='self' && value!='nsfw') {
return 'background-image: url(' + value + ')';
}
else {
return 'background-image: url(assets/img/placeholder.png)';
}
});
/*-----------------
Initialize app
-----------------*/
new Vue({
el: 'body'
});
HTML
<!DOCTYPE html>
<html>
<head>
<title>Your First App With Vue.js</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="assets/css/styles.css">
</head>
<body>
<div class="container">
<subreddit name="aww"></subreddit>
<subreddit name="space"></subreddit>
<subreddit name="gifs"></subreddit>
<subreddit name="food"></subreddit>
<subreddit name="comics"></subreddit>
<subreddit name="sports"></subreddit>
</div>
<template id="subreddit">
<div class="subreddit">
<h2>{{ name | uppercase }}</h2>
<ul class="item-list">
<li v-for="obj in posts">
<post :item="obj"></post>
</li>
</ul>
</div>
</template>
<template id="post">
<div class="post">
<a :href="item.data.url" :style="item.data.thumbnail | setAsBackground"
target="_blank" class="thumbnail"></a>
<div class="details">
<a :href="item.data.url" :title="item.data.title" target="_blank" class="title">
{{ item.data.title | truncate}}
</a>
<div class="action-buttons">
<a href="http://reddit.com{{ item.data.permalink }}" title="Vote">
<i class="material-icons">thumbs_up_down</i>
{{item.data.score}}
</a>
<a href="http://reddit.com{{ item.data.permalink }}" title="Go to discussion">
<i class="material-icons">forum</i>
{{item.data.num_comments}}
</a>
</div>
</div>
</div>
</template>
<script src="assets/js/vue.js"></script>
<script src="assets/js/vue-resource.min.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
CSS
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
a{
text-decoration: none;
}
a:hover{
text-decoration: underline;
}
html{
font: normal 16px sans-serif;
color: #333;
background-color: #f9f9f9;
}
.container{
padding: 27px 20px;
margin: 30px auto 50px;
max-width: 1250px;
display: flex;
flex-wrap: wrap;
flex-direction: row;
background-color: #fff;
box-shadow: 0 0 1px #ccc;
}
/* Subreddit component */
.subreddit{
flex: 0 0 33%;
min-width: 400px;
padding: 20px 42px;
}
.subreddit h2{
font-size: 18px;
margin-bottom: 10px;
}
.subreddit .item-list{
border-top: 1px solid #bec9d0;
padding-top: 20px;
list-style: none;
}
.subreddit .item-list li{
margin-bottom: 17px;
}
/* Post component */
.post{
display: flex;
}
.post .thumbnail{
display: block;
flex: 0 0 60px;
height: 60px;
background-repeat: no-repeat;
background-size: cover;
background-position: center;
margin-right: 10px;
border-radius: 4px;
margin-right: 12px;
}
.post .details{
display: flex;
flex-direction: column;
}
.post .details .title{
font-size: 15px;
margin-bottom: 3px;
color: #04477b;
}
.post .details .title:visited{
color: purple;
}
.post .details .action-buttons a{
font-size: 11px;
margin-right: 4px;
display: inline-block;
color: #666;
}
.post .details .action-buttons i{
font-size: 10px;
margin-right: 1px;
}
@media(max-width: 1250px){
.container{
justify-content: center;
margin: 30px 30px 50px 30px;
}
}
@media(max-width: 500px){
.subreddit{
min-width: 300px;
padding: 20px 15px;
}
}
See a more detailed tutorial on tutorialzine