如何用SpringBoot + Vue实现网页中很常见的下拉刷新而不是分页展示呢,比如B站首页下拉刷新视频这种操作。
下拉刷新的本质是页面本身置于顶部时,用户下拉时需要触发的动作
关于下拉刷新的原生实现,主要分成三步:
1、监听原生touchstart事件,记录其初始位置的值,e.touches[0].pageY;
2、监听原生touchmove事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3的translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值;
3、监听原生touchend事件,若此时元素滑动达到最大值,则触发callback,同时将translateY重设为0,元素回到初始位置
举个例子:
<main>
<p class="refreshText"></p >
<ul id="refreshContainer">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
...
</ul>
</main>
监听touchstart事件,记录初始的值:
var _element = document.getElementById('refreshContainer'),
_refreshText = document.querySelector('.refreshText'),
_startPos = 0, // 初始的值
_transitionHeight = 0; // 移动的距离
_element.addEventListener('touchstart', function(e) {
_startPos = e.touches[0].pageY; // 记录初始位置
_element.style.position = 'relative';
_element.style.transition = 'transform 0s';
}, false);
监听touchmove移动事件,记录滑动差值:
_element.addEventListener('touchmove', function(e) {
// e.touches[0].pageY 当前位置
_transitionHeight = e.touches[0].pageY - _startPos; // 记录差值
if (_transitionHeight > 0 && _transitionHeight < 60) {
_refreshText.innerText = '下拉刷新';
_element.style.transform = 'translateY('+_transitionHeight+'px)';
if (_transitionHeight > 55) {
_refreshText.innerText = '释放更新';
}
}
}, false);
最后,就是监听touchend离开的事件:
_element.addEventListener('touchend', function(e) {
_element.style.transition = 'transform 0.5s ease 1s';
_element.style.transform = 'translateY(0px)';
_refreshText.innerText = '更新中...';
// todo...
}, false);
从上面可以看到,在下拉到松手的过程中,经历了三个阶段:
1、当前手势滑动位置与初始位置差值大于零时,提示正在进行下拉刷新操作
2、下拉到一定值时,显示松手释放后的操作提示
3、下拉到达设定最大值松手时,执行回调,提示正在进行更新操作
在这次项目中,我才用springboot+vue实现图片的上传与下载:
//实体类:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="xxxTable对象", description="")
public class DamTable implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private String lastName;
private String address;
private Integer classId;
private LocalDateTime gmtCreated;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime gmtModified;
@ApiModelProperty(value = "图片地址字段映射")
private String imgAddress;
}
@PostMapping("/addCoverPic/{Id}")
public Result addCoverPic(@PathVariable (name = "Id")Integer damId,@RequestParam("upload") MultipartFile upload){
String filePath="E:/xxxxx/xxx_pic/";
File file =new File(filePath);
if(!file.exists()){
file.mkdirs();
}
String originalFileName = upload.getOriginalFilename();
//获取原始图片的扩展名
String newFileName = UUID.randomUUID()+originalFileName;
String newFilePath = filePath+newFileName;
String newFileName2 = "/xxx_pic/"+newFileName;
try {
upload.transferTo(new File(newFilePath));
//将传来的文件写入新建的文件
}catch (IllegalStateException | IOException e) {
//处理异常
}
XXXTable ar = xxxTableService.getById(Id);
ar.setImgAddress(newFileName2);
System.out.println(newFilePath);
xxxTableService.saveOrUpdate(ar);
return Result.success(newFileName);
}
const columns = [
{
dataIndex: 'id',
key: 'id',
slots: { title: 'customTitle' },
scopedSlots: { customRender: 'name' },
},
{
title: "封面图片",
dataIndex: "imgAddress1",
key: "imgAddress1",
align: "center",
width: "15%",
scopedSlots: {
customRender: "imgAddress1"
}
},
{
dataIndex: 'name',
key: 'name',
title: '名称',
scopedSlots: { customRender: 'name' },
},
{
title: '曾用名',
dataIndex: 'lastName',
key: 'lastName',
},
{
title: '编号',
dataIndex: 'damNo',
key: 'damNo',
}
];
采用axios请求在created()方法中获取接口数据(数据中含有img_address字段的地址值)
在获取到了column的数据之后:
<a-table :columns="columns" :data-source="users">
<span slot="customTitle"><a-icon type="smile-o" /> 编号</span>
<template slot="imgAddress1" slot-scope="text, record">
<img class="coverimg" :src="'http://localhost:xxxx/'+record.imgAddress" width="100px" alt="无封面" />
</template>
<template slot="modify" slot-scope="text, record">
<a-button type="primary" @click="showModal(record)">
修改
</a-button>
</template>
</a-table>
一定要采用上面这种的方法来加载图片,否则图片无法展示将会成为这样:
在正确使用之后,得到如下图的结果:
希望大家能有所借鉴和收获!
Respect!!!