感谢那些无私开源的程序员,你们是最可爱的人儿~~~~
//根app app.js
<template>
<div id="app">
<v-header></v-header>
<div class="main">
<router-view></router-view>
</div>
<v-footer></v-footer>
</div>
</template>
<script>
import vHeader from './components/header'
import vFooter from './components/footer'
export default {
name: 'app',
components: {
vHeader,
vFooter
}
}
</script>
<style>
#app {
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
background: #E2E2E2;
color: #778087;
}
img {
height: auto;
vertical-align: top;
}
.main {
width: 1100px;
margin: 0 auto;
}
</style>
公共header
//src/components/header.vue
<template>
<div class="header">
<div class="header-wrapper">
<h1 class="title">
<router-link to="/tag/all">
<img src="./../assets/logo.png">
<span>cNodeJS</span>
</router-link>
</h1>
<p class="about">关于</p>
</div>
</div>
</template>
<script>
export default {
};
</script>
<style scoped>
.header {
background: #fff;
margin-bottom: 35px;
}
.header .header-wrapper {
width: 1100px;
margin: 0 auto;
overflow: hidden;
}
.header .header-wrapper .title {
float: left;
padding: 10px 0;
}
.header .header-wrapper .title img {
width: 30px;
height: 30px;
vertical-align: middle;
margin-right: 10px;
}
.header .header-wrapper .title span {
font-size: 18px;
font-weight: bold;
color: #778087;
}
.header .header-wrapper .about {
float: right;
margin-top: 15px;
}
</style>
//src/components/footer.vue
<template>
<div class="footer">
<p>由 Vue 强力驱动 | Write - By XMit</p>
</div>
</template>
<script>
export default {
name: 'footer',
}
</script>
<style scoped>
.footer {
background: #fff;
margin-top: 35px;
padding: 50px 0 30px;
text-align: center;
}
</style>
路由部分
//src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import main from '@/components/main';
import detail from '@/components/detail';
import user from '@/components/user';
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: main,
children: [
{
path: '/tag/:id',
}
]
},
{
path: '/topic/:id',
name: 'detail',
component: detail
},
{
path: '/user/:id',
name: 'user',
component: user
},
]
})
//src/components/user.vue
<template>
<div class="user" v-if="user.length !== 0">
<div class="user-info">
<div class="user-info-hd">个人用户信息</div>
<div class="user-info-bd">
<ul>
<li>
<img :src="user.avatar_url" alt="img">
<p class="username">{{user.loginname}}</p>
</li>
<li>{{user.score}} 积分</li>
<li>github <a :href="'http://github.com/' + user.githubUsername">{{'http://github.com/' + user.githubUsername}}</a></li>
<li>注册时间 {{getTime(user.create_at)}}</li>
</ul>
</div>
</div>
<div class="new-topic" v-if="user.recent_topics.length !== 0">
<div class="new-topic-hd">最近创建的话题</div>
<div class="new-topic-bd">
<ul>
<li v-for="item in user.recent_topics">
<img :src="user.avatar_url" alt="img">
<router-link :to="{ name: 'detail', params: {id: item.id} }" class="title">{{item.title}}</router-link>
</li>
</ul>
</div>
</div>
<div class="participate" v-if="user.recent_replies.length !== 0">
<div class="participate-hd">最近参与的话题</div>
<div class="participate-bd">
<ul>
<li v-for="item in user.recent_replies">
<img :src="user.avatar_url" alt="img">
<router-link :to="{ name: 'detail', params: {id: item.id} }" class="title">{{item.title}}</router-link>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['userdata'],
data: function() {
return {
user: []
};
},
methods: {
getData: function() {
this.$http
.get("https://cnodejs.org/api/v1/user/" + (this.userdata || this.$route.params.id), {
params: {}
})
.then(it => {
this.user = it.data.data;
console.log(this.user);
})
.catch(it => {
console.log("user.vue:", it);
});
},
getDateTimeStamp: function (dateStr){
return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
},
getTime: function(hisTime, nowTime) {
var now = nowTime ? nowTime : new Date().getTime(),
diffValue = now - this.getDateTimeStamp(hisTime),
result = "",
minute = 1000 * 60,
hour = minute * 60,
day = hour * 24,
halfamonth = day * 15,
month = day * 30,
year = month * 12,
_year = diffValue / year,
_month = diffValue / month,
_week = diffValue / (7 * day),
_day = diffValue / day,
_hour = diffValue / hour,
_min = diffValue / minute;
if (_year >= 1) result = parseInt(_year) + "年前";
else if (_month >= 1) result = parseInt(_month) + "个月前";
else if (_week >= 1) result = parseInt(_week) + "周前";
else if (_day >= 1) result = parseInt(_day) + "天前";
else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
else if (_min >= 1) result = parseInt(_min) + "分钟前";
else result = "刚刚";
return result;
}
},
created() {
this.getData();
}
};
</script>
<style scoped>
.user {
border-radius: 4px;
}
.user a {
color: #778087;
}
.user-info,
.new-topic,
.participate {
margin-bottom: 20px;
background: #fff;
border-radius: 4px;
}
.user .user-info-hd,
.new-topic .new-topic-hd,
.participate .participate-hd {
padding: 10px 20px;
background: #F6F6F6;
border-radius: 4px;
}
.user .user-info-bd img {
width: 50px;
height: auto;
border-radius: 4px;
margin-bottom: 5px;
}
.new-topic .new-topic-bd img,
.participate .participate-bd img {
width: 30px;
height: auto;
border-radius: 4px;
margin-bottom: 5px;
margin-right: 10px;
vertical-align: middle;
}
.user .user-info-bd {
padding: 20px;
}
.user .user-info-bd li {
margin-bottom: 10px;
}
.new-topic .new-topic-bd li,
.participate .participate-bd li {
border-bottom: 1px solid #ddd;
padding: 5px 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.new-topic .new-topic-bd li:last-child,
.participate .participate-bd li:last-child {
border-bottom: 0
}
</style>
//src/components/main.vue
<template>
<div class="main">
<div class="main-wrapper">
<ul class="tab-list">
<li class="item" @click="tabs('all')">全部</li>
<li class="item" @click="tabs('good')">精华</li>
<li class="item" @click="tabs('share')">分享</li>
<li class="item" @click="tabs('ask')">问答</li>
<li class="item" @click="tabs('job')">招聘</li>
<li class="item" @click="tabs('dev')">客户端测试</li>
</ul>
<ul class="list">
<li v-for="(item,index) in content" :key="index" class="item">
<div class="item-hd">
<router-link :to="{ name: 'user', params: {id: item.author.loginname} }" class="user">
<img :src="item.author.avatar_url">
</router-link>
</div>
<div class="item-bd">
<router-link :to="{ name: 'detail', params: {id: item.id} }" class="title">{{item.title}}</router-link>
<p class="footer">
<span class="reply" v-show="item.reply_count !== 0">{{item.reply_count}}</span>
<span class="authour">{{item.author.loginname}} • </span>
<span class="time">创建于: {{getTime(item.create_at)}}</span>
</p>
<p :class="{top: item.top}" v-if="item.top">置顶</p>
</div>
</li>
</ul>
</div>
<p class="pagination">
<!-- <a class="button" @click="prev" >GO PREV</a>
<a class="button" @click="next" >GO NEXT</a> -->
<v-tab v-on:changePage="test"></v-tab>
</p>
</div>
</template>
<script>
import vTab from "./tab";
export default {
data: function() {
return {
content: [],
page: 1,
tab: 'all',
show: true
};
},
methods: {
test(page) {
// console.log('page:' + page)
this.page = page
},
tabs(data) {
this.tab = data
this.$router.push({ path: `/tag/${data}` })
},
prev() {
if(this.page > 1) {
return this.page--
}
},
next() {
return this.page++
},
getData: function(page,tab) {
this.$http
.get("https://cnodejs.org/api/v1/topics", {
params: {
page: page,
limit: 0,
tab: tab,
mdrender: true
}
})
.then(it => {
this.content = it.data.data
})
.catch(it => {
console.log("main.vue:", it);
});
},
getDateTimeStamp: function (dateStr){
return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
},
getTime: function(hisTime, nowTime) {
var now = nowTime ? nowTime : new Date().getTime(),
diffValue = now - this.getDateTimeStamp(hisTime),
result = "",
minute = 1000 * 60,
hour = minute * 60,
day = hour * 24,
halfamonth = day * 15,
month = day * 30,
year = month * 12,
_year = diffValue / year,
_month = diffValue / month,
_week = diffValue / (7 * day),
_day = diffValue / day,
_hour = diffValue / hour,
_min = diffValue / minute;
if (_year >= 1) result = parseInt(_year) + "年前";
else if (_month >= 1) result = parseInt(_month) + "个月前";
else if (_week >= 1) result = parseInt(_week) + "周前";
else if (_day >= 1) result = parseInt(_day) + "天前";
else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
else if (_min >= 1) result = parseInt(_min) + "分钟前";
else result = "刚刚";
return result;
}
},
created() {
this.getData(this.page)
},
watch: {
page(val) {
this.getData(val)
},
tab(newVal, oldVal) {
this.getData(this.page, newVal)
},
$route(to, from) {
// this.getData(to.params.id)
this.getData(this.page, to.params.id)
}
},
components: {
vTab
}
};
</script>
<style scoped>
.tab-list {
overflow: hidden;
padding: 10px 15px;
background: #f6f6f6;
border-radius: 4px 4px 0 0;
}
.tab-list .item {
float: left;
margin-right: 15px;
}
.button {
display: inline-block;
background: #212121;
color: #fff;
font-weight: bold;
text-align: center;
padding: 1em;
cursor: pointer;
text-decoration: none;
}
.pagination {
padding: 20px 0 0;
text-align: center;
}
.main .main-wrapper {
background: #fff;
border-radius: 4px;
}
.main .main-wrapper .list .item {
overflow: hidden;
padding: 10px;
border-bottom: 1px solid #ddd;
}
.main .main-wrapper .list .item:last-child {
border: 0;
}
.main .main-wrapper .list .item .item-hd {
float: left;
}
.main .main-wrapper .list .item .item-hd .user {
display: inline-block;
}
.main .main-wrapper .list .item .item-hd img {
width: 50px;
height: 50px;
display: inline-block;
border-radius: 4px;
}
.main .main-wrapper .list .item .item-bd {
margin-left: 70px;
}
.main .main-wrapper .list .item .item-bd .title {
font-size: 16px;
margin-bottom: 5px;
color: #778087;
}
.main .main-wrapper .list .item .item-bd .footer {
color: #8492a6;
}
.main .main-wrapper .list .item .item-bd .footer .reply {
display: inline-block;
position: absolute;
right: 10px;
top: 15px;
background: #aab0c5;
border-radius: 10px;
width: 30px;
text-align: center;
color: #fff;
font-size: 12px;
}
.main .main-wrapper .list .item .item-bd {
position: relative;
}
.main .main-wrapper .list .item .item-bd .top {
position: absolute;
right: -20px;
top: -20px;
background: #81bb24;
color: #fff;
padding: 3px 3px;
border-radius: 2px;
font-size: 12px;
text-indent: -9999px;
transform: rotate(-45deg);
}
</style>
//src/components/detail.vue
<template>
<div class="content" v-if="itemdetail">
<div class="detail-left">
<div class="detail">
<div class="detail-wrapper">
<div class="detail-hd">
<h2 class="title">{{itemdetail.title}}</h2>
<span class="time">发布于 {{getTime(itemdetail.create_at)}} •</span>
<span class="author">作者 {{itemdetail.author.loginname}} •</span>
<span class="visit">{{itemdetail.visit_count}} 次浏览</span>
</div>
<div class="detail-bd">
<div id="content" v-html="itemdetail.content"></div>
</div>
</div>
</div>
<v-reply :replydata="itemdetail.replies"></v-reply>
</div>
<div class="detail-right">
<v-user :userdata="itemdetail.author.loginname"></v-user>
</div>
</div>
</template>
<script>
import vReply from "./reply";
import vUser from "./user";
export default {
name: "detail",
data() {
return {
itemdetail: ""
};
},
methods: {
getData: function(id) {
this.$http
.get("https://cnodejs.org/api/v1/topic/" + id, {
params: {
accesstoken: true,
mdrender: true
}
})
.then(it => {
this.itemdetail = it.data.data;
// console.log(this.itemdetail);
})
.catch(it => {
// console.log('detail.vue:',it)
});
},
getDateTimeStamp: function (dateStr){
return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
},
getTime: function(hisTime, nowTime) {
var now = nowTime ? nowTime : new Date().getTime(),
diffValue = now - this.getDateTimeStamp(hisTime),
result = "",
minute = 1000 * 60,
hour = minute * 60,
day = hour * 24,
halfamonth = day * 15,
month = day * 30,
year = month * 12,
_year = diffValue / year,
_month = diffValue / month,
_week = diffValue / (7 * day),
_day = diffValue / day,
_hour = diffValue / hour,
_min = diffValue / minute;
if (_year >= 1) result = parseInt(_year) + "年前";
else if (_month >= 1) result = parseInt(_month) + "个月前";
else if (_week >= 1) result = parseInt(_week) + "周前";
else if (_day >= 1) result = parseInt(_day) + "天前";
else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
else if (_min >= 1) result = parseInt(_min) + "分钟前";
else result = "刚刚";
return result;
}
},
created() {
this.getData(this.$route.params.id);
},
watch: {
$route(to, from) {
this.getData(to.params.id)
// console.log(to, from)
}
},
components: {
vReply,
vUser
}
};
</script>
<style scoped>
.content {
overflow: hidden;
}
.detail-left {
float: left;
width: 70%;
}
.detail-right {
float: right;
width: 28%;
}
.detail .detail-wrapper {
background: #fff;
border-radius: 4px;
}
.detail .detail-wrapper .detail-hd,
.detail .detail-wrapper .detail-bd {
padding: 20px;
}
.detail .detail-wrapper .detail-hd {
border-bottom: 1px solid #ddd;
}
.detail .detail-wrapper .detail-hd .title {
font-size: 20px;
margin-bottom: 15px;
}
</style>
//src/components/reply.vue
<template>
<div class="reply" v-if="replydata && replydata.length !== 0">
<div class="reply-wrapper">
<p class="reply-head">{{replydata.length}} 回复</p>
<ul class="list">
<li class="item" v-for="(item, index) in replydata" :key="index">
<div class="item-hd">
<router-link :to="{ name: 'user', params: {id: item.author.loginname} }" class="user">
<img :src="item.author.avatar_url">
</router-link>
</div>
<div class="item-bd">
<div class="top">
<span class="user">{{item.author.loginname}}</span>
<span class="floor">{{index+1}} 楼</span>
<span class="time">{{getTime(item.create_at)}}</span>
</div>
<div class="content" v-html="item.content"></div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "reply",
props: ["replydata"],
methods: {
getDateTimeStamp: function (dateStr){
return Date.parse(dateStr.replace(/-/gi,"/").replace(/[A-Z]+/gi," "));
},
getTime: function(hisTime, nowTime) {
var now = nowTime ? nowTime : new Date().getTime(),
diffValue = now - this.getDateTimeStamp(hisTime),
result = "",
minute = 1000 * 60,
hour = minute * 60,
day = hour * 24,
halfamonth = day * 15,
month = day * 30,
year = month * 12,
_year = diffValue / year,
_month = diffValue / month,
_week = diffValue / (7 * day),
_day = diffValue / day,
_hour = diffValue / hour,
_min = diffValue / minute;
if (_year >= 1) result = parseInt(_year) + "年前";
else if (_month >= 1) result = parseInt(_month) + "个月前";
else if (_week >= 1) result = parseInt(_week) + "周前";
else if (_day >= 1) result = parseInt(_day) + "天前";
else if (_hour >= 1) result = parseInt(_hour) + "个小时前";
else if (_min >= 1) result = parseInt(_min) + "分钟前";
else result = "刚刚";
return result;
}
}
};
</script>
<style scoped>
.reply {
margin-top: 30px;
background: #fff;
border-radius: 4px;
}
.reply .reply-wrapper .reply-head {
padding: 8px 10px;
background: #f6f6f6;
border-radius: 4px;
}
.reply .reply-wrapper .list .item {
overflow: hidden;
padding: 20px;
border-bottom: 1px solid #ddd;
}
.reply .reply-wrapper .list .item:last-child {
border: 0;
}
.reply .reply-wrapper .list .item .item-hd {
float: left;
}
.reply .reply-wrapper .list .item .item-hd img {
border-radius: 4px;
width: 50px;
}
.reply .reply-wrapper .list .item .item-bd {
margin-left: 60px;
}
.reply .reply-wrapper .list .item .item-bd .top {
margin-bottom: 10px;
}
.reply .reply-wrapper .list .item .item-bd .user {
color: #666;
}
</style>
手机扫一扫
移动阅读更方便
你可能感兴趣的文章