uview-next
Version:
基于uView UI 2.0,110+高质量组件库,支持vue2和vue3,支持鸿蒙,支持多语言,搭配便捷工具助力,让开发更得心应手
148 lines (124 loc) • 4.02 kB
JavaScript
// 下拉刷新 mixin
export default {
data() {
return {
// 触摸相关状态
startY: 0,
startTime: 0,
isDragging: false,
lastMoveY: 0,
dragDistance: 0,
velocity: 0,
isTouchStarted: false,
}
},
methods: {
// 触摸开始
touchStartHandler(e) {
if (!this.refresherEnabled) return;
const touch = e.touches[0];
// 重置状态
this.startY = touch.pageY;
this.startTime = Date.now();
this.isDragging = false;
this.dragDistance = 0;
this.velocity = 0;
this.lastMoveY = touch.pageY;
this.isTouchStarted = true;
if (this.curReadyRefresh && this.refreshStatus !== 3) {
this.updateContainerStyle('translateY(0px)', '0s');
}
},
// 触摸移动
touchMoveHandler(e) {
if (!this.isTouchStarted || !this.refresherEnabled ||
!this.curReadyRefresh || this.refreshStatus === 3) return;
const touch = e.touches[0];
const currentY = touch.pageY;
const diffY = currentY - this.startY;
if (diffY <= 0) return;
// 计算拖拽距离和速度
this.dragDistance = diffY;
this.velocity = (currentY - this.lastMoveY) / (Date.now() - this.startTime);
this.lastMoveY = currentY;
this.isDragging = true;
// 应用阻力效果
const resistedDistance = this.calculateResistance(diffY, 150);
const displayDistance = resistedDistance * 0.6;
// 更新状态
if (displayDistance > 10) {
if (!this.readyRefresh) {
this.setReadyRefresh({ readyRefresh: true });
this.readyRefresh = true;
}
if (!this.refreshShow) {
this.setRefreshShow({ refreshShow: true });
this.refreshShow = true;
}
}
// 设置变换
this.updateContainerStyle('translateY(' + displayDistance + 'px)', '0s');
// 更新刷新状态
const newStatus = displayDistance >= this.refresherThreshold ? 2 : 1;
if (this.refreshStatus !== newStatus) {
this.setRefreshStatus(newStatus);
}
},
// 触摸结束
touchEndHandler(e) {
if (!this.refresherEnabled || !this.curReadyRefresh || !this.isDragging) return;
// 重置拖拽状态
this.isDragging = false;
this.setReadyRefresh({ readyRefresh: false });
this.readyRefresh = false;
// 判断是否应该刷新
const shouldRefresh = this.refreshStatus === 2 ||
(Math.abs(this.velocity) > 0.5 && this.dragDistance > 10);
if (shouldRefresh) {
// 触发刷新
this.setRefreshStatus(3);
// 动画到刷新位置
this.updateContainerStyle('translateY(' + this.refresherThreshold + 'px)', '0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)');
} else {
// 回弹动画
this.updateContainerStyle('translateY(0px)', '0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94)');
// 隐藏刷新指示器
this.setRefreshShow({ refreshShow: false });
this.refreshShow = false;
}
// 重置拖拽相关状态
this.dragDistance = 0;
this.velocity = 0;
this.isTouchStarted = false;
},
// 更新容器样式
updateContainerStyle(transform, transition) {
const container = this.$refs['refresh-container'];
if (container) {
container.style.transform = transform;
container.style.transition = transition;
}
},
// 计算阻力效果
calculateResistance(distance, maxDistance) {
if (distance <= maxDistance) {
return distance;
}
return maxDistance + (distance - maxDistance) * 0.6;
},
// 重置拖拽状态
resetDragState() {
this.refreshShow = false;
this.readyRefresh = false;
this.isDragging = false;
this.dragDistance = 0;
this.velocity = 0;
this.isTouchStarted = false;
},
// 重置容器位置
resetContainerPosition(useEasing = true) {
const transition = useEasing ? '0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)' : '0.3s ease-out';
this.updateContainerStyle('translateY(0px)', transition);
}
}
};