Vue封装下拉刷新组件
时间: 2023-08-30 07:06:10 浏览: 113
下拉刷新是移动端 APP 中常见的交互方式,可以提高用户体验,因此我们可以将其封装成一个组件,方便在多个页面中复用。下面是一个简单的 Vue 下拉刷新组件的实现:
```html
<template>
<div class="pull-refresh-wrapper">
<div class="pull-refresh-status" :class="{'loading': isLoading}">
<div class="pull-refresh-icon"></div>
<div class="pull-refresh-text">{{ text }}</div>
</div>
<div class="pull-refresh-content" ref="content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
threshold: {
type: Number,
default: 80
},
text: {
type: String,
default: '下拉刷新'
}
},
data() {
return {
startY: 0,
isLoading: false,
isDragging: false
};
},
mounted() {
this.$refs.content.addEventListener('touchstart', this.handleTouchStart);
this.$refs.content.addEventListener('touchmove', this.handleTouchMove);
this.$refs.content.addEventListener('touchend', this.handleTouchEnd);
},
beforeDestroy() {
this.$refs.content.removeEventListener('touchstart', this.handleTouchStart);
this.$refs.content.removeEventListener('touchmove', this.handleTouchMove);
this.$refs.content.removeEventListener('touchend', this.handleTouchEnd);
},
methods: {
handleTouchStart(e) {
this.startY = e.touches[0].clientY;
},
handleTouchMove(e) {
if (this.isLoading) {
return;
}
const currentY = e.touches[0].clientY;
const distance = currentY - this.startY;
if (distance > 0 && this.$refs.content.scrollTop === 0) {
this.isDragging = true;
e.preventDefault();
if (distance >= this.threshold) {
this.text = '松开刷新';
} else {
this.text = '下拉刷新';
}
} else {
this.isDragging = false;
}
},
handleTouchEnd() {
if (this.isLoading || !this.isDragging) {
return;
}
if (this.text === '松开刷新') {
this.isLoading = true;
this.text = '正在刷新';
this.$emit('refresh', () => {
this.isLoading = false;
this.text = '下拉刷新';
});
} else {
this.text = '下拉刷新';
}
this.isDragging = false;
}
}
};
</script>
<style>
.pull-refresh-wrapper {
height: 100%;
overflow: hidden;
}
.pull-refresh-status {
height: 80px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
}
.pull-refresh-icon {
width: 16px;
height: 16px;
margin-right: 8px;
border-radius: 50%;
border: 2px solid #666;
border-top-color: transparent;
animation: spin 0.6s linear infinite;
}
.pull-refresh-text {
white-space: nowrap;
}
.pull-refresh-content {
height: calc(100% - 80px);
overflow-y: auto;
}
.loading .pull-refresh-icon {
border-color: #42b983;
border-top-color: transparent;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
```
在上面的代码中,我们使用了 touch 事件来实现下拉刷新。当用户下拉到一定程度时,组件会触发 refresh 事件,我们可以在该事件中进行数据的异步请求。在请求完成后,将 isLoading 设为 false 即可停止 loading 状态。
另外,我们使用了 slot 来插入需要刷新的内容,并监听了 touchstart、touchmove 和 touchend 事件来处理下拉刷新的逻辑。其中,handleTouchMove 方法用于判断下拉距离是否达到阈值,并改变刷新文本的内容;handleTouchEnd 方法用于处理下拉刷新的触发事件,如果下拉距离达到阈值,则触发 refresh 事件,并将 isLoading 设为 true,同时改变刷新文本的内容为“正在刷新”。在事件处理函数中,我们使用了箭头函数来确保 this 指向正确。
阅读全文