1 问题背景

效果图如下所示:

在这里插入图片描述

2 前言

针对本篇博文,有问题的小伙伴欢迎留言

3 技术栈

  • 后台:SSM
  • 前台:Layui。因为全是html,没有jsp,所以在写任何路径时要记得加上/项目名
  • 商品展示:使用Layui的laypage,用ajax 同步请求提交

4 解决方案

定义2个容器div,一个用来展示商品,一个用来显示分页导航栏,代码如下所示:

    <div style="margin-top:70px;" id="product" ></div>
    <div style="margin-top:640px;margin-left:200px;">
		 <div  id="layuipage" ></div>
    </div>

在这里先列出最最最关键的代码,就是渲染分页,记住必须在分页显示前就获取到商品的数据,否则分页导航栏将显示不出来,代码如下所示:

 //分页的完整功能,page,limit,resCount都是自定义的全局变量
        function renderPage1(){
             renderProduct(page, limit);//关键
        	 laypage.render({
                 elem: 'layuipage'//div的id,不能加#
                 ,count: resCount//数据总条数
                 ,limit: limit//每页显示多少条数据
                 ,limits: [limit]//可选择的 每页显示多少条数据
                 ,curr: page//当前页码
                 ,theme: '#FFB800'//分页导航栏的颜色,用了橘色
                 ,layout: ['count', 'prev', 'page', 'next', 'limit', 'refresh', 'skip']
                 ,jump: function(obj, first){
                   console.info(obj);
                   page = obj.curr;
                   if(!first){//如果不是首次加载,那么进行ajax同步获取数据请求
                	   renderProduct(page, limit);//关键
                   }
                 }
               });
        }

解释: 注意,elem的值中不能加#,从上面可以看到有一个renderProduct(page, limit)的方法,这是最最最最最最关键的代码,必须在进行渲染分页前就获得商品的数据(如商品ID,商品名称等等),获取完数据后,再进行分页渲染,然后在jump中的if(!first)中再次进行获取数据,否则会进行无限刷新

下面给出JS的完整的代码:

<script>
    layui.use(['jquery', 'layer', 'miniAdmin', 'miniTongji', 'laypage'], function () {
        var $ = layui.jquery,
            layer = layui.layer,
            miniAdmin = layui.miniAdmin,
            miniTongji = layui.miniTongji,
            laypage = layui.laypage;
        
        var page = 1;//当前页
        var limit = 16;//每页显示的数目
        var resCount, resData ;
        var resPage = renderPage1();
        
        //渲染展示商品的html页面
        function renderProductHtml(data){
        	var str = "";//用来存储html内容
        	if(data.length > 0){
	        	$.each(data, function(v, o){
	        		str += "<div style='margin:auto; margin-bottom:130px;  width:150px; height:150px; float:left; text-align:center'><div><img alt='' src='"+o.imgPath+"' width='150px' height='150px'/></div>";
	        		str += "<div style='text-align:left'><div><label>商品名称:</label><span>"+o.productName+"</span></div>";
	        		str += "<div><label>价格:</label><span style='color:#FF3030;'>¥"+o.price+"</span></div>";
	        		str += "<div><label>新旧程度:</label><span>"+o.degree+"</span></div>";
	        		str += "<div><label>销量:</label><span style='color:#CDC9C9;'>"+o.sales+"</span>";
	        		str += "<label>库存:</label><span style='color:#CDC9C9;'>"+o.stock+"</span></div>";
	        		str += "<div style='display:none;'><label>商品ID:</label><span>"+o.product_id+"</span></div></div></div>";
	        	});
	        	$("#product").html(str);
        	}
        	
        }
        
        
        //同步加载商品数据
        function renderProduct(page, limit){
        	$.ajax({
        		async: false,
        		url: '/UsedProduct/product/getProductPage',
        		data: {"page": page, "limit": limit},
        		dataType: 'json',
        		success: function(result){
        			console.info(result);
        			resCount = result.count;
        			resData = result.data;
        			renderProductHtml(resData);
        		}
        	});
        }
        
        
        //分页的完整功能
        function renderPage1(){
             renderProduct(page, limit);
        	 laypage.render({
                 elem: 'layuipage'
                 ,count: resCount
                 ,limit: limit
                 ,limits: [limit]
                 ,curr: page
                 ,theme: '#FFB800'
                 ,layout: ['count', 'prev', 'page', 'next', 'limit', 'refresh', 'skip']
                 ,jump: function(obj, first){
                   console.info(obj);
                	   page = obj.curr;
                   if(!first){
                	   renderProduct(page, limit);
                   }
                 }
               });
        }
    });
</script>

ajax提交的请求,交给servlet处理,servlet必须返回json格式(所以必须加@ResponseBody注释。响应报文的格式必须包含codemsgcountdata字段。servlet代码如下:

    @ResponseBody  
	@RequestMapping(value="/getProductPage")
	public Map<String, Object> getProductPage(@RequestParam("page")Integer page,
			@RequestParam("limit")Integer limit){
		Map<String,Object> map = new HashMap<String, Object>();
		PageInfo<Product> pageInfo = productService.getProductPage(page, limit);
		map.put("code", 0);
		map.put("msg", "操作成功");
		map.put("count", pageInfo.getTotal());
		map.put("data", pageInfo.getList());
		return map;
	}

5 后记

更新于2022-04-12:

本博文是笔者在校期间做的一个小demo,算不得一个项目。看着接近毕业日期,很多小伙伴看笔者的这篇文章。如果大家拿来做毕设,不推荐使用Layui作为前端技术栈,推荐使用vue。如果觉得压力大,无法完成前后端所有工作,毕设可以考虑做其他东西,比如缓存一致性算法、高可用解决方案、高性能解决方案、排序算法的变种。追求细致的点,没必要做那种完整的项目,学校老师多年经验都看腻了那些完整项目的毕设了,都非常极力推荐有亮点、更加细致的东西。笔者做的是一个高并发场景下如何提高数据加载速率,涉及到了一整套缓存架构,其中有jvm内存缓存、分布式缓存、nginx缓存架构等等,做起来也不会枯燥乏味。针对本篇博文,有问题的小伙伴欢迎留言。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐