vue下拉刷新实现
Vue 下拉刷新实现方法
使用第三方库(推荐)
安装 vue-pull-refresh 或 mescroll.js 等专门为 Vue 设计的插件,这些库提供开箱即用的下拉刷新功能,支持自定义样式和回调函数。
// 以 vue-pull-refresh 为例
npm install vue-pull-refresh --save
// 组件中使用
<template>
<pull-refresh :on-refresh="onRefresh">
<!-- 列表内容 -->
</pull-refresh>
</template>
<script>
import PullRefresh from 'vue-pull-refresh';
export default {
components: { PullRefresh },
methods: {
onRefresh() {
return new Promise((resolve) => {
setTimeout(() => {
// 刷新数据逻辑
resolve();
}, 1000);
});
}
}
}
</script>
原生实现方案
通过监听 touchstart、touchmove 和 touchend 事件手动计算滑动距离,结合 CSS 过渡动画实现效果。
<template>
<div class="refresh-container" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
<div class="refresh-control" :style="{ transform: `translateY(${offsetY}px)` }">
<span v-if="!isLoading">下拉刷新</span>
<span v-else>加载中...</span>
</div>
<div class="content">
<!-- 列表内容 -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
startY: 0,
offsetY: 0,
isLoading: false
};
},
methods: {
touchStart(e) {
this.startY = e.touches[0].pageY;
},
touchMove(e) {
const moveY = e.touches[0].pageY - this.startY;
if (moveY > 0 && window.scrollY <= 0) {
this.offsetY = Math.min(moveY, 100);
e.preventDefault();
}
},
touchEnd() {
if (this.offsetY > 60 && !this.isLoading) {
this.isLoading = true;
this.onRefresh().finally(() => {
this.isLoading = false;
this.offsetY = 0;
});
} else {
this.offsetY = 0;
}
},
onRefresh() {
return new Promise(resolve => {
// 模拟异步请求
setTimeout(resolve, 1500);
});
}
}
}
</script>
<style>
.refresh-container {
position: relative;
overflow: hidden;
}
.refresh-control {
position: absolute;
width: 100%;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
transition: transform 0.3s;
}
</style>
结合 Better-Scroll 实现
Better-Scroll 提供更流畅的滚动体验,内置下拉刷新功能。

npm install better-scroll --save
// 组件中使用
<template>
<div ref="wrapper" class="wrapper">
<div class="content">
<div class="refresh-tip">{{ refreshText }}</div>
<!-- 列表内容 -->
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll';
export default {
data() {
return {
scroll: null,
refreshText: '下拉刷新'
};
},
mounted() {
this.initScroll();
},
methods: {
initScroll() {
this.scroll = new BScroll(this.$refs.wrapper, {
pullDownRefresh: {
threshold: 50,
stop: 40
},
click: true
});
this.scroll.on('pullingDown', () => {
this.refreshText = '释放刷新';
});
this.scroll.on('scroll', (pos) => {
if (pos.y > 50) {
this.refreshText = '下拉刷新';
}
});
this.scroll.on('scrollEnd', () => {
if (this.scroll.y <= -50 && this.refreshText === '释放刷新') {
this.refreshData();
}
});
},
refreshData() {
this.refreshText = '加载中...';
setTimeout(() => {
// 数据更新逻辑
this.scroll.finishPullDown();
this.refreshText = '下拉刷新';
}, 1500);
}
}
}
</script>
注意事项
- 移动端需要添加
touch-action: none防止浏览器默认行为冲突 - 下拉距离阈值建议设置为 60-100px 触发刷新
- 加载中状态需显示明确反馈(如旋转图标)
- 在
onRefresh完成后必须调用恢复方法(如resolve()或finishPullDown())






