最近在做个人博客网站,后端的条件分页查询已经写好(见https://blog.csdn.net/ws6afa88/article/details/108928401),现在来用Vue做前端显示。
1. 数据表
数据表sql:
CREATE DATABASE /*!32312 IF NOT EXISTS*/`myblog` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `myblog`;
/*Table structure for table `articles` */
DROP TABLE IF EXISTS `articles`;
CREATE TABLE `articles` (
`article_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`title` varchar(255) DEFAULT NULL COMMENT '文章标题',
`name` varchar(255) DEFAULT NULL,
`view_num` int(11) DEFAULT NULL COMMENT '浏览数',
`comment_num` int(11) DEFAULT NULL COMMENT '评论数',
`category_id` bigint(20) DEFAULT NULL COMMENT '文章分类ID',
`create_time` datetime DEFAULT NULL COMMENT '创建日期',
`like_num` int(11) DEFAULT '0',
PRIMARY KEY (`article_id`),
KEY `key_category_id` (`category_id`),
KEY `key_userId` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8 COMMENT='文章表';
/*Data for the table `articles` */
insert into `articles`(`article_id`,`user_id`,`title`,`name`,`view_num`,`comment_num`,`category_id`,`create_time`,`like_num`) values (1,0,'555','555.md',0,3,1,'2020-09-22 00:00:00',0),(83,1,'daidai','daidai.md',0,4,1,'2020-09-30 11:09:42',0),(84,1,'redis安装','redis安装.md',0,1,1,'2020-09-30 11:09:43',0),(85,1,'淘宝革命的启示录','淘宝革命的启示录.md',0,2,1,'2020-09-30 11:09:43',0),(98,1,'444','444.md',0,9,0,'2020-10-01 10:55:45',0);
2. 最终效果
3. axios函数
所需要的条件分页函数定义在article.js中
//条件分页查询
export const findPage = (pageSize,pageNum,title) => {
return axios({
method: 'post',
url: `/findPage`,
data: {
sortView: "commentNum", //暂时写死,按浏览量排序
direction: "desc", //暂时写死,倒序
pageSize: pageSize,
pageNum: pageNum,
title:title
},
})
}
与后端的条件分页查询相对应
4.前端布局
<el-container class="home-container" >
<!-- 内容栏 -->
<el-main>
<!-- 显示具体文章,如果flag=true,则显示 -->
<div v-if="flag">
<router-view></router-view>
</div>
<!--显示文件列表,如果<router-view>显示,就会触发flag=true,这个时候文件列表隐藏-->
<div v-if="!flag">
<!--搜索区域-->
<el-row >
<el-col :span="8">
<el-input placeholder="请输入查找文章的名子" v-model="queryName" clearable @clear="getAllPage">
<el-button slot="append" icon="el-icon-search" @click="getAllPage"></el-button>
</el-input>
</el-col>
</el-row>
<el-row v-for="(item,index) in routerList" :key="item.articleId">
<el-col :span="24">
<div class="grid-content">
<p>
<span class="num">{{index}}</span>
<router-link :to="'/articleList/article/'+item.articleId" class="router-link-active">{{item.name}}</router-link>
</p>
<i class = "el-icon-view">浏览量</i>
<span class="commentNum">{{item.viewNum}}</span>
<i class = "el-icon-thumb">评论数</i>
<span class="commentNum">{{item.commentNum}}</span>
<i class = "el-icon-loading"></i>点赞数
<span class="commentNum">{{item.likeNum}}</span>
<i class = "el-icon-edit"></i>创建日期
<span class="commentNum">{{item.createTime}}</span>
</div>
</el-col>
</el-row>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[2, 5, 10, 15]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</el-main>
</el-container>
这里每一个列表项都是一个"router-link组件",点击后路由跳转到Article组件,并显示到“router-view组件”中,当router-view组件显示时,会触发flag=true,这个时候列表项就会隐藏。具体的触发方式需要监听$route对象的变化:
watch:{
//监听路由变化
$route(to,from){
//如果传过来的path不为空,就将flag设为true
if(to.path!=null){
this.flag=true;
}
}
}
用到的相关组件都是ElementUI中的,请自行导入,在此不再赘述。
5. 相关样式
可能你有更漂亮的样式设计,请原谅我的审美
<style scoped>
.home-container {
height: 100%;
display: flex;
}
.el-main {
color: #333;
}
.router-link-active {
/* 不显示链接的下划线 */
text-decoration: none;
font-family: '微软雅黑';
font-size: 25px;
color: #333 ;
letter-spacing: 1px;
font-weight:bolder;
margin-right: 20px;
}
/* 鼠标悬停显示红色 */
.router-link-active:hover{
color: rgb(228, 22, 22) ;
}
.grid-content {
border-radius: 4px;
border-block-width: 10px;
border-color: blue;
min-height: 36px;
margin-top: 20px;
border-bottom: 1px solid #ddd;
padding-bottom: 10px;
}
.num{
font-size: 25px;
margin-right: 30px;
}
.commentNum{
margin-left: 20px;
margin-right: 20px;
}
.el-pagination{
margin-top: 15px;
}
</style>
重点注意“router-link组件”不显示下划线的样式写法,以及鼠标悬停变色的样式写法。
6. data
data(){
return {
flag: false, //false显示列表,true显示文章
routerList:[], //后端获取的Array
currentPage:1, //当前显示页数
pageSize:5, //单页条数
total:0, //总条数
queryName:null //查询的内容,这里固定死,只查title,以后慢慢扩展
}
},
7.methods中相关函数
methods:{
//页数大小变化
handleSizeChange(val){
this.pageSize=val;
this.getAllPage();
},
//当前页变化
handleCurrentChange(val){
this.currentPage=val;
this.getAllPage();
},
//条件分页查询
getAllPage(){
findPage(this.pageSize,this.currentPage,this.queryName).then(res=>{
console.log(res)
this.routerList=res.content;
this.total=res.totalSize;
})
}
},
mounted(){
this.getAllPage(); //页面初始化显示
}
}
这里的findPage,需要从article.js中引入
import {findPage} from '@/api/article'
8. 需要注意的两个点
8.1 Vue的POST请求是通过json传参
因此后端controller层需要通过@RequestBody标明参数,并对参数进行格式转换
@PostMapping("api/findPage")
public Object findPage(@RequestBody JSONObject param) {
//取出json中的内容,注意取出的字段值都是String类型
String sortView = param.getString("sortView");
String direction = param.getString("direction");
String pageSize = param.getString("pageSize");
String pageNum = param.getString("pageNum");
String title = param.getString("title");
ArticleQuery aq=new ArticleQuery();
aq.setSortView(sortView);
aq.setDirection(direction);
aq.setPageSize(Integer.valueOf(pageSize));
aq.setPageNum(Integer.valueOf(pageNum));
//查询条件
aq.setTitle(title);
return articleService.findPage(aq);
}
8.2 日期格式转换
由于Article中定义的createTime为Timestamp类型
当后端传回前端Vue时,会显示这样的效果:
“2020-10-01T02:55:45.000+00:00”显示出来明显不太好,我们需要对这个时间格式进行处理,这时需要用response拦截器来做,response拦截器的设计见https://blog.csdn.net/ws6afa88/article/details/108878027,为此只需在拦截器中加上下面的代码即可:
//response拦截器
axios.interceptors.response.use(
response => {
//如果返回成功对respone做什么处理
if(response.data.content != null){
var myArray = response.data.content;
myArray.forEach(element=>{
//将时间格式改为年月日
var da = element.createTime;
da = new Date(da);
var year = da.getFullYear()+'年';
var month = da.getMonth()+1+'月';
var date = da.getDate()+'日';
// console.log([year,month,date].join(''));
element.createTime=[year,month,date].join('')
})
}
// console.log(response.data)
return response.data
},
error => {
//如果返回错误,对error做什么处理
// console.log(error.response)
return Promise.reject('error')
})
于是可以得到我们想要的结果:
9. 检测查询与分页效果
查询“44”,效果如下,没有问题:
分页效果测试也是正确的,没有问题:
10. 总结
关于前端与后端的条件分页做法,看SpringBoot - 条件分页查询-MyBatis解决方案与本文章即可,如果还有什么别的功能需要增加,以此为基础进行扩展即可。如果对你有帮助,请记得点赞!如果发现问题,请记得在评论区告诉我,我会即时修正,谢谢!