【uniapp】实现触底加载数据

前言:实现界面触底数据加载。后端接口得支持翻页传参(本案例使用django)

1、后端接口 

1.1 封装翻页公共方法standardPagination.py

# -*- coding: utf-8 -*-
# @Time    : 2024/10/15 13:15
# @Author  : super
# @File    : standardPagination.py
# @Software: PyCharm
# @Describe:from rest_framework.pagination import PageNumberPagination
# 定义分页类,可以自定义每页显示的记录数
class StandardResultsSetPagination(PageNumberPagination):page_size = 10  # 每页显示的记录数,可以根据需要调整page_size_query_param = 'page_size'  # 允许客户端通过此参数指定每页显示的记录数max_page_size = 100  # 最大每页显示的记录数,防止客户端请求过多数据

1.2 views代码

支持按标题进行查询

class HonorExperienceSet(ModelViewSet):queryset = HonorExperience.objects.all().order_by('-date_earned','-create_time')serializer_class = HonorExperienceSerializerpagination_class = StandardResultsSetPagination  # 设置分页类def get_queryset(self):queryset = super().get_queryset()title = self.request.query_params.get('title', None)if title is not None:queryset = queryset.filter(title__icontains=title)return queryset

 2、uniapp方法

2.1 页面支持数据查询 

页面可进行查询,然后导入onReachBottom

<template>
<view class="pageBg" ><view class="header"><!-- 搜索框 --><input type="text" v-model="searchQuery" placeholder="搜索荣誉标题" class="search-input" /><!-- 确定按钮 --><button @click="searchHonor" class="search-button"><image src="/static/images/honorWall/ss.png" class="search-icon" /></button><!-- 新增按钮 --><navigator url="/pages/addHonor/addHonor"><button class="add-button"><image src="/static/images/honorWall/add.png" class="add-icon" /></button></navigator></view><!-- 列表展示 --><view v-if="honorList.length > 0" class="honor-list"><view v-for="(item,index) in honorList" :key="item.id"  class="honor-item"><text>{{ index + 1 }}</text>  <text>{{ item.type_display }}</text><text>{{ item.title }}</text><text>{{ formatDate(item.date_earned) }}</text></view></view>  <!-- 无数据时的占位提示 --><view v-else class="no-data"><text>暂无荣誉数据</text></view></view>
</template><script setup>
import { api } from '../../config/settings';
import { ref, onMounted, watch } from 'vue';
import {onReachBottom} from '@dcloudio/uni-app';
import {apiFetchHonorData} from '@/api/apis.js';
import { useRouter } from 'vue-router';// 定义存储荣誉数据的变量
const honorList = ref([]);// 查询条件
const searchQuery = ref('');
// 定义请求参数,title 参数如果没有提供,默认为 null
const params = ref({title: '', // 不传 title 参数时,接口将不过滤 titlepage: 1,   // 页码page_size: 20 // 每页显示的记录数
});// 格式化日期的方法
const formatDate = (dateStr) => {const date = new Date(dateStr);return `${date.getFullYear()}-${('0' + (date.getMonth() + 1)).slice(-2)}-${('0' + date.getDate()).slice(-2)}`;
};// 默认查询
const fetchHonorData = async () => {  // console.log(params);try {  const res = await apiFetchHonorData(params.value); // 初始加载时不带查询条件  honorList.value = res.data.results || []; // 确保即使响应中没有 data 字段,honorList 也是一个数组  } catch (error) {  console.error('组件挂载时获取荣誉数据失败:', error);  // 可以选择在这里处理错误,比如显示一个错误消息  }  
}
//挂载时执行默认查询
onMounted(fetchHonorData);  
//  搜索查询 
const searchHonor = async () => {// 更新 params 的 title 值params.value.title = searchQuery.value;// console.log(params.value);try {  const res = await apiFetchHonorData(params.value);  honorList.value = res.data.results  || []; // 更新荣誉列表 } catch (error) {  console.error('搜索荣誉数据时失败:', error);  // 可以选择在这里处理错误,比如显示一个错误消息或重置查询框  }  
};  onReachBottom(()=>{	console.log("sss")
})</script><style lang="scss" scoped>
.header {display: flex;justify-content: space-between;align-items: center;// margin-bottom: 5px;
}.search-input {flex-grow: 1;padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}.search-button {display: flex;align-items: center;color: white;border: none;border-radius: 5px;padding: 10px;cursor: pointer;
}.search-icon {width: 24px;height: 24px;
}.add-button {display: flex;align-items: center;color: white;border: none;border-radius: 5px;padding: 10px;cursor: pointer;
}.add-icon {width: 24px;height: 24px;
}.honor-list {padding: 5px;
}// .honor-item {
//   display: flex;
//   justify-content: space-between;
//   border-bottom: 1px solid #ddd;
//   padding: 10px 0;
// }
.honor-item {  display: flex;  align-items: center; // 确保所有子元素垂直居中  border-bottom: 1px solid #ddd;  padding: 10px 0;  
}  .honor-item > text:nth-child(1) { // 序号列  width: 40px; // 固定宽度  text-align: center;  
}  .honor-item > text:nth-child(2) { // 类型显示列  width: 60px; // 根据内容调整或固定宽度  text-align: left; // 或根据需求调整  
}  .honor-item > text:nth-child(3) { // 标题列  flex-grow: 1; // 填充剩余空间  min-width: 0; // 允许收缩到内容的最小宽度  white-space: nowrap; // 防止文本换行  overflow: hidden; // 隐藏溢出内容  text-overflow: ellipsis; // 使用省略号表示溢出文本  margin: 0 10px; // 可选:增加左右间距以改善可读性 }  .honor-item > text:nth-child(4) { // 日期列  width: 120px; // 固定宽度  text-align: right; // 根据需求调整  
}.no-data {text-align: center;padding: 20px;color: #999;
}
</style>

2.2 添加实现触底翻页查询

onReachBottom(()=>{params.value.page++;fetchHonorData();console.log("sss")
})

2.3 实现数据触底拼接

honorList.value = [...honorList.value, ...res.data.results] || []; // 更新荣誉列表 

2.4 解决数据加载完毕还执行查询问题

//定义获取不到数据的处理
const noDate = ref(false)#此位置加入如下代码honorList.value = [...honorList.value, ...res.data.results] || []; // 确保即使响应中没有 data 字段,honorList 也是一个数组  if(params.value.page_size > res.data.results.length) noDate.value = true;# 加判断
onReachBottom(()=>{if(noDate.value) return;params.value.page++;fetchHonorData();console.log("sss")
})

2.5 完整代码

<template>
<view class="pageBg" ><view class="header"><!-- 搜索框 --><input type="text" v-model="searchQuery" placeholder="搜索荣誉标题" class="search-input" /><!-- 确定按钮 --><button @click="searchHonor" class="search-button"><image src="/static/images/honorWall/ss.png" class="search-icon" /></button><!-- 新增按钮 --><navigator url="/pages/addHonor/addHonor"><button class="add-button"><image src="/static/images/honorWall/add.png" class="add-icon" /></button></navigator></view><!-- 列表展示 --><view v-if="honorList.length > 0" class="honor-list"><view v-for="(item,index) in honorList" :key="item.id"  class="honor-item"><text>{{ index + 1 }}</text>  <text>{{ item.type_display }}</text><text>{{ item.title }}</text><text>{{ formatDate(item.date_earned) }}</text></view></view>  <!-- 无数据时的占位提示 --><view v-else class="no-data"><text>暂无荣誉数据</text></view></view>
</template><script setup>
import { api } from '../../config/settings';
import { ref, onMounted, watch } from 'vue';
import {onReachBottom} from '@dcloudio/uni-app';
import {apiFetchHonorData} from '@/api/apis.js';
import { useRouter } from 'vue-router';//定义获取不到数据的处理
const noDate = ref(false)
// 定义存储荣誉数据的变量
const honorList = ref([]);// 查询条件
const searchQuery = ref('');
// 定义请求参数,title 参数如果没有提供,默认为 null
const params = ref({title: '', // 不传 title 参数时,接口将不过滤 titlepage: 1,   // 页码page_size: 20 // 每页显示的记录数
});// 格式化日期的方法
const formatDate = (dateStr) => {const date = new Date(dateStr);return `${date.getFullYear()}-${('0' + (date.getMonth() + 1)).slice(-2)}-${('0' + date.getDate()).slice(-2)}`;
};// 默认查询
const fetchHonorData = async () => {  // console.log(params);try {  const res = await apiFetchHonorData(params.value); // 初始加载时不带查询条件  honorList.value = [...honorList.value, ...res.data.results] || []; // 确保即使响应中没有 data 字段,honorList 也是一个数组  if(params.value.page_size > res.data.results.length) noDate.value = true;} catch (error) {  console.error('组件挂载时获取荣誉数据失败:', error);  // 可以选择在这里处理错误,比如显示一个错误消息  }  
}
//挂载时执行默认查询
onMounted(fetchHonorData);  
//  搜索查询 
const searchHonor = async () => {// 更新 params 的 title 值params.value.title = searchQuery.value;// console.log(params.value);try {  const res = await apiFetchHonorData(params.value);  honorList.value = [...honorList.value, ...res.data.results] || []; // 更新荣誉列表 if(params.value.page_size > res.data.results.length) noDate.value = true;} catch (error) {  console.error('搜索荣誉数据时失败:', error);  // 可以选择在这里处理错误,比如显示一个错误消息或重置查询框  }  
};  onReachBottom(()=>{if(noDate.value) return;params.value.page++;fetchHonorData();console.log("sss")
})</script><style lang="scss" scoped>
.header {display: flex;justify-content: space-between;align-items: center;// margin-bottom: 5px;
}.search-input {flex-grow: 1;padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}.search-button {display: flex;align-items: center;color: white;border: none;border-radius: 5px;padding: 10px;cursor: pointer;
}.search-icon {width: 24px;height: 24px;
}.add-button {display: flex;align-items: center;color: white;border: none;border-radius: 5px;padding: 10px;cursor: pointer;
}.add-icon {width: 24px;height: 24px;
}.honor-list {padding: 5px;
}// .honor-item {
//   display: flex;
//   justify-content: space-between;
//   border-bottom: 1px solid #ddd;
//   padding: 10px 0;
// }
.honor-item {  display: flex;  align-items: center; // 确保所有子元素垂直居中  border-bottom: 1px solid #ddd;  padding: 10px 0;  
}  .honor-item > text:nth-child(1) { // 序号列  width: 40px; // 固定宽度  text-align: center;  
}  .honor-item > text:nth-child(2) { // 类型显示列  width: 60px; // 根据内容调整或固定宽度  text-align: left; // 或根据需求调整  
}  .honor-item > text:nth-child(3) { // 标题列  flex-grow: 1; // 填充剩余空间  min-width: 0; // 允许收缩到内容的最小宽度  white-space: nowrap; // 防止文本换行  overflow: hidden; // 隐藏溢出内容  text-overflow: ellipsis; // 使用省略号表示溢出文本  margin: 0 10px; // 可选:增加左右间距以改善可读性 }  .honor-item > text:nth-child(4) { // 日期列  width: 120px; // 固定宽度  text-align: right; // 根据需求调整  
}.no-data {text-align: center;padding: 20px;color: #999;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/454780.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Hbase]一 HBase基础

1. HBase简介 1.1 HBase定义 HBase数据模型的关键在于 稀疏、分布式、多维、排序 的映射。其中映射 map指代非关系型数据库的 key-Value结构。 1.2 HBase数据模型 1)Name Space 命名空间,类似于关系型数据库的database 概念,每个命名空间下有多个表。HBase 两个自…

MFC工控项目实例二十五多媒体定时计时器

承接专栏《MFC工控项目实例二十四模拟量校正值输入》 用多媒体定时器实现0.1秒计时器 1、在SEAL_PRESSUREDlg.h文件中添加代码 #include<MMSystem.h> #pragma comment(lib,"winmm.lib")class CSEAL_PRESSUREDlg : public CDialog { public:CSEAL_PRESSUREDlg(…

Redis实现全局ID生成器

全局ID生成器 为什么要用全局ID生成器 1.当我们使用数据库自增来实现id的生成时,规律过于明显,会给用户暴露很多信息 2.当我们订单量过大时无法用数据库的一张表来存放订单,如果两张表的id都是自增的话,id就会出现重复 什么是全局ID生成器 全局ID生成器,是一种在分布式系统…

css刮刮卡效果(附源码!!!)

这个刮刮卡PC端和移动端都可以用使用 首发的公众号[小白讲前端]欢迎大家关注浏览 PC端展现 移动端展示 源码(PC和移动端直接复制运行) <!DOCTYPE html> <html><head><meta charset"utf-8"><meta name"viewport" content&quo…

宣恩文旅微短剧双作开机,融合创新助力城市经济发展

近日&#xff0c;宣恩文旅微短剧《弥彰》与《新年恋爱申请&#xff0c;请通过》正式开机。这两部作品由常斌、徐子琁、常喆宽、李果、况琪儿、梅凯杰、刘书赫等实力派演员领衔主演&#xff0c;不仅汇聚了众多演艺界的佼佼者&#xff0c;更承载着宣恩县文化旅游事业的创新与发展…

【从零开始的LeetCode-算法】3075. 幸福值最大化的选择方案

给你一个长度为 n 的数组 happiness &#xff0c;以及一个 正整数 k 。 n 个孩子站成一队&#xff0c;其中第 i 个孩子的 幸福值 是 happiness[i] 。你计划组织 k 轮筛选从这 n 个孩子中选出 k 个孩子。 在每一轮选择一个孩子时&#xff0c;所有 尚未 被选中的孩子的 幸福值 …

【ELK】初始阶段

一、logstash学习 安装的时候最好不要有中文的安装路径 使用相对路径 在 Windows PowerShell 中&#xff0c;如果 logstash 可执行文件位于当前目录下&#xff0c;你需要使用相对路径来运行它。尝试输入以下命令&#xff1a; .\logstash -e ‘input { stdin { } } output { s…

Ubuntu22.04 制作系统ISO镜像

第一步&#xff1a;安装软件-Systemback 1.如果已经添加过ppa&#xff0c;可以删除重新添加或者跳过此步 sudo add-apt-repository --remove ppa:nemh/systemback 2.添加ppa 我是ubuntu20&#xff0c;但这个软件最后支持的是 ubuntu16.04版本&#xff0c;所以加一个16版本…

通过Python爬虫获取商品销量数据,轻松掌握市场动态

为什么选择Python爬虫&#xff1f; 简洁易用&#xff1a;Python语言具有简洁的语法和丰富的库&#xff0c;使得编写爬虫变得简单高效。强大的库支持&#xff1a;Python拥有强大的爬虫框架&#xff08;如Scrapy、BeautifulSoup、Requests等&#xff09;&#xff0c;可以快速实现…

算法1—八大常用排序算法(上)

1.直接插入排序 原理&#xff1a;从arr[0]开始&#xff0c;每次和后一个数据比大小&#xff0c;然后根据需要的是升序还是降序进行操作。 最差的情况下时间复杂度&#xff1a;O&#xff08;n&#xff09; 最好的情况下时间复杂度&#xff1a;O&#xff08;1&#xff09; 所…

漏洞挖掘 | 通过域混淆绕过实现账户接管

由于这是一个私有项目&#xff0c;我将使用 example.com 来代替。 很长一段时间以来&#xff0c;我一直想在漏洞赏金项目中找到一个账户接管&#xff08;ATO&#xff09;漏洞。于是&#xff0c;我开始探索项目范围内的 account.example.com。 我做的第一件事就是注册一个新账…

WebRTC音频 03 - 实时通信框架

WebRTC音频01 - 设备管理 WebRTC音频 02 - Windows平台设备管理 WebRTC音频 03 - 实时通信框架(本文) WebRTC音频 04 - 关键类 WebRTC音频 05 - 音频采集编码 一、前言&#xff1a; 前面介绍了音频设备管理&#xff0c;并且以windows平台为例子&#xff0c;介绍了ADM相关的类…

探索 Web Audio API 的奇妙世界

Web Audio API 是一项强大而灵活的 JavaScript API&#xff0c;它允许开发者在网页中处理和生成音频。本文将带您深入了解 Web Audio API 的基本概念&#xff0c;并介绍一些令人兴奋的应用场景。 1. 什么是 Web Audio API&#xff1f; Web Audio API 是一组用于处理和生成音频…

react18中在列表项中如何使用useRef来获取每项的dom对象

在react中获取dom节点都知道用ref&#xff0c;但是在一个列表循环中&#xff0c;这样做是行不通的&#xff0c;需要做进一步的数据处理。 实现效果 需求&#xff1a;点击每张图片&#xff0c;当前图片出现在可视区域。 代码实现 .box{border: 1px solid #000;list-style: …

计算机专业大学四年的学习路线(非常详细),零基础入门到精通,看这一篇就够了

前言 许多学子选择踏上计算机这条充满挑战与机遇的道路。但在大学四年中&#xff0c;如何规划自己的学习路线&#xff0c;才能在毕业时脱颖而出&#xff0c;成为行业的佼佼者呢&#xff1f; 第一学年&#xff1a;基础知识的奠基 1.1 课程安排 在大学的第一年&#xff0c;重…

elementUI进度条el-progress不显示白色

效果图 通过设置百分比为100,动态修改进度条的宽度完成 <template><div class"myProgressBox"><div class"index">{{ index }}</div><div class"typeTitle">{{ typeTitle }}</div><div class"twoP…

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第六篇-阶段总结篇】

因为马上就要进入下一个阶段&#xff0c;制作动态编辑体积纹理的模块。 但在这之前&#xff0c;要在这一章做最后一些整理。 首先&#xff0c;我们完成没完成的部分。其次&#xff0c;最后整理一下图表。最后&#xff0c;本文附上正在用的贴图 完善Shader 还记得我们之前注…

『完整代码』坐骑召唤

创建一个按钮 作为召唤/消失坐骑的开关 将预制体放入指定文件夹 命名为Mount01 创建脚本并编写&#xff1a;CallMount.cs using UnityEngine; using UnityEngine.UI; public class CallMount : MonoBehaviour{public Button callBtn;GameObject mountPrefab;GameObject mountIn…

嵌套div导致子区域margin失效问题解决

嵌套div导致子区域margin失效问题解决 现象原因解决方法 现象 <div class"prev"></div> <div class"parent"><div class"child"></div><div class"child"></div> </div> <div cl…

Netty无锁化设计之对象池实现

池化技术是比较常见的一种技术&#xff0c;在平时我们已经就接触很多了&#xff0c;比如线程池&#xff0c;数据库连接池等等。当我们要使用一个资源的时候从池中去获取&#xff0c;用完就放回池中以便其他线程可以使用&#xff0c;这样的目的就是为了减少资源开销&#xff0c;…