vue实现下拉刷新
Vue 实现下拉刷新功能
使用第三方库(推荐)
安装 vue-pull-refresh 库:
npm install vue-pull-refresh --save
在组件中引入并使用:
<template>
<pull-to-refresh
:top-load-method="refreshData"
@top-state-change="stateChange"
>
<!-- 你的列表内容 -->
<div v-for="item in list" :key="item.id">{{ item.text }}</div>
</pull-to-refresh>
</template>
<script>
import PullToRefresh from 'vue-pull-refresh'
export default {
components: {
PullToRefresh
},
data() {
return {
list: []
}
},
methods: {
refreshData(loaded) {
// 模拟异步请求
setTimeout(() => {
// 更新数据
this.list = [...newData]
// 调用loaded表示加载完成
loaded('done')
}, 1000)
},
stateChange(state) {
console.log('当前状态:', state)
}
}
}
</script>
原生实现方案
监听 touch 事件实现基础下拉刷新:
<template>
<div
class="pull-refresh"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<div class="refresh-tip" :style="{ height: pullHeight + 'px' }">
{{ refreshText }}
</div>
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
startY: 0,
currentY: 0,
pullHeight: 0,
isRefreshing: false,
maxPullHeight: 100
}
},
computed: {
refreshText() {
if (this.isRefreshing) return '加载中...'
return this.pullHeight > 50 ? '释放刷新' : '下拉刷新'
}
},
methods: {
handleTouchStart(e) {
this.startY = e.touches[0].pageY
},
handleTouchMove(e) {
if (this.isRefreshing) return
this.currentY = e.touches[0].pageY
const distance = this.currentY - this.startY
if (distance > 0 && window.scrollY <= 0) {
e.preventDefault()
this.pullHeight = Math.min(distance, this.maxPullHeight)
}
},
handleTouchEnd() {
if (this.isRefreshing) return
if (this.pullHeight > 50) {
this.isRefreshing = true
this.$emit('refresh', () => {
this.isRefreshing = false
this.pullHeight = 0
})
} else {
this.pullHeight = 0
}
}
}
}
</script>
<style>
.pull-refresh {
position: relative;
}
.refresh-tip {
position: absolute;
width: 100%;
top: -100px;
display: flex;
justify-content: center;
align-items: flex-end;
}
</style>
结合 better-scroll 实现
安装 better-scroll:
npm install better-scroll --save
实现代码:
<template>
<div ref="wrapper" class="wrapper">
<div class="pull-down-refresh">
<div class="refresh-tip">
{{ pullDownRefreshText }}
</div>
<slot></slot>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
data() {
return {
scroll: null,
pullDownRefreshText: '下拉刷新'
}
},
mounted() {
this.initScroll()
},
methods: {
initScroll() {
this.scroll = new BScroll(this.$refs.wrapper, {
pullDownRefresh: {
threshold: 50,
stop: 40
},
click: true
})
this.scroll.on('pullingDown', () => {
this.pullDownRefreshText = '正在刷新...'
this.$emit('refresh', () => {
this.finishPullDown()
})
})
this.scroll.on('scroll', (pos) => {
if (pos.y > 50) {
this.pullDownRefreshText = '释放刷新'
} else {
this.pullDownRefreshText = '下拉刷新'
}
})
},
finishPullDown() {
this.scroll.finishPullDown()
this.scroll.refresh()
this.pullDownRefreshText = '下拉刷新'
}
}
}
</script>
注意事项
- 移动端需要添加 touch 事件监听
- 下拉刷新时应该阻止页面默认滚动行为
- 刷新完成后需要重置状态
- 性能优化:使用 requestAnimationFrame 优化滚动效果
- 在组件销毁时移除事件监听







