uniapp微信小程序商品列表数据分页+本地缓存+下拉刷新+图片懒加载

图片懒加载写在scroll-view标签下的image里

html 复制代码
	<image lazy-load :src="car.mainImageUrl ?car.mainImageUrl :'/static/logo.jpg'" mode="aspectFill"
					class="car-item-image"></image>

完整代码

html 复制代码
<template>
		<scroll-view scroll-y @scrolltolower="loadMore" refresher-enabled @refresherrefresh="onPullDownRefresh">
			<carlist :view-mode="viewMode" :carList="carList" />
		</scroll-view>
	</view>
</template>
<script setup>
	import {
		onMounted,
		ref
	} from 'vue';

	import {
		onPullDownRefresh,
		onPageShow,
		onShareAppMessage,
		onShareTimeline
	} from '@dcloudio/uni-app'
	import {
		t
	} from '@/utils/i18n'
	import api from '@/utils/api.js'

	// --- 响应式数据 ---
	const carList = ref([]);
	const pageNum = ref(1); // 当前页码
	const pageSize = 10; // 每页数量,与后端接口保持一致
	const hasMore = ref(true); // 是否还有更多数据
	const loadingMore = ref(false); // 是否正在加载更多
	const isRefreshing = ref(false); // 是否正在下拉刷新

	// --- 本地缓存的 key ---
	const CACHE_KEY = 'carListCache';
	const CACHE_TIME_KEY = 'carListCacheTime';
	const CACHE_EXPIRY = 30 * 60 * 1000; // 缓存有效期,30分钟

	/**
	 * 获取车辆列表数据
	 * @param {boolean} isRefresh - 是否为下拉刷新
	 */
	const getCarList = async (isRefresh = false) => {
		// 如果正在加载更多或没有更多数据,则直接返回
		if (loadingMore.value || !hasMore.value && !isRefresh) {
			return;
		}

		if (isRefresh) {
			isRefreshing.value = true;
			pageNum.value = 1; // 刷新时重置页码
			hasMore.value = true;
		}

		loadingMore.value = true;
		try {
			const result = await api.car.getList({
				pageNum: pageNum.value,
				pageSize
			});

			const records = result.data.records || [];
			// 检查是否有数据,如果后端返回的数据条数少于 pageSize,则表示没有更多数据了
			if (records.length < pageSize) {
				hasMore.value = false;
			}
			
			// 下拉刷新时,清空原有列表
			if (isRefresh) {
				carList.value = records.reverse();
				// 刷新成功后更新缓存
				uni.setStorageSync(CACHE_KEY, carList.value);
				uni.setStorageSync(CACHE_TIME_KEY, Date.now());
			} else {
				// 上拉加载时,追加新数据
				carList.value = [...carList.value, ...records.reverse()];
			}

			pageNum.value++; // 页码递增
		} catch (error) {
			console.error('获取列表失败:', error);
			// 接口报错时,将hasMore设为false以避免无限加载
			hasMore.value = false; 
			// 提示用户加载失败
			uni.showToast({
				title: t('common.load_failed'),
				icon: 'error',
				duration: 2000
			});
		} finally {
			loadingMore.value = false;
			isRefreshing.value = false;
			uni.stopPullDownRefresh(); // 关闭下拉刷新动画
		}
	}

	// 监听小程序生命周期
	onPageShow(() => {
		const cachedData = uni.getStorageSync(CACHE_KEY);
		const cacheTime = uni.getStorageSync(CACHE_TIME_KEY);

		// 如果有缓存且未过期,使用缓存数据
		if (cachedData && cacheTime && (Date.now() - cacheTime < CACHE_EXPIRY)) {
			carList.value = cachedData;
			console.log('使用本地缓存数据');
		} else {
			// 没有缓存或缓存过期,加载最新数据
			console.log('缓存失效或无缓存,加载最新数据');
			getCarList(true); // 首次加载使用刷新模式
		}
	});
	
	/**
	 * 上拉加载更多
	 */
	const loadMore = () => {
		if (hasMore.value && !loadingMore.value) {
			console.log("加载更多");
			getCarList();
		} else {
			console.log("没有更多数据或正在加载");
		}
	};
	
	/**
	 * 页面级下拉刷新
	 */
	const onPullDownRefresh = () => {
		console.log("触发下拉刷新");
		getCarList(true);
	};

</script>
相关推荐
考拉讲支付5 小时前
母婴亲子服务平台分账架构设计:多场景多方分账与合规清结算实践
大数据·运维·人工智能·微信小程序·架构·微信公众平台
拖孩5 小时前
AI 帮我写的小程序「厨菜记」上线满月了,挣了两百块!!!
前端·后端·微信小程序
程序员小孔.9 小时前
基于 SpringBoot + UniApp + Vue 的家政服务系统设计与实现
前端·数据库·spring boot·python·docker·微信小程序
Chenyu_31017 小时前
DPDK、TC 和 XDP:Linux 高性能网络到底在优化什么
linux·服务器·网络·缓存
hflmwl81 天前
RedisDesktopManager安装包中文版官方下载,redis可视化客户端工具下载
数据库·redis·缓存·可视化客户端工具
一枕槐安4871 天前
大模型应用后端设计:上下文管理、缓存、降级策略的工程方案总结
java·spring·缓存
IT研究室1 天前
最新计算机毕业设计选题推荐-基于微信小程序的汉服交易系统-网站-文档指导-Java-springboot
java·微信小程序·课程设计
梦想平凡1 天前
棋牌游戏技术实战(十三):缓存对局历史时控制容量,命中以后仍然检查成员权限
游戏·缓存
我不会起名字3221 天前
Redis 从 0 到 1(十一):缓存穿透/击穿/雪崩三连击,Go 3 套防御代码
redis·缓存·go·布隆过滤器·雪崩
2301_32241428041 天前
springboot学生课堂出勤统计系统15835-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·mysql·随机森林·微信小程序·uni-app·微信开发者工具·推荐算法