uniapp 自定义上拉加载下拉刷新组件

介绍

该组件是结合uview框架写的,主要结合了里面的u-loadmore组件,可配置下拉刷新加载圈的颜色及背景色,暂无数据时的图等,突出的特点就是通过设置组件的高度,适配刘海屏iPhone,且支持嵌套在各种盒子中。

iPhone手机即使我们没有开启原生的下拉刷新,上拉加载,默认也可以进行下拉和上拉的动作,我们可以在配置文件中关闭 “(disableScroll”: true )。

"globalStyle": {
    "disableScroll": true ,
    "navigationStyle": "custom", // 隐藏系统导航栏
    "navigationBarTextStyle": "white" 
},

组件最终实现效果图

image.png

image.png

image.png

了解整个页面的结构,计算准确的滚动组件的高度

image.png

配置项个别详解

    //暂无数据的类型,就是根据不同的场景展示不同的暂无数据的图片,
    _type:{
            default:'',
            type:String
    },
比如列表中暂无数据(_type:nodata)

image.png

消息列表中暂无数据(_type:nomsg)

image.png

    //除了标题栏和状态栏以外的高度
    otherHeight: {
            default: 0,
            type: Number
    },

otherHeight具体指页面中(不确定元素)的高度,不理解请看整个页面的结构图

组件使用

  1. 在根目录下创建components文件夹,定义全局组件,组件名建议xxx-功能.vue,例如safe-scrollbox.vue
  2. 注册为全局组件(page.json)
"easycom": {
    "autoscan": true, //是否开启自动扫描,开启后将会自动扫描符合components/组件名称/组件名称.vue目录结构的组件
    "safe-(.*)": "@/components/safe-$1.vue", // 匹配components目录下组件名称/组件名称内的vue文件
    "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
},
  1. 页面内使用
<safe-scrollbox @lowerFun="lowerFun" @refreshFun="refreshFun" :otherHeight="otherHeight"
    _type="nodata" :list="sealListArr" :status="loadStatus" :isRefresh="isRefresh" bgColor="#fff">
    <view class="seal-list-container" slot="contBox">
            <sealList @showActionBox="showActionBox" :list="sealListArr" :loadings="loadings"></sealList>
    </view>
</safe-scrollbox>

image.png

组件完整代码

<template>
	<!-- 滚动组件外层的框-->
	<view class="">
		<!-- 滚动区域 -->
		<scroll-view class="scroll-component" :scroll-top="scrollTop" scroll-y="true"
			:style="{
					height: `calc(100vh - ${statusBarHeight}px - ${navbarHeight}px - ${otherHeight}rpx - env(safe-area-inset-bottom) )`,
				}"
			:lower-threshold="150"
			:refresher-triggered="triggered"
			:refresher-enabled="true"
			refresher-default-style="none"
			:refresher-threshold="20"
			@refresherpulling="onPulling"
			@scrolltoupper="upper" @scrolltolower="lower"
			@scroll="scroll"
			@refresherrefresh="refresh"
			@refresherrestore="restore">
			<!-- 下拉刷新提示 -->
			<u-loadmore status="loading" bgColor="#fff" v-if="triggered" :icon-color="activeColor" :color="activeColor" :load-text="refreshText" margin-top="30" margin-bottom="30"/>
			<slot name="contBox"> </slot>
			<!-- 暂无数据 -->
			<view class="no-data-box" v-if="_type&&list.length==0">
				<image src="../static/imgs/nodata.png" v-if="_type=='nodata'" mode="aspectFit"></image>
				<image src="../static/imgs/nofile.png" v-if="_type=='nofile'" mode="aspectFit"></image>
				<image src="../static/imgs/nomsg.png" v-if="_type=='nomsg'" mode="aspectFit"></image>
				<image src="../static/imgs/nospace.png" v-if="_type=='nospace'" mode="aspectFit"></image>
				<image src="../static/imgs/nofile.png" v-if="_type=='nofile'" mode="aspectFit"></image>
			</view>
			<!-- 上拉加载 -->
			<u-loadmore :status="status" :load-text="loadText" margin-top="30" margin-bottom="30"/>
		</scroll-view>
		<!-- 回到顶部 -->
		 <view @tap="goTop" class="go-top" v-if="old.scrollTop>500">
			  <u-icon name="arrow-upward" color="#909399" size="56"></u-icon>
		 </view>
	</view>
</template>
import { mapGetters } from 'vuex';
export default {
	props: {
		// 这个数组结合暂无数据的类型主要是控制暂无数据模块的展示与隐藏
		list: {
			default: [],
			type: Array
		},
		//暂无数据的类型
		_type: {
			default: '',
			type: String
		},
		//控制上拉加载时提示 loadmore代表还可以继续上拉加载 nomore没有更多数据 loading 加载中
		status: {
			default: 'loadmore',
			type: String
		},
		//结合这个控制下拉刷新时加载圈的显示隐藏
		isRefresh: {
			default: false,
			type: Boolean
		},
		//除了标题栏和状态栏以外的高度
		otherHeight: {
			default: 0,
			type: Number
		},
		//下拉加载时加载圈的背景色
		bgColor: {
			default: '',
			type: String
		},
		//加载中,上拉加载时,暂无更多数据时所提示的文案
		loadText: {
			default: {
				loadmore: '轻轻上拉获取更多数据',
				loading: '努力加载中...',
				nomore: '暂无更多数据'
			},
			type: Object
		}
	},
	computed: {
		triggered() {
			return this.isRefresh;
		},
		...mapGetters(['activeColor', 'statusBarHeight', 'navbarHeight', 'skeletonColor'])
	},
	data() {
		return {
			old: {
				scrollTop: 0
			},
			scrollTop: 0,
			refreshText: {
				loading: '正在获取最新数据...'
			} //刷新文案
		};
	},
	methods: {
		onPulling() {
			// 下拉
			this.$emit('refreshFun');
			// this.triggered = true; //下拉加载,先让其变true再变false才能关闭
		},
		// 自定义下拉刷新控件被下拉
		refresh(e) {},
		// 刷新重置
		restore() {
			// this.triggered = 'restore'; // 需要重置
		},
		// 刷新终止
		onAbort() {
			// console.log("onAbort");
		},
		upper: function(e) {
			console.log(e);
		},
		// 上拉加载
		lower: function(e) {
			// console.log('上拉加载')
			this.$emit('lowerFun');
			// console.log(e)
			// this.status='loading'
		},
		scroll: function(e) {
			this.old.scrollTop = e.detail.scrollTop;
		},
		goTop: function(e) {
			this.scrollTop = this.old.scrollTop;
			this.$nextTick(() => {
				this.scrollTop = 0;
			});
		}
	}
};
.scroll-component {
	width: 750rpx;
	overflow-y: scroll;
}
/deep/ .u-loading-circle {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 80rpx;
	width: 750rpx;
}
.go-top {
	position: fixed;
	bottom: 208rpx;
	right: 0;
	z-index: 2;
	background-color: red;
	width: 100rpx;
	height: 100rpx;
	display: flex;
	justify-content: center;
	align-items: center;
	background: #606266;
	border-radius: 50%;
}
.no-data-box {
	width: 750rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	padding-top: 20%;
	margin-bottom: 10%;
	image {
		max-width: 600rpx;
	}
}
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以封装一个uniapp的上和下刷新组件,以下是一个简单的示例代码: ```vue <template> <view> <!-- 下刷新 --> <scroll-view class="refresh" scroll-y="true" refresher-triggered="{{refreshing}}" bindrefresherrefresh="onRefresh"> <refresher-slot> <!-- 自定义刷新内容 --> <view class="refresh-text">{{refreshText}}</view> </refresher-slot> <view> <!-- 列表内容 --> <block v-for="(item, index) in list" :key="index"> <view class="list-item">{{item}}</view> </block> <!-- 更多 --> <view class="load-more" v-show="!loading && !noMoreData" bindtap="loadMore">更多</view> <!-- 中 --> <view class="loading" v-show="loading">中...</view> <!-- 没有更多数据 --> <view class="no-more" v-show="noMoreData">没有更多数据了</view> </view> </scroll-view> </view> </template> <script> export default { data() { return { refreshing: false, // 是否正在下刷新 refreshText: "下刷新", // 下刷新文本 list: [], // 列表数据 loading: false, // 是否正在更多 noMoreData: false // 是否没有更多数据 }; }, methods: { // 下刷新事件 onRefresh() { this.refreshing = true; this.refreshText = "正在刷新..."; // 模拟刷新数据 setTimeout(() => { this.list = [1, 2, 3, 4, 5]; this.refreshing = false; this.refreshText = "下刷新"; this.loading = false; this.noMoreData = false; }, 1000); }, // 更多事件 loadMore() { this.loading = true; // 模拟更多数据 setTimeout(() => { if (this.list.length >= 10) { // 数据完成,没有更多数据 this.loading = false; this.noMoreData = true; } else { // 追数据 this.list.push(this.list.length + 1); this.loading = false; } }, 1000); } } }; </script> <style lang="scss"> .refresh { height: 100vh; } .refresh-text { text-align: center; line-height: 80rpx; } .list-item { height: 100rpx; line-height: 100rpx; text-align: center; } .load-more, .loading, .no-more { height: 80rpx; line-height: 80rpx; text-align: center; } </style> ``` 这个组件使用了`scroll-view`作为容器,通过设置`scroll-y`为`true`开启垂直滚动。下刷新通过监听`bindrefresherrefresh`事件,当下刷新触发时,执行`onRefresh`方法。更多通过点击"更多"按钮触发`loadMore`方法。 你可以根据自己的需求进行样式和功能的修改。希望对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值