title: 乐优商城学习笔记十五-搜素微服务(三)
date: 2019-04-19 16:51:52
tags:
- 乐优商城
- java
- springboot
categories:
- 乐优商城
3.页面分页效果
刚才的查询中,我们默认了查询的页码和每页大小,因此所有的分页功能都无法使用,接下来我们一起看看分页功能条该如何制作。
这里要分两步,
- 第一步:如何生成分页条
- 第二步:点击分页按钮,我们做什么
3.1.如何生成分页条
先看下页面关于分页部分的代码:
1526692249371可以看到所有的分页栏内容都是写死的。
3.1.1.需要的数据
分页数据应该是根据总页数、当前页、总条数等信息来计算得出。
- 当前页:肯定是由页面来决定的,点击按钮会生成不同的页
- 总页数:需要后台传递给我们
- 总条数:需要后台传递给我们
我们首先在data中记录下这几个值:
1526694848538因为page是搜索条件之一,所以记录在search对象中。
要注意:我们在created钩子函数中,会读取url路径的参数,然后赋值给search。如果是第一次请求页面,page是不存在的。因此为了避免page被覆盖,我们应该这么做:
1526715358560不过,这个时候我们自己的search对象中的值就可有可无了
3.1.2.后台提供数据
后台返回的结果中,要包含total和totalPage,我们改造下刚才的接口:
在我们返回的PageResult对象中,其实是有totalPage字段的:
1526695144476我们在返回时,把这个值填上:
1526695592422页面测试一下:
1526695713496OK
3.1.3.页面计算分页条
首先,把后台提供的数据保存在data中:
1526695967230然后看下我们要实现的效果:
1526695821870这里最复杂的是中间的1~5的分页按钮,它需要动态变化。
思路分析:
- 最多有5个按钮,因此我们可以用
v-for
循环从1到5即可,假如遍历得到的值为i
- 但是分页条不一定是从1开始:
- 如果当前页值小于等于3的时候,分页条位置从1开始到5结束,页码就是遍历得到的
i
的值 - 但是如果大于3,则不应该是
i
,而是要比i
大了(page-3),所以就是page-3 + i
- 如果当前页值小于等于3的时候,分页条位置从1开始到5结束,页码就是遍历得到的
所以,我们的页面这样来做:
1526698486165a标签中的分页数字通过index
函数来计算,需要把i
传递过去:
index(i) {
if (this.search.page <= 3 || this.totalPage <= 5) {
// 当前页小于3,则页码就是从 i 开始
return i;
} else if(this.search.page <= this.totalPage - 2) {
// 大于3,则从page-2开始,然后逐个加1
return this.search.page - 3 + i;
} else{
return this.totalPage - 5 + i;
}
}
需要注意的是,如果总页数不足5页,我们就不应该遍历15,而是1总页数,稍作改进:
1526698842013分页条的其它部分就比较简单了:
<div class="sui-pagination pagination-large">
<ul style="width: 550px">
<li :class="{prev:true,disabled:search.page === 1}">
<a href="#">«上一页</a>
</li>
<li :class="{active: index(i) === search.page}" v-for="i in Math.min(5,totalPage)" :key="i">
<a href="#">{{index(i)}}</a>
</li>
<li class="dotted" v-show="totalPage > 5"><span>...</span></li>
<li :class="{next:true,disabled:search.page === totalPage}">
<a href="#">下一页»</a>
</li>
</ul>
<div>
<span>共{{totalPage}}页 </span>
<span>
到第
<input type="text" class="page-num" :value="search.page">
页 <button class="page-confirm" onclick="alert(1)">确定</button>
</span>
</div>
</div>
3.2.点击分页做什么
点击分页按钮后,自然是要修改page
的值
所以,我们在上一页
、下一页
按钮添加点击事件,对page进行修改,在数字按钮上绑定点击事件,点击直接修改page:
翻页事件的方法:
prevPage(){
if(this.search.page > 1){
this.search.page--
}
},
nextPage(){
if(this.search.page < this.totalPage){
this.search.page++
}
}
当page
发生变化,我们应该去后台重新查询数据。
不过,如果我们直接发起ajax请求,那么浏览器的地址栏中是不会有变化的,没有记录下分页信息。如果用户刷新页面,那么就会回到第一页。
这样不太友好,我们应该把搜索条件记录在地址栏的查询参数中。
因此,我们监听search的变化,然后把search的过滤字段拼接在url路径后:
watch:{
search:{
deep:true,
handler(val){
// 把search对象变成请求参数,拼接在url路径
window.location.href = "http://www.leyou.com/search.html?" + ly.stringify(val);
}
}
},
刷新页面测试,然后就出现重大bug:页面无限刷新!为什么?
因为Vue实例初始化的钩子函数中,我们读取请求参数,赋值给search的时候,也触发了watch监视!也就是说,每次页面创建完成,都会触发watch,然后就会去修改window.location路径,然后页面被刷新,再次触发created钩子,又触发watch,周而复始,无限循环。
所以,我们需要在watch中进行监控,如果发现是第一次初始化,则不继续向下执行。
那么问题是,如何判断是不是第一次?
第一次初始化时,search中的key值肯定是空的,所以,我们这么做:
watch:{
search:{
deep:true,
handler(val,old){
if(!old || !old.key){
// 如果旧的search值为空,或者search中的key为空,证明是第一次
return;
}
// 把search对象变成请求参数,拼接在url路径
window.location.href = "http://www.leyou.com/search.html?" + ly.stringify(val);
}
}
}
再次刷新,OK了!
3.3.页面顶部分页条
在页面商品列表的顶部,也有一个分页条:
1526716212704我们把这一部分,也加上点击事件:
15267163881963.4.页面跳转
代码
到第
<input type="text" class="page-num" ref="page">
页 <button class="page-confirm" @click="navPage">确定</button></span></div>
</div>
</div>
</div>
navPage(){
this.search.page = this.$refs.page.value;
},
4.排序(作业)
4.1.页面搜索排序条件
在搜索商品列表的顶部,有这么一部分内容:
1526716565293这是用来做排序的,默认按照综合排序。点击新品,应该按照商品创建时间排序,点击价格应该按照价格排序。因为我们没有统计销量和评价,这里咱们以新品
和价格
为例,进行讲解,做法是想通的。
排序需要知道两个内容:
- 排序的字段
- 排序的方式
因此,我们首先在search
中记录这两个信息,因为created钩子函数会对search进行覆盖,因此我们在钩子函数中对这两个信息进行初始化即可:
然后,在页面上给按钮绑定点击事件,修改sortBy
和descending
的值:
<!--排序字段-->
<ul class="sui-nav">
<li :class="{active:!search.sortBy}" @click="search.sortBy=''">
<a href="#">综合</a>
</li>
<li>
<a href="#">销量</a>
</li>
<li @click="search.sortBy='createTime'" :class="{active: search.sortBy==='createTime'}">
<a href="#">新品</a>
</li>
<li>
<a href="#">评价</a>
</li>
<li @click="search.sortBy='price'; search.descending = !search.descending"
:class="{active: search.sortBy==='price'}">
<a href="#">
价格
<v-icon v-show="search.descending">arrow_drop_down</v-icon>
<v-icon v-show="!search.descending">arrow_drop_up</v-icon>
</a>
</li>
</ul>
可以看到,页面请求参数中已经有了排序字段了:
15267182523154.2.后台添加排序逻辑
接下来,后台需要接收请求参数中的排序信息,然后在搜索中加入排序的逻辑。
现在,我们的请求参数对象SearchRequest
中,只有page、key两个字段。需要进行扩展:
然后在搜索业务逻辑中,添加排序条件:
1526718637618注意,因为我们存储在索引库中的的价格是一个数组,因此在按照价格排序时,会进行智能处理:
- 如果是价格降序,则会把数组中的最大值拿来排序
- 如果是价格升序,则会把数组中的最小值拿来排序
网友评论