首页的逻辑是:文章的渲染,按条件进行搜索
一、文章的渲染就是后端把所有数据库里article的文档作为响应返回给前端,前端将数据存在一个数组中,在模板渲染数据即可。
这里要注意这个方法是在mounted生命周期里,即每次跳转到首页都会调用一次这个方法。方法是post请求(这里为什么是post,由于我们需要传参到后端返回不同的数据),从后端请求文档数据。
有一个小点需要注意,是请求文档的时候返回,渲染顺序是反的,即旧的发布在前,新的发布在后,这是不对的,将数组reverse一下即可。(后期在后端做了这个功能,因为按存储时间拿数据的时候顺便就逆序了)
还有一个小优化是将返回的文章详情文字字数限制到200字防止太多造成布局的不美观。
代码如下:
getArticles(){
axios.post("/articles/articleList",{sex:this.sex}).then((response)=>{
let res = response.data;
if(res.status=="0"){
this.articleList = res.msg.reverse();
}else{
this.errFlag=true;
console.log("获取服务器出现问题,请稍后重试")
}
}).then(()=>{
for(var i=0;i<this.articleList.length;i++){
this.articleList[i].articleDescription = this.articleList[i].articleDescription.substr(0,200)+'……'
}
})
}
}
<div v-for="article in articleList" class="article-contain" :class="[(article.articleOwnerSex=='M'?'boy-color':'girl-color')]"><router-link :to="{path:'/detail',query:{id:article.articleId}}">
<el-row class="article-title">
<el-col :span="23" :offset="1">
<h3> {{article.articleGoTime}} 去 {{article.articleDestination}} <span class="school-style">({{article.articleOwnerSchool}})</span> </h3>
</el-col>
</el-row>
<div class="details">
<el-row>
<el-col :span="22" :offset="1">
<h4>{{article.articleDescription}}</h4>
</el-col>
</el-row><br>
<el-row>
<el-col :sm={span:1,offset:18} :xs={span:4,offset:10}>
<h5>评论:{{article.articleComment.length}}</h5>
</el-col>
<el-col :span="4" :xs="10">
<h5 class="grey-color">{{article.articlePublishTime}}</h5>
</el-col>
</el-row>
<el-row>
<el-col :span="24" style="height:12px"></el-col>
</el-row>
</div>
</router-link></div>
二、按性别、目的地、出发时间搜索符合条件的文章
这需要传参数到后台,后端根据参数过滤数据库并返回相对应的文章。
这边要用到父子组件传参,因为导航栏我封装成了一个组件,所以需要传递参数到父组件。我在另一篇文章里粗略介绍了一下父子组件传参的过程。
这里点击子组件中的性别,父组件就会将自身的sex置为F或M,点选目的地、点选出发时间,将这些值全部传给后端,后端查找并返回文章。(点击最新,清空参数,返回全部)
按目的地和按性别查找都不难,直接数据库查就行,但是按出发时间查找就有些复杂了,一开始也不知道怎么比较日期,但是日期确实是可以比较的,两个都是日期类型就可以比较,但是我一开始传入后端的goTime变量格式化成了字符串,所以还得重新改一下前面的传参格式,把goTIme重新变成日期格式写入数据库。
这里还有个坑,就是前后端的时间是不一致的,比如说我前端是2018-6-18T0:00:00,传到后端数据就会少8小时,变成2018-6-17T16:00:00,原因就在于前后端所用的时间不一致,后端是格林尼治时间,前端是电脑时间(也就是我们所在东八区时间)。
关于这一点,因为我只用日期,所以将前端传入的时间都加了8小时,在el-date-picker这个组件中有:default-time=”[‘08:00:00’, ‘08:00:00’]”属性,如此设置即可。
关于日期的比较,类似这种查询语句{‘date’:{$lt:new Date(2018,7,1),$gt:new Date(2018,6,1)}},比较查询,只要两个都是日期类型就可以比较。
后端如此(查询的逻辑还是稍稍有点绕,三个参数进行同时查询,还得判断是不是都存在还是只存在其中一两个,我的思路是先将三个查询都放在一个变量param里,然后判断哪个为空就删除哪一个,这样很简洁):
router.post("/articleList",function(req,res,next){
var destination = req.body.destination;
var goTime = req.body.goTime;
var searchTime;//查询条件变量
var sex = req.body.sex;
var date = new Date();
//查询条件
if(goTime=="最近1月")searchTime={$lte:date.setMonth(date.getMonth()+1)}
if(goTime=="1-3月内")searchTime={$gte:date.setMonth(date.getMonth()+1),$lte:date.setMonth(date.getMonth()+2)} //这里特别注意是加2,因为前面已经加了1,原始date已改变
if(goTime=="3月以上")searchTime={$gte:date.setMonth(date.getMonth()+3)}
var param={'articleDestination':destination,'articleGoTime':searchTime,'articleOwnerSex':sex};
if(destination=='')delete param.articleDestination
if(goTime=='')delete param.articleGoTime
if(sex=='')delete param.articleOwnerSex
Article.find(param).sort({'_id':-1}).exec((err,doc)=>{
if(err){
res.json({
status:"1",
msg:err.message
})
}else{
res.json({
status:"0",
msg:doc
})
}
})
})