用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经过不断的重构与更新迭代,现在不管是功能上还是代码结构上都是相当不错的,都是很值我们去学习的. ...
随机推荐
- CentOS7安装MYSQL。
参考这个文章(网页已存到本地):http://www.cnblogs.com/starof/p/4680083.html 安装完成后,本地登录MYSQL没有问题. 现在主要是在windows下用ora ...
- Shell - 简明Shell入门12 - 定制输出(ColorOutput)
示例脚本及注释 #!/bin/bash echo -e "\033[32m" # 设置输出属性,绿色字体 echo "This is a test!" echo ...
- 条件变量 sync.Cond
sync.Cond 条件变量是基于互斥锁的,它必须有互斥锁的支撑才能发挥作用. sync.Cond 条件变量用来协调想要访问共享资源的那些线程,当共享资源的状态发生变化的时候,它可以用来通知被互斥锁阻 ...
- [原创]Base32加密解密工具
工具: Base32_Decode编译: VS2012 C# (.NET Framework v2.0)组织: K8搞基大队[K8team]作者: K8拉登哥哥博客: http://qqhack8. ...
- 改变IIS的Framework版本
Changing the Framework version requires a restart of the W3SVC service. Alternatively, you can chang ...
- Android:一个高效的UI才是一个拉风的UI(二)
趁今晚老大不在偷偷早下班,所以有时间继续跟大伙扯扯UI设计之痛,也算一个是对上篇<Android:一个高效的UI才是一个拉风的UI(一)>的完整补充吧.写得不好的话大家尽管拍砖~(来!砸死 ...
- 在vue中使用vuex 一个简单的实例
1.安装vuex:npm install vuex --save 2.在main.js文件中引入vuex (请忽略其它代码) 3.建一个vuex文件夹,然后在建一个store.js(这两个文件名字可以 ...
- es-08-hadoop集成
1, 版本匹配: https://www.elastic.co/guide/en/elasticsearch/hadoop/current/requirements.html 2, maven集成: ...
- 解析Resources.arsc
一.前言 对于APK里面的Resources.arsc文件大家应该都知道是干什么的(不知道的请看我的另一篇文章Android应用程序资源文件的编译和打包原理),它实际上就是App的资源索引表.下面我会 ...
- elasticSearch6源码分析(12)DiscoveryModule
1.DiscoveryModule概述 /** * A module for loading classes for node discovery. */ 2.discovery The discov ...