<template>
<view>
<movable-area
style="width: 100%;height: 100%;"
:style="{ height: scrollHeight + 50 + 'px' }"
>
<view
class="display_flex_center"
style="height: 40px; font-size: 15px; color: #6b6a6a"
>
<view v-if="refreshSuccess">
{{ refreshSuccessText }}
</view>
<block v-else>
<view v-if="!refreshing" class="refresh-icon display_flex_center" :class="{ 'refresh-icon-active': refreshFlag }" >↓ </view>
<view v-if="!refreshing">{{
refreshFlag ? refreshReady : refreshText
}}</view>
<view v-else class="display_flex_center">
<image src="https://caishentongweb.oss-cn-hangzhou.aliyuncs.com/mp-weixin/loading.gif" class="loading_img"></image>
<text>{{ refreshingText }}</text>
</view>
</block>
</view>
<movable-view
:x="x"
:y="y"
:direction="isRefresh ? 'vertical' : 'none'"
:out-of-bounds="false"
style="width: 100%"
:style="{ height: scrollHeight + 'px' }"
@change="onChange"
@touchend="touchend"
>
<view :style="{ height: scrollHeight + 'px' }">
<scroll-view
:scroll-y="scrollStatus"
:style="{
height: scrollHeight + 'px',
background: backgroundColor,
}"
:scroll-into-view="top_viewId"
:upper-threshold="10"
@scroll="onScroll"
@scrolltoupper="scrollToTop"
@scrolltolower="loadMore"
>
<view id="top_view" @touchstart="touchstart" @touchmove="touchMove">
<slot></slot>
</view>
<view
class="display_flex_center"
style="height: 40px; font-size: 15px; color: #999"
>
<block v-if="noMore">
{{ noMoreText }}
</block>
<block v-else-if="isLoading != 2">
{{ loadingMoreText }}
</block>
<block v-else>
{{ loadingText }}
</block>
</view>
<view
v-if="showGoTop && scrollTop > scrollHeight"
class="go_top_icon_back"
@click.stop="goTop"
>
<image src="https://caishentongweb.oss-cn-hangzhou.aliyuncs.com/mp-weixin/go_top.png" class="top_icon"></image>
</view>
</scroll-view>
</view>
</movable-view>
</movable-area>
</view>
</template>
<script>
export default {
name: "zyq-movableRefresh",
props: {
isRefresh: {
type: Boolean,
default: true,
},
scrollHeight: {
type: Number,
default: 300,
},
refreshText: {
type: String,
default: "下拉可以刷新",
},
refreshReady: {
type: String,
default: "释放立即刷新",
},
refreshingText: {
type: String,
default: "正在刷新...",
},
refreshSuccessText: {
type: String,
default: "刷新完成",
},
loadingMoreText: {
type: String,
default: "上拉加载更多",
},
loadingText: {
type: String,
default: "正在加载...",
},
noMoreText: {
type: String,
default: "已经到底了~",
},
pullHeight: {
type: Number,
default: 40,
},
noMore: {
type: Boolean,
default: false,
},
backgroundColor: {
type: String,
default: "#eee",
},
showGoTop: {
type: Boolean,
default: false,
},
},
data() {
return {
x: 50,
y: 0,
old: {
x: 0,
y: 0,
},
refreshFlag: false,
refreshing: false,
scrollStatus: true,
isLoading: 0, //加载状态,1:正在下拉刷新,2:正在触底加载
refreshSuccess: false,
scrollTop: 0,
startX: 0,
startY: 0,
inTop: true,
moveHeight: 0, //下拉刷新移动距离
showLoadingMore: false,
top_viewId: "",
};
},
methods: {
onChange(e) {
let y = e.detail.y;
this.old.x = e.detail.x;
this.old.y = y;
this.moveHeight = y;
if (y < this.pullHeight) {
this.refreshFlag = false;
} else {
this.refreshFlag = true;
}
},
touchstart(e) {
let obj = e.changedTouches[0];
this.startX = obj.pageX;
this.startY = obj.pageY;
},
touchMove(e) {
if (!this.isRefresh) {
return;
}
this.refreshSuccess = false;
let obj = e.changedTouches[0];
let endX = obj.pageX;
let endY = obj.pageY;
let distanceX = endX - this.startX;
let distanceY = endY - this.startY;
if (
(this.inTop || this.scrollTop == 0) &&
Math.abs(distanceX) < Math.abs(distanceY) &&
distanceY > 0
) {
this.scrollStatus = false;
}
},
touchend(e) {
let that = this;
let moveHeight = this.moveHeight;
if (moveHeight < this.pullHeight) {
this.x = this.old.x;
this.y = this.old.y;
this.$nextTick(function () {
this.x = 0;
this.y = 0;
});
this.refreshFlag = false;
this.refreshing = false;
} else {
this.refreshing = true;
this.refreshFlag = true;
this.refresh();
}
this.scrollStatus = true;
},
scrollToTop(e) {
if (this.scrollTop < 5) {
this.inTop = true;
}
},
onScroll(e) {
let scrollTop = e.detail.scrollTop;
this.scrollTop = scrollTop;
this.$emit("onScroll", scrollTop);
if (scrollTop > 3) {
this.inTop = false;
} else {
this.inTop = true;
}
},
goTop() {
this.top_viewId = "";
this.$nextTick(function () {
this.top_viewId = "top_view";
});
},
runRefresh(callback = false) {
let that = this;
this.x = this.old.x;
this.y = this.old.y;
this.$nextTick(function () {
this.scrollTop = 0;
this.x = that.pullHeight;
this.y = that.pullHeight;
that.refreshing = true;
that.refreshFlag = true;
that.refresh();
});
},
refresh() {
if (this.isLoading) {
return;
}
this.isLoading = 1;
this.$emit("refresh");
},
loadMore() {
if (this.noMore || this.isLoading) {
return;
}
this.isLoading = 2;
this.$emit("loadMore");
},
endLoad() {
let that = this;
this.refreshSuccess = true;
setTimeout(function () {
that.refreshSuccess = false;
}, 800);
this.x = this.old.x;
this.y = this.old.y;
this.$nextTick(function () {
this.x = 0;
this.y = 0;
});
this.scrollStatus = true;
this.refreshing = false;
this.refreshFlag = false;
this.isLoading = 0;
},
},
};
</script>
<style>
.display_flex_center {
display: flex;
justify-content: center;
align-items: center;
}
.refresh-icon {
width: 20px;
height: 20px;
font-weight: 700;
transition-duration: 0.5s;
transition-property: transform;
transform: rotate(0deg);
}
.refresh-icon-active {
transform: rotate(180deg);
}
.loading_img {
width: 20px;
height: 20px;
margin-right: 5px;
}
.go_top_icon_back {
position: fixed;
right: 40px;
bottom: 40px;
height: 40px;
width: 40px;
border-radius: 50%;
background: #f5f7fa;
display: flex;
justify-content: center;
align-items: center;
}
.top_icon {
height: 30px;
width: 30px;
}
</style>
使用--------------------------------------------
<template>
<view class="content">
<movable-refresh
ref="movableRefresh"
:scrollHeight="scrollHeight"
:showGoTop="false"
:noMore="noMore"
:isRefresh="true"
@refresh="refresh"
@loadMore="loadMore"
backgroundColor="#F5F7FA"
>
<view
class="list-item display justify-content align-items"
v-for="(item, index) in list"
:key="index"
>
<view class="list-item-left">
<image
:src="Notify"
class="list-item-img"
:class="item.isRead ? 'read' : ''"
/>
</view>
<view class="list-item-right">
<view class="list-item-right-top display justify-content align-items">
<view class="list-item-right-title"
>{{ item.title }}{{ index }}</view
>
<view class="list-item-right-time">{{ getTimer(item.time) }}</view>
</view>
<view class="list-item-right-bottom">
<view class="list-item-right-content">{{ item.content }}</view>
</view>
</view>
</view>
</movable-refresh>
</view>
</template>
<script>
import { getTimer } from "@/utils/getTimer.js";
import movableRefresh from "@/components/zyq-movableRefresh/zyq-movableRefresh.vue";
export default {
components: {
movableRefresh,
},
data() {
return {
getTimer,
Notify:
"https://caishentongweb.oss-cn-hangzhou.aliyuncs.com/mp-weixin/messageNotify.png",
scrollHeight: 100,
total: 30,
noMore: false,
list: [
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
],
list1: [
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
{
id: 1,
title: "休假申请",
content: "您有一条休假申请待处理",
time: "2022-10-10 10:10:10",
isRead: false,
},
],
};
},
onLoad() {
let system = uni.getSystemInfoSync();
this.scrollHeight = system.windowHeight - 32;
},
methods: {
refresh() {
uni.showLoading({
title: "加载中...",
icon: "loading",
});
setTimeout(() => {
this.list = this.list1;
this.$refs["movableRefresh"].endLoad();
uni.hideLoading();
}, 2000);
},
getList() {
uni.showLoading({
title: "加载中...",
icon: "loading",
});
setTimeout(() => {
this.list = [...this.list, ...this.list1];
this.$refs["movableRefresh"].endLoad();
uni.hideLoading();
}, 2000);
},
loadMore() {
console.log(this.list.length);
console.log(this.total);
if (this.list.length > this.total || this.list.length == this.total) {
this.noMore = true;
uni.showToast({
title: "没有更多了...",
icon: "none",
duration: 1000,
});
return;
} else {
this.getList();
}
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100vh;
background-color: $background-color;
padding: 32rpx 24rpx;
.list-item {
padding: 34rpx 30rpx;
border-radius: 24rpx;
background: $uni-text-color-inverse;
margin-bottom: 21rpx;
&:last-child {
margin-bottom: 0;
}
.list-item-right-title,
.list-item-right-time,
.list-item-right-content {
font-family: PingFangSC_0;
font-weight: 400;
}
.list-item-left {
position: relative;
}
.read::after {
border-radius: 50%;
content: "";
position: absolute;
width: 16rpx;
height: 16rpx;
background: #ff0000;
right: 0;
top: 0;
}
.list-item-img {
width: 94rpx;
height: 94rpx;
}
.list-item-right {
padding-left: 24rpx;
flex: 1;
.list-item-right-title {
font-size: 32rpx;
color: $uni-text-color;
line-height: 45rpx;
}
.list-item-right-time {
font-size: 24rpx;
color: $uni-text-color-grey;
line-height: 36rpx;
}
.list-item-right-content {
font-size: 26rpx;
color: $uni-text-color-grey;
line-height: 36rpx;
}
}
}
}
</style>
uniapp 上拉刷新下拉加载
最新推荐文章于 2024-09-17 22:42:06 发布