实战篇
cnode社区的基本架构
组件:
- Header 头部
- Posltlist 首页列表
- Article 文章的详情页
- Sidebar 侧边栏
- Userinfo 用户个人信息
- psgination 分页组件
准备工作:从0开始实战 Header组件
cmder中的操作
- 进入目录-初始化项目 vue init webpack (my-project) cnode ---cnode为项目名称 会有一系列的yes或no的操作。
- 进入项目 cd cnode
- 安装依赖 cnpm install
- 启动项目 npm run dev 此时出现了一个网址,而且cnode文件夹子里,也建好了很多文件。
vscode中的操作
- 在vscode中引入cnode文件;
- 删除src\components\HelloWorld.vue,这个helloworld。
- 删除app.vue的
<img src="./assets/logo.png"> <router-view/>以及#app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; }
一、Header的创建
- 下面是header的样式:有图片,列表
- 在component下面新建组建header.vue;
- template里面有且只能有一个根组件,所以只能有一个div; -快捷创建列表ul>li*5,因为列表上的小标题有链接,所以加上一个href。
<template>
<div class="header">
<img src="" alt="">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">新手入门</a></li>
<li><a href="#">API</a></li>
<li><a href="#">关于</a></li>
<li><a href="#">注册</a></li>
<li><a href="#">登录</a></li>
</ul>
</div>
</template>
<script>
export default{
name:"Header"
}
</script>
<style scoped>
.header{
background-color:rgb(68,68,68);
height:50px;
}
img{
max-width:120px;
margin-left:50px;
margin-top:10px;
}
ul{
list-style:none;
float:right;
margin:4px;
}
li{
display:inline-block;
padding:10px 15px;
}
a{
text-decoration:none;
color:#ccc;
font-size: 14px;
}
</style>
在App.vue中引入刚才创建的Header组件
<template>
<div id="app">
<Header></Header>
</div>
</template>
<script>
import Header from './components/Header'
export default {
name: 'App',
components:{
Header
}
}
</script>
备注:此时刷新页面会报错,因为在router的index.js中之前引入的helloworld文件没有被删除。
- 删除assets里面自带的logo.png;
- 在assets中放入相应的图片,在Header.vue后台引入
<img src="../assets/cnodejs_light.svg" alt=""> - 在下面的中设置图片的大小,scoped的作用是只对当前的组件有效,不加scoped则对整个应用都有效。在style可以设置大小,对齐等等。
二、PostList组件的创建
-
- 在components中创建一个PostList组件;
-
- 在template创建一个div根组件,里面在加两个div,一个是为了在加载慢时出现提示,即数据没有返回时显示正在加载,另一个div就是正常的内容;
<template>
<div>
//在数据没有返回时,显示正在加载,加一个v-if是否要加载
<div class="loading" v-if="isLoading">
<img src="../assets/loading.gif" >
</div>
<!--数据一旦返回,就显示下面的div,帖子的主题,我们需要帖子的一些数据所以要用到一个官方的,API的接口https://cnodejs.org/api/v1/topics,用来获取帖子列表-->
<div class="posts" v-else>
<ul>
<li>
<div class="toobar>
<span>全部</span>
<span>精华</span>
<span>分享</span>
<span>问答</span>
<span>招聘</span>
</div>
</li>
</ul>
</div>
<li v-for="post in posts">
<!--头像-->
<img :src="post.author.avatar_url" alt="">
<!--回复/浏览-->
<span class="allcount">
<span class="reply_count">{{post.reply_count}}</span>
/{{post.visit_count}}
</span>
<!--帖子的分类-->
如果post.good是true,那么就执行put_good在style中的格式
<span :class="[{put_good:(post.good == true),put_top:(post.top == true),
topiclist-tab:(post.good != true && post.top != true)}]">
<span>
{{post | tabFormatter}}
</span>
</span>
<!--标题-->
<router-link :to="{
name:'post_content',
params:{
id:post.id,
name:post.author.loginname
}
}">
<span>
{{post.title}}
</span>
</router-link>
<!--最終回复时间-->
<span class="last_reply">
{{post.last_reply_at | formatDate}}
</span>
</li>
<li>
<!--分页-->
<pagination @handleList="renderList"></pagination>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "PostList",
data(){
return{
isLoading:false
}
}
}
</script>
<style scoped>
</style>
-
- API接口:cnodejs.org/api/v1/topi… 获取帖子列表 limit(每页显示多少) page(显示在第几页) API的参数分析:
- 头像:author.avatar_url
- 回复量/浏览量:reply_count/visit_count
- 帖子的标题:title
- 需要用到的过滤器:
- 时间(发帖子的时间):last_reply_at
- 帖子分类:top: 代表是否置顶; good: 代表是否精华 tab是表示除了置顶和精华之外的其余分区; -share 分享; -ask 问答; -job 招聘
- 在新建终端里面安装axios,目的是链接API
- npm install axios(安装)
- import Axios from 'axios'(在main.js引入,一些全局使用的文件,都是在main.js 中引用)
- Vue.prototype.http来发动请求了 4.最终回复时间的过滤器写在main.js中,因为是全局的。
时间的过滤器
Vue.filter('formatDate', function (str) {
if (!str) return ''
var date = new Date(str)
var time = new Date().getTime() - date.getTime() //现在的时间-传入的时间 = 相差的时间(单位 = 毫秒)
if (time < 0) {
return ''
} else if ((time / 1000 < 30)) {
return '刚刚'
} else if (time / 1000 < 60) {
return parseInt((time / 1000)) + '秒前'
} else if ((time / 60000) < 60) {
return parseInt((time / 60000)) + '分钟前'
} else if ((time / 3600000) < 24) {
return parseInt(time / 3600000) + '小时前'
} else if ((time / 86400000) < 31) {
return parseInt(time / 86400000) + '天前'
} else if ((time / 2592000000) < 12) {
return parseInt(time / 2592000000) + '月前'
} else {
return parseInt(time / 31536000000) + '年前'
}
}
)
'mock.hunger-valley.com/cnode/api/v…'