Vue H5(手写)实现下拉刷新
当我们在做移动端的时候 ,经常会遇到订单列表或者首页,经常会遇到下拉刷新 ,但是我经常用到 Vant 组件库中的下拉刷新 ,但是Vant 中的下拉刷新 会有一些问题 就是刷新的时候,在将页面象上滑动 ,就会出现卡顿的状态 ,这样就会导致用户体验非常不好 ,偶然看到一个博主写的一篇文章 还挺好用的 我就拿来试一试 真的还可以
1. 首先 我们在 components 下创建一个 pullRefresh.vue 公共文件
<template><divclass="weui-pull-refresh"ref="scrollBox":style="style"@touchstart="touchStart"@touchmove="touchMove"@touchend="touchEnd"><div class="weui-pull-refreshing-box"><div v-if="moveState < 2">{{ moveState === 0 ? "下拉即可刷新..." : "释放即可刷新..." }}</div><div v-else><i class="weui-loading" /> 加载中...</div></div><div class="weui-pull-present-box"><slot /></div></div>
</template><script>
export default {name: "pull-refresh",data() {return {startY: "", //保存touch时的Y坐标moveDistance: 0, //保存向下滑动的距离moveState: 0, //开始滑动到结束后状态的变化 0:下拉即可刷新 1:释放即可刷新 2:加载中duration: 0, //动画持续时间,0就是没有动画};},computed: {style() {return {transition: `${this.duration}ms`,transform: `translate3d(0,${this.moveDistance}px, 0)`,};},},methods: {touchStart(e) {this.duration = 0; // 关闭动画this.moveDistance = 0; // 滑动距离归0this.startY = e.targetTouches[0].clientY; // 获得开始Y坐标},touchMove(e) {//这里是整个下拉刷新的核心let scrollTop =document.documentElement.scrollTop || document.body.scrollTop;//首先判断我们有没有滚动条,如果有,我们下拉刷新就不能启用。if (scrollTop > 0) return;let move = e.targetTouches[0].clientY - this.startY;//判断手指滑动的距离,只有为正数才代表用户下拉了。if (move > 0) {//阻止默认事件,在微信浏览器中尤为有用,至于为什么,你去试就知道了。e.preventDefault();//增加滑动阻力的感觉this.moveDistance = Math.pow(move, 0.8);if (this.moveDistance > 50) {//如果滑动距离大于50 那我就告诉你,释放即可刷新if (this.moveState === 1) return;this.moveState = 1;} else {//否则 恢复原样if (this.moveState === 0) return;this.moveState = 0;}}},touchEnd(e) {// 只要手指拿开,我都需要加上结束时的动画,这里为300msthis.duration = 300;if (this.moveDistance > 50) {//这里逻辑跟touchMove一样,但是需要真的加载数据了,那moveState变为2 所以加载动画在这出现this.moveState = 2;//因为还没加载完,我得让加载动画显示着,所以这里移动距离为50this.moveDistance = 50;this.$emit("refresh", () => {//这里就是成功后的回调了,如果该函数被调用,那就以为着加载数据完成,所以状态要回到0,当然需要在父组件调用。this.moveState = 0;});} else {//否则 给我老老实实恢复原样this.moveDistance = 0;}},},watch: {//这里是给用户操作返回的核心moveState(state) {//我们监听moveState的状态,//0意味着开始也意味着结束,这里是结束,并且只有动画生效我们才能 moveDistance 设为0,//为什么动画生效才行,因为动画生效意味着手指离开了屏幕,如果不懂去看touchEnd方法,这时//我们让距离变为0才会有动画效果。if (state === 0 && this.duration === 300) {this.moveDistance = 0;}},},
};
</script>
<!-- css我就不讲了,你肯定比我厉害 -->
<style scoped lang="scss">
.weui-pull-refresh {display: flex;height: calc(100vh - 5px);flex-direction: column;margin-top: -50px;.weui-pull-refreshing-box {line-height: 50px;height: 50px;font-size: 14px;color: rgba(69, 90, 100, 0.6);text-align: center;margin-bottom: 20px;}.weui-pull-present-box {background-color: lighten(#fff, 10%);}
}
</style>
2. 我们在 main.js 中 进行全局的注册和引入 这样就不会在 每个页面中 都要引入了
import pullRefresh from '@/components/pullRefresh'
Vue.component('pull-refresh',pullRefresh)
3. 我们创建一个 Scroll.vue 文件夹
<template><pull-refresh @refresh="refresh"><div class="content"><p class="text">基础用法</p>刷新次数:{{ num }}</div></pull-refresh>
</template><script>
export default {data() {return {num: 0,};},methods: {refresh(done) {setTimeout(() => {this.num++;done(); //我就想说这里,把状态归0}, 500);},},
};
</script><style scoped lang="scss">
.content {padding: 0 15px;.text {font-size: 14px;color: rgba(69, 90, 100, 0.6);}
}
</style>
这样就可以实现下拉刷新了