感谢那些无私开源的程序员,你们是最可爱的人儿~~~~

//根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>

点进去就可以看到项目哇~

vue-cnodejs的更多相关文章

  1. vue分页组件table-pagebar

    之前一直接触都是原始的前端模型,jquery+bootstrap,冗杂的dom操作,繁琐的更新绑定.接触vue后,对前端MVVM框架有了全新的认识.本文是基于webpack+vue构建,由于之前的工作 ...

  2. Vue开源项目库汇总

    最近做了一个Vue开源项目库汇总,里面集合了OpenDigg 上的优质的Vue开源项目库,方便移动开发人员便捷的找到自己需要的项目工具等,感兴趣的可以到GitHub上给个star. UI组件 elem ...

  3. Vue 2.0初学后个人总结及分享

    摘要:最近在上海找工作,发现Vue前景还不错,于是就打算先学习一下(之前了解过,但是一直没提到日程上)这篇随笔当是为了自己学习之后,做一个小的阶段性总结.希望本文的内容对于刚开始接触vue的朋友们有点 ...

  4. vue.js应用开发笔记

    看vue.js有几天了,之前也零零散散的瞅过,不过一直没有动手去写过demo,这几天后台事比较少,一直在讨论各种需求(其实公司对需求还是比较重视与严谨的,一个项目需求讨论就差不多一周了,这要搁之前,天 ...

  5. Vue常用经典开源项目汇总参考-海量

    Vue常用经典开源项目汇总参考-海量 Vue是什么? Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的 ...

  6. 基于angular的route实现单页面cnodejs

    Angular ui-router 前言 之前不太理解前端怎么实现路由功能,以前知道有一种方式使用html5的pushState可以操作url才实现路由的功能,在实践项目中也用过一次,后来这种操作叫成 ...

  7. 使用Vue快速开发单页应用

    本文所涉及代码全在vue-cnode 单页应用,即在一个页面集成系统中所有功能,整个应用只有一个页面.因为路由的控制在前端,单页面应用在页面切换时比传统页面更快,从而在前端体验更好. 将逻辑从后端转移 ...

  8. Vue.js学习网址

    Vue官网:http://cn.vuejs.org/v2/guide/index.html 淘宝镜像:http://npm.taobao.org/ Vue-router:https://router. ...

  9. Vue常用开源项目汇总

    前言:Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还 ...

  10. vue报错 Do not use built-in or reserved HTML elements as component id:header

    组件,不能和html标签重复 header组件,h5新标签重复 Do not use built-in or reserved HTML elements as component id:header ...

随机推荐

  1. spring cloud深入学习(十一)-----服务网关zuul

    前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...

  2. Windows 10专业版激活(附激活码)

    安全密钥:BT6TH-FN8VP-6WGCK-6BM9R-MWRDB(使用有效,在物理机,虚拟机都激活了一次) 六一八期间自己买了配件第一次组了台式机,系统是在123pe下的原版win10,装好机器之 ...

  3. PAT甲级——A1015 Reversible Primes

    A reversible prime in any number system is a prime whose "reverse" in that number system i ...

  4. 微端 打包更新工具 as air 分享

    分享 微端,更新的是散包,不像端游,一个大包搞定. 更新须要每次用工具把资源的散文件.依据文件夹结构及时间 生成一个列表, 每次更新就是 文件夹及时间的比对! 该project能够翻译成 其它语言.有 ...

  5. LA3905 Meteor

    https://vjudge.net/problem/UVALive-3905 计算出每个点在相框中的时间段,扫描线做即可 关键在如何快速计算每个点在相框中的时间段.对每个点进行运动分解,进入的时间L ...

  6. Luogu P4011 孤岛营救问题(状态压缩+最短路)

    P4011 孤岛营救问题 题意 题目描述 \(1944\)年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到 ...

  7. Firefox Developer Edition - Mozilla

    冰狐浏览器开发者工具:https://www.mozilla.org/en-US/firefox/developer/ 冰狐浏览器开发者工具:https://www.mozilla.org/en-US ...

  8. 使用requireJs进行模块化开发

    requireJs使用 requireJs 使用require.js的第一步,是先去官方网站下载最新版本. 下载后,假定把它放在js子目录下面,就可以加载了. <script src=" ...

  9. vue组件与路由的使用步骤

    router:根据不同的地址跳转到不同的页面一.vue-router的使用 1.下载路由模块      npm vue-router --save 2.在router.js中 先引入路由    imp ...

  10. [转]js的垃圾回收机制

    javascript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存.在编写javascript程序时,开发人员不用再关心内存使用问题,所需内存的分配以及无用内存的回收完全实现了自动管 ...