Vue系列-前端条件分页查询全流程演示

    科技2024-12-14  28

    最近在做个人博客网站,后端的条件分页查询已经写好(见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解决方案与本文章即可,如果还有什么别的功能需要增加,以此为基础进行扩展即可。如果对你有帮助,请记得点赞!如果发现问题,请记得在评论区告诉我,我会即时修正,谢谢!

    Processed: 0.012, SQL: 8