用vue写一个仿app下拉刷新的组件
如果你用vue弄移动端的页面,那么下拉刷新还是比较常见的场景,下面来研究如何写一个下拉刷新的组件(先上图);




由于节省大家的时间,样式就不贴出来了。
html结构也不必介绍了,直接看代码吧-.-
<transition>
<div class="refresh-wrapper" ref="refresh">
<div class="refresh-inner">
<div class="refresh-pull" v-show="state==='pull'">
<span>下拉刷新-.-</span>
</div>
<div class="refresh-loading" v-show="state==='loading'">
<span>刷新中...~.~</span>
</div>
<div class="refresh-end" v-show="state==='end'">
<span>刷新完成!^.^</span>
</div>
</div>
</div>
</transition>
核心思路及步骤
- 给
document绑定touch事件
document.addEventListener('touchstart',this.touchStart,false);
document.addEventListener('touchmove',this.touchMove,false);
document.body.addEventListener('touchend',this.touchEnd,false);
touchStart细节
2.1 判断状态,这是为了防止在刷新时多次触发。可以定义一个变量保存状态,状态值为pull, loading, end;
2.2 记录开始的位置,Y轴的就可以了;
2.3 获取当前touch的对象? 虽然我们已经把事件绑定在document上了,但是在有局部滚动的时候,那么向下滑动的时候就会有冲突,这个时候可以获取到当前touch的对象,后面做处理;
touchStart(e){
if(this.state === 'loading') return;
this.startY = e.touches[0].clientY;
this.getTouchTarget(e.target);
}
getTouchTarget(elm){
let currentNode = elm;
while(currentNode && currentNode.tagName !== "HTML" &&
currentNode.tagName !== "BODY" && currentNode.nodeType === 1){
let overflowY = window.getComputedStyle(currentNode).overflowY;
if(overflowY === "scroll" || overflowY === "auto"){
this.currentNode = currentNode;
this.firstNode = currentNode.firstElementChild; //记录局部滚动的第一个子元素
break;
}
currentNode = currentNode.parentNode;
}
}
touchMove细节
3.1 判断当前滑动的区域是否局部滚动,如果是,通过判断父元素和子元素的getBoundingClientRect().top的差值是否小于0来判断是否滚动到顶部
3.2 判断一些其他的条件
3.3 记录滑动的距离
3.4 改变视图
touchMove(e){
let firstTop=0, currentTop=0;
if(this.firstNode){
firstTop = this.firstNode.getBoundingClientRect().top;
currentTop = this.currentNode.getBoundingClientRect().top;
}
let range = (e.touches[0].clientY - this.startY);
if( document.documentElement.scrollTop>0 || this.state === 'loading' || firstTop-currentTop <0 || range<0) return;
range = range*0.75 > this.maxRange? this.maxRange : range;
this.translate = range;
this.changeView();
}
changeView(){
//这里针对transfrom对fixed定位的bug做的降级处理
if(this.isFixed){
this.$refs.refresh.style.transform=`translate3d(0,${this.translate}px,0)`;
}else{
document.body.style.transform = `translate3d(0,${this.translate}px,0)`;
}
}
touchEnd细节
4.1 判断状态
4.2 判断滑动距离是否到可刷新距离,如果是,调用刷新api
4.3 改变视图
touchEnd(e){
if(this.state === 'loading') return;
if(this.translate && this.translate >= this.maxRange){
this.translate = this.maxRange/2;
this.refresh();
}else{
this.translate = 0;
}
this.rotate = 0;
this.changeView();
}
refresh(){
this.state = 'loading';
console.log('更新中...');
this.$emit('refresh'); //父组件监听refresh方法,并在异步回调中调用子组件的refreshEnd方法,可通过this.$refs.名称.refreshEnd()方法调用
}
refreshEnd(){
let _this = this;
this.state = 'end';
setTimeout(()=>{
_this.translate = 0;
_this.changeView();
},1000);
setTimeout(()=>{
_this.state = 'pull';
},1300)
console.log('更新完成...');
}
注意
1.如果有fixed布局,要传isFixed='true',否则会有bug。关于transform 与fixed的bug,可以参考这里
2. 不建议用在过于复杂的布局,可能有未知bug -.-
用vue写一个仿app下拉刷新的组件的更多相关文章
- 用vue写一个仿简书的轮播图
原文地址:用vue写一个仿简书的轮播图 先展示最终效果: Vue的理念是以数据驱动视图,所以拒绝通过改变元素的margin-top来实现滚动效果.写好css样式,只需改变每张图片的class即可实现轮 ...
- 基于PtrFrameLayout实现自定义仿京东下拉刷新控件
前言 最近基于项目需要,使用PtrFrameLayout框架实现了自定义的下拉刷新控件,大体效果类似于京东APP的下拉刷新动态效果.在这里和大家分享一下具体的思路和需要注意的地方,以便帮助有类似开发和 ...
- 高仿IOS下拉刷新的粘虫效果
最近看需要做一款下拉刷新的效果,由于需要和Ios界面保持一致,所以这用安卓的方式实现了ios下的下拉刷新的粘虫效果. 最新的安卓手机版本的QQ也有这种类似的效果,就是拖动未读信息的那个红色圆圈,拖动近 ...
- vue实现网络图片瀑布流 + 下拉刷新 + 上拉加载更多
一.思路分析和效果图 用vue来实现一个瀑布流效果,加载网络图片,同时有下拉刷新和上拉加载更多功能效果.然后针对这几个效果的实现,捋下思路: 根据加载数据的顺序,依次追加标签展示效果: 选择哪种方式实 ...
- Android自定义控件之仿美团下拉刷新
美团的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull to refresh),在这个状态下是一个绿色的椭圆随着下拉的距离动态改变其大小. 第二个部分为放开刷新状态(release to r ...
- IOS怎么实现一个UITableView的下拉刷新
採用的EGORefreshTableHeaderView来实现: 在Controller上实现EGORefreshTableHeaderDelegate的delegate @property(nona ...
- 打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)
前言 近期在做项目时,使用了一个开源的下拉刷新ListView组件.极其的不稳定,bug还多.稳定的组件又写得太复杂了,jar包较大.在我的一篇博客中也讲述过下拉刷新的实现,即Android打造(Li ...
- Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件
前言: 忙完了结婚乐APP的开发,终于可以花一定的时间放在博客上了.好了,废话不多说,今天我们要带来的效果是苹果版本的QQ下拉刷新.首先看一下目标效果以及demo效果: 因为此效果实现的步骤 ...
- 如何写一套下拉刷新的控件?《MJRefresh原理浅析》(附Demo下载地址)
相信大家有很多人在做项目的时候都在使用MJRefresh 控件来实现下拉刷新的功能: MJRefresh经过不断的重构与更新迭代,现在不管是功能上还是代码结构上都是相当不错的,都是很值我们去学习的. ...
随机推荐
- Linux - APT包管理
dpkg与apt dpkg用来安装本地deb格式软件包,但不会解决软件包的依赖关系. APT(Advanced Packaging Tool)是从更新源获取并安装软件包,而且会解决依赖关系, 但不会安 ...
- 7-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(TCP实现HTTP访问下载文件,明白底层如何实现的,地基稳才踏实)
看了好多文章.....唉,还是自己亲自动手用网络监控软件测试吧 先看这个节安装WEB服务器.....安装好以后就可以用HTTP访问电脑文件了 6-STM32物联网开发WIFI(ESP8266)+GPR ...
- ubuntu升级pip后, ImportError: cannot import name ‘main‘
场景描述: 原先pip安装完成之后,一直没有更新版本,原pip版本为8.1.1,今天安装python 包pysftp的时候,提示需要升级pip到(pip 10.0.1); 于是乎,直接手到擒来,终端命 ...
- 一口一口吃掉Hexo(五)
如果你想得到更好的阅读效果,请访问我的个人网站 ,版权所有,未经许可不得转载! 通过前四节的内容,相信你已经能够在你的虚拟主机上成功部署网站,并且能够通过你自己的域名访问你的网站了,接下来要做的就是日 ...
- sql server 2008 R2
SQL SERVER 2008 R2序列号: 数据中心版:PTTFM-X467G-P7RH2-3Q6CG-4DMYB 开 发者 版:MC46H-JQR3C-2JRHY-XYRKY-QWPVM 企 ...
- Python学习--11 面向对象高级编程
多重继承 Python里允许多重继承,即一个类可以同时继承多个类: class Mammal(Animal): pass class Runnable(object): def run(self): ...
- CentOS7 下安装 iSCSI Target(tgt) ,使用 Ceph rbd
目录 一.iSCSI 介绍 1. iSCSI 定义 2. 几种常见的 iSCSI Target 3. 优缺点比较 二.安装步骤 1. 关闭防火墙 2. 关闭selinux 3. 通过 yum 安装 t ...
- JavaScript事件-this传递
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- Async异步编程入门示例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 简易的命令行聊天室程序(Winsock,服务器&客户端)
代码中使用WinSock2函数库,设计并实现了简单的聊天室功能.该程序为命令行程序.对于服务器和客户端,需要: 服务器:创建监听套接字,并按本地主机绑定:主线程监听并接受来自客户端的请求,并为该客户端 ...