如果你用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>

核心思路及步骤

  1. document绑定touch事件
document.addEventListener('touchstart',this.touchStart,false);
document.addEventListener('touchmove',this.touchMove,false);
document.body.addEventListener('touchend',this.touchEnd,false);
  1. 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;
} }
  1. 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)`;
}
}
  1. 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下拉刷新的组件的更多相关文章

  1. 用vue写一个仿简书的轮播图

    原文地址:用vue写一个仿简书的轮播图 先展示最终效果: Vue的理念是以数据驱动视图,所以拒绝通过改变元素的margin-top来实现滚动效果.写好css样式,只需改变每张图片的class即可实现轮 ...

  2. 基于PtrFrameLayout实现自定义仿京东下拉刷新控件

    前言 最近基于项目需要,使用PtrFrameLayout框架实现了自定义的下拉刷新控件,大体效果类似于京东APP的下拉刷新动态效果.在这里和大家分享一下具体的思路和需要注意的地方,以便帮助有类似开发和 ...

  3. 高仿IOS下拉刷新的粘虫效果

    最近看需要做一款下拉刷新的效果,由于需要和Ios界面保持一致,所以这用安卓的方式实现了ios下的下拉刷新的粘虫效果. 最新的安卓手机版本的QQ也有这种类似的效果,就是拖动未读信息的那个红色圆圈,拖动近 ...

  4. vue实现网络图片瀑布流 + 下拉刷新 + 上拉加载更多

    一.思路分析和效果图 用vue来实现一个瀑布流效果,加载网络图片,同时有下拉刷新和上拉加载更多功能效果.然后针对这几个效果的实现,捋下思路: 根据加载数据的顺序,依次追加标签展示效果: 选择哪种方式实 ...

  5. Android自定义控件之仿美团下拉刷新

    美团的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull to refresh),在这个状态下是一个绿色的椭圆随着下拉的距离动态改变其大小. 第二个部分为放开刷新状态(release to r ...

  6. IOS怎么实现一个UITableView的下拉刷新

    採用的EGORefreshTableHeaderView来实现: 在Controller上实现EGORefreshTableHeaderDelegate的delegate @property(nona ...

  7. 打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)

    前言 近期在做项目时,使用了一个开源的下拉刷新ListView组件.极其的不稳定,bug还多.稳定的组件又写得太复杂了,jar包较大.在我的一篇博客中也讲述过下拉刷新的实现,即Android打造(Li ...

  8. Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件

    前言: 忙完了结婚乐APP的开发,终于可以花一定的时间放在博客上了.好了,废话不多说,今天我们要带来的效果是苹果版本的QQ下拉刷新.首先看一下目标效果以及demo效果:      因为此效果实现的步骤 ...

  9. 如何写一套下拉刷新的控件?《MJRefresh原理浅析》(附Demo下载地址)

    相信大家有很多人在做项目的时候都在使用MJRefresh 控件来实现下拉刷新的功能: MJRefresh经过不断的重构与更新迭代,现在不管是功能上还是代码结构上都是相当不错的,都是很值我们去学习的. ...

随机推荐

  1. vue项目常见需求(项目实战笔记)

    一.起步 1.引入reset.css解决手机之间不同分辨率的问题(reset.css为别人封装的css文件) import './assets/styles/reset.css' 使用方式 1rem= ...

  2. Win7删除网络位置那些不用的网络位置(驱动器)

    1.初始状态: 映射成功的网络位置如下图 2.要删除这个网络位置:点击"打开网络和共享中心",然后如下图设置: 3.重启电脑之后,删除的"网络位置"不会在资源管 ...

  3. (转)Db2 数据库性能优化中,十个共性问题及难点的处理经验

    (转)https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid=2650629396&idx=1&sn=3ec17927b3d ...

  4. Mac 下安装.NET Core 与 CLI

    .NET Foundation:https://github.com/dotnet/home .NET Core:https://github.com/dotnet/coreclr CLI:https ...

  5. docker 非root用户修改mount到容器的文件出现“Operation not permitted

    使用环境centos7 x86-64 内核版本4.19.9 docker使用非root用户启动,daemon.json配置文件内容如下: # cat daemon.json { "usern ...

  6. find_package()的查找*.cmake的顺序

    1. find_package(<Name>)命令首先会在模块路径中寻找 Find<name>.cmake,这是查找库的一个典型方式.具体查找路径依次为CMake: 变量${C ...

  7. Nginx缓存配置

    访问我的博客 前言 本文介绍利用 nginx 的 nginx_ngx_cache_purge 模块来实现缓存功能,前几篇文章介绍了 Nginx 的动静分离以及 CDN 技术,在其基础上,再对整个页面进 ...

  8. redis学习(五) redis过期时间

    redis过期时间 1.redis过期时间介绍 有时候我们并不希望redis的key一直存在.例如缓存,验证码等数据,我们希望它们能在一定时间内自动的被销毁.redis提供了一些命令,能够让我们对ke ...

  9. JGraphT

    例1: 添加点.边 import java.net.*; import org.jgrapht.*; import org.jgrapht.graph.*; /** * A simple introd ...

  10. 你的网站升级https了吗

    升级 HTTPS,价值何在? HTTPS 实质上是一种面向安全信息通信的协议.从最终的数据解析的角度上看,HTTPS 与 HTTP 没有本质上的区别.对于接收端而言,SSL/TSL 将接收的数据包解密 ...