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

//根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. Python字符串切片操作知识详解

    Python字符串切片操作知识详解 这篇文章主要介绍了Python中字符串切片操作 的相关资料,需要的朋友可以参考下 一:取字符串中第几个字符 print "Hello"[0] 表 ...

  2. 查看JDK的安装路径 和 安装版本

    查看JDK的安装路径: 打开 运行,输入 cmd .  输入: java -verbose                      (ps:java后面必须敲一个空白格) 得到下图:  最后的两行, ...

  3. 数字统计类题目的非数位DP解法

    ZJOI2010 数字统计 上题题意为求[l,r]区间中每个数字(0~9)出现的次数 一般的做法为将区间当成[0,r]-[0,l-1],然后进行数位DP 但事实上将区间当成[0,r]-[0,l-1]后 ...

  4. HYSBZ 1015/BZOJ1015 星球大战starwar

    Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过 ...

  5. 配置android studio环境

    配置java jdk 1.1运行exe 程序 1.2配置jdk 环境变量 添加环境变量 ;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin .;%JAVA_HOME%\lib;% ...

  6. alert对象相关问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. web服务器--nginx简介

    nginx 介绍Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务.Nginx是一款轻量级的Web 服务器/反向代理服务器及电 ...

  8. WPF 单个模块换肤

    xmal: <Window x:Class="wpfSkin.MainWindow" xmlns="http://schemas.microsoft.com/win ...

  9. mysql查询 包含某个字符的记录

    从excel导入数据库的时候,发现poi自动把电话号码转换为科学计数法了 所以要把带e的筛选出来 SELECT * FROM t_customer WHERE phone like '%E%'; 然后 ...

  10. 006-使用python编写一个猜数字的程序

    题目:随机生成一个数字,共有三次机会对该数字进行猜测. #功能点# 1.猜错的时候给出提示,告诉用户输入的值是大了还是小了# 2.最多提供三次机会# 3.随机生成需要猜的数字答案 编写思路: 1.刚开 ...