开发时间:2024/09/15
开发作者:zhaozzz
开发工具:uniapp开发微信小程序
好久没写博客了,最近挺忙的,要看论文,要找方向。更新一下最近遇到的问题把。
1.实现加载分页+下拉刷新+上拉加载
只需要改一下接口和属性名,其他的全部复制粘贴,就可以使用,我已经帮大家测试过了喔~
欢迎大家来交流哦
1.实现加载分页 。我使用了uview中的---loadMore 加载更多组件 点击跳转
我先来展示一下我的界面,看是否对您有帮助呢?
上拉加载界面+下拉刷新界面
HTML界面
<view class="wrap">
<view class="item u-border-bottom" v-for="(item, index) in list" :key="index">
<view class="main_toalbox" @click="toTeacherResume(item.teacherId)">
<view class="main-box">
<view class="main-box_1">
<ul>
<li>
<u-avatar
:show-sex="true"
:sex-icon="getSexIcon(item.teacherGender)"
:src="`${BASE_URL}${item.teacherAvatar}`"></u-avatar>
</li>
<li style="font-size: 12px;color: #999999;">最近登录</li>
<li style="padding-left: 10px;font-size: 12px;color: #999999;">今天</li>
</ul>
</view>
<view class="main-box_2">
<ul>
<li class="li_1">
<span>{{ getTeacherLabel(item.teacherName)}}</span>
</li>
<li class="li_2">
<span
style="
display: inline-block;
margin-left: 0px;
margin-top: 8px;
width: 25px;
margin-right: 5px;
text-align: center;
border-radius: 5px;
background-color: #6e7ac2;
color: #ffffff;">{{ item.teacherGender }}</span>
<span style="
width: 80px;
display: inline-block;
margin-right: 7px;
text-align: center;
border-radius: 5px;
background-color: #6e7ac2;
color: #ffffff;
margin-top: 8px;
"
>{{ item.starRating }}</span>
<span style="
color: #fa7409;
background-color: #ffffff;
border: 1px solid #fa7409;
margin-top: 8px;
border-radius: 5px;
padding-left: 5px;
padding-right: 5px;">{{ item.university }}</span>
</li>
<li class="li_3" style="margin-top: 8px;">
<span style="color: black;">家教区域:</span>
<span v-for="(area,index) in splitAreas(item.teachingArea)" :key="index" class="area-label">
{{area}}
</span>
<span v-if="item.teachingArea.split(',').length > 3"></span>
</li>
<li class="li_4" style="margin-top: 8px;">
<span style="color: black;">家教科目:</span>
<span v-for="(subject, index) in displayedSubjects(item.tutoringSubjects)" :key="index" class="subject-label">
{{ subject }}
</span>
</li>
</ul>
</view>
</view>
</view>
</view>
<u-loadmore :status="status" style="margin-top: 20px;" /> //使用组件开发
</view>
JS界面
<script>
import { getTutorList } from "@/api/getTutorList.js"; //引入获取数据的接口
import { BASE_URL } from "@/static/js/data.js"; //方便修改服务器地址
export default {
data() {
return {
status: 'loadmore',// 组件状态,指的是加载更多
list: [],//存放数据
current: 1, //当前页
pageSize: 5,//页面大小
showTotal: true, //是否显示“下拉加载更多~”
BASE_URL, //方便修改服务器地址 同一写到一个data.js中
selectedGender: '',
selectedGenderLabel: '性别',
selectedStar: '',
selectedStarLabel: '星级',
selectedCity: '',
selectedCityLabel: '城市',
selectedSubject: '',
selectedSubjectLabel: '科目',
};
},
methods: {
//因为头像组件的值是man/woman 但是我接收到数据是男/女 所以这里要调整一下
getSexIcon(teacherGender){
return teacherGender ==='女'? 'woman' : 'man'
},
splitAreas(teachingArea) {
// 确保传入的是一个字符串,否则返回空数组
if (!teachingArea || typeof teachingArea !== 'string') return [];
// 将字符串按逗号分割为数组
const areaArray = teachingArea.split(',');
// 如果区域数量超过3个,展示前三个并加上'...'
if (areaArray.length > 3) {
return areaArray.slice(0, 3);
}
// 否则直接展示全部区域
return areaArray;
},
getTeacherLabel(name) {
if (name && name.length > 0) {
// 取姓名的第一个字并加上"教员"
return name.charAt(0) + '教员';
}
return '教员'; // 如果名字为空,默认显示"教员"
},
displayedSubjects(subjects) {
// 将字符串按逗号分割为数组
const subjectArray = subjects.split(',');
// 如果科目数量超过3个,展示前三个并加上'...'
if (subjectArray.length > 3) {
return [...subjectArray.slice(0, 3)];
}
// 否则直接展示全部科目
return subjectArray;
},
//因为头像组件的值是man/woman 但是我接收到数据是男/女 所以这里要调整一下
getSexIcon(teacherGender) {
return teacherGender === '女' ? 'woman' : 'man'
},
search() {
this.status = 'loadmore';
this.list = [];
this.current = 1;
this.findData();
},
//获取数据
findData() {
//当我查找到具体内容后,我想返回全部内容时,这里是用来返回全部
const tutoringSubjects = this.selectedSubject === '科目' ? '' : this.selectedSubject;
const tutoringStar = this.selectedStar === '不限' ? '' : this.selectedStar;
const tutoringCity = this.selectedCity === '全部' ? '' : this.selectedCity;
const tutoringGender =this.selectedGender === '不限' ? '' : this.selectedGender;
//根据不同接口,写上需要传输的参数
const params = {
current: this.current,
pageSize: this.pageSize,
teaching_area:tutoringCity,
teacher_gender: tutoringGender,
star_rating: tutoringStar,
current_address: '',
tutoring_subjects: tutoringSubjects
};
console.log('Params:', params); // 打印筛选条件
uni.showToast({
title: '加载中',
icon: 'loading',
duration: 1000 // 1秒后自动消失
});
setTimeout(() => {
getTutorList(params).then(res => {
console.log('Response:', res);
const data = res.tutors || [];
const total = res.total;
// 合并新数据到列表中
this.list = [...this.list, ...data];
console.log('Updated list:', this.list);
// 更新状态
this.status = data.length < this.pageSize ? 'nomore' : 'loadmore';
this.total = total; // 更新总条数
uni.hideToast();
}).catch(err => {
console.error('Error:', err);
this.status = 'loadmore'; // 请求失败恢复状态
});
}, 300); // 延迟1秒
},
// 下拉刷新
onPullDownRefresh() {
this.current = 1; // 重置为第一页
this.list = []; // 清空当前列表数据
this.findData(); // 请求第一页数据
uni.stopPullDownRefresh(); // 停止下拉刷新
},
//上拉加载
onReachBottom() {
console.log('Reached bottom. Status:', this.status);
if (this.status === 'loading' || this.status === 'nomore') return;
this.status = 'loading';
this.current++; // 增加当前页码
this.findData();
},
},
onLoad() {
this.findData()
}
};
</script>
特别注意
当我们想要实现下拉刷新时, 就需要在 pages.json 找到该页面,然后添加上该属性。然后利用生命周期函数onPullDownRefresh 进行操作就可以了 很简单
"enablePullDownRefresh": true,
css(这里我有些分不清了 所以把整个页面的css都v过来了 注意甄别)
<style lang="scss" scoped>
.container_teacher {
display: flex;
flex-direction: column;
background-color: #ffffff;
padding: 10px;
overflow: hidden; /* 确保 container_teacher 不滚动 */
}
.search-bar {
width: 100%;
height: 100rpx;
margin-top: 2%;
}
.search-bar-box {
display: flex;
margin: 0 auto;
width: 620rpx;
height: 74rpx;
border: 5rpx solid #00a8cc;
border-radius: 50rpx;
}
.search-span {
width: 100rpx;
height: 56rpx;
margin-top: 6rpx;
margin-left: 30rpx;
}
.search-text {
width: 100%;
margin-top: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
color: #7f7f81;
}
.search-btn {
background-color: #00a8cc; /* Green */
color: white;
text-align: center;
display: inline-block;
font-size: 35rpx;
width: 240rpx;
height: 70rpx;
line-height: 65rpx;
border-radius: 30rpx;
letter-spacing: 3rpx;
}
.top {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
padding: 10px;
}
.topItem {
background-color: #ffffff;
// border: 1px solid #dddddd;
border-radius: 5px;
padding: 10px;
width: 24%;
text-align: center;
margin-bottom: 10px;
position: relative;
}
.topItem image {
position: absolute;
right: 3px;
top: 50%;
transform: translateY(-50%);
}
.wrap {
flex: 1;
overflow-y: auto;
padding-bottom: 10px; /* 确保内容不会贴在底部 */
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.item {
margin-top: 10px;
width: 97%;
padding: 15px;
box-shadow: 0px 0px 6px #ccc;
border-radius: 5px;
background-color: #ffffff;
}
.main_toalbox {
display: flex;
flex-direction: column;
cursor: pointer;
}
.main-box {
display: flex;
}
.main-box_1 {
flex: 1;
display: flex;
align-items: center;
}
.main-box_2 {
flex: 4;
}
.main-box_2 .li_1 {
font-size: 16px;
font-weight: bold;
}
.main-box_2 .li_2 {
color: #666666;
}
.main-box_2 .li_3 {
color: #999999;
}
.main-box_2 .li_4 {
font-size: 14px;
color: #fa7409;
}
.u-border-bottom {
border-bottom: 1px solid #dddddd;
}
.isOver {
font-size: 20px;
margin: 0 auto;
width: 70%;
padding: 5px;
}
.ellipsis {
max-width: 80px; /* 根据需要调整宽度 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.area-label {
background-color: #eff0fe; /* 设置背景颜色 */
color:#8a8ba5;
padding: 3px 7px;
margin-right: 3px;
border-radius: 5px;
font-size: 12px;
display: inline-block;
}
.subject-label {
background-color: #dbfcfb; /* 这里设置统一的背景颜色 */
padding: 3px;
margin-right: 3px;
border-radius: 5px; /* 圆角 */
display: inline-block;
font-size: 12px;
color:#66d7b2;
}
</style>
完整版本(只需要改一下接口和属性名 其他的全部复制粘贴 就可以使用 )
<template>
<view>
<view class="wrap">
<view class="item u-border-bottom" v-for="(item, index) in list" :key="index">
<view class="main_toalbox" @click="toTeacherResume(item.teacherId)">
<view class="main-box">
<view class="main-box_1">
<ul>
<li>
<u-avatar :show-sex="true" :sex-icon="getSexIcon(item.teacherGender)"
:src="`${BASE_URL}${item.teacherAvatar}`"></u-avatar>
</li>
<li style="font-size: 12px;color: #999999;">最近登录</li>
<li style="padding-left: 10px;font-size: 12px;color: #999999;">今天</li>
</ul>
</view>
<view class="main-box_2">
<ul>
<li class="li_1">
<span>{{ getTeacherLabel(item.teacherName)}}</span>
</li>
<li class="li_2">
<span style="
display: inline-block;
margin-left: 0px;
margin-top: 8px;
width: 25px;
margin-right: 5px;
text-align: center;
border-radius: 5px;
background-color: #6e7ac2;
color: #ffffff;">{{ item.teacherGender }}</span>
<span style="
width: 80px;
display: inline-block;
margin-right: 7px;
text-align: center;
border-radius: 5px;
background-color: #6e7ac2;
color: #ffffff;
margin-top: 8px;
">{{ item.starRating }}</span>
<span style="
color: #fa7409;
background-color: #ffffff;
border: 1px solid #fa7409;
margin-top: 8px;
border-radius: 5px;
padding-left: 5px;
padding-right: 5px;">{{ item.university }}</span>
</li>
<li class="li_3" style="margin-top: 8px;">
<span style="color: black;">家教区域:</span>
<span v-for="(area,index) in splitAreas(item.teachingArea)" :key="index"
class="area-label">
{{area}}
</span>
<span v-if="item.teachingArea.split(',').length > 3"></span>
</li>
<li class="li_4" style="margin-top: 8px;">
<span style="color: black;">家教科目:</span>
<span v-for="(subject, index) in displayedSubjects(item.tutoringSubjects)"
:key="index" class="subject-label">
{{ subject }}
</span>
</li>
</ul>
</view>
</view>
</view>
</view>
<u-loadmore :status="status" style="margin-top: 20px;" />
</view>
</view>
</template>
<script>
import {
getTutorList
} from "@/api/getTutorList.js"; //引入获取数据的接口
import {
BASE_URL
} from "@/static/js/data.js"; //方便修改服务器地址
export default {
data() {
return {
status: 'loadmore', // 组件状态,指的是加载更多
list: [], //存放数据
current: 1, //当前页
pageSize: 5, //页面大小
showTotal: true, //是否显示“下拉加载更多~”
BASE_URL, //方便修改服务器地址 同一写到一个data.js中
selectedGender: '',
selectedGenderLabel: '性别',
selectedStar: '',
selectedStarLabel: '星级',
selectedCity: '',
selectedCityLabel: '城市',
selectedSubject: '',
selectedSubjectLabel: '科目',
};
},
methods: {
getSexIcon(teacherGender){
return teacherGender ==='女'? 'woman' : 'man'
},
splitAreas(teachingArea) {
// 确保传入的是一个字符串,否则返回空数组
if (!teachingArea || typeof teachingArea !== 'string') return [];
// 将字符串按逗号分割为数组
const areaArray = teachingArea.split(',');
// 如果区域数量超过3个,展示前三个并加上'...'
if (areaArray.length > 3) {
return areaArray.slice(0, 3);
}
// 否则直接展示全部区域
return areaArray;
},
getTeacherLabel(name) {
if (name && name.length > 0) {
// 取姓名的第一个字并加上"教员"
return name.charAt(0) + '教员';
}
return '教员'; // 如果名字为空,默认显示"教员"
},
displayedSubjects(subjects) {
// 将字符串按逗号分割为数组
const subjectArray = subjects.split(',');
// 如果科目数量超过3个,展示前三个并加上'...'
if (subjectArray.length > 3) {
return [...subjectArray.slice(0, 3)];
}
// 否则直接展示全部科目
return subjectArray;
},
//因为头像组件的值是man/woman 但是我接收到数据是男/女 所以这里要调整一下
getSexIcon(teacherGender) {
return teacherGender === '女' ? 'woman' : 'man'
},
search() {
this.status = 'loadmore';
this.list = [];
this.current = 1;
this.findData();
},
//获取数据
findData() {
//当我查找到具体内容后,我想返回全部内容时,这里是用来返回全部
const tutoringSubjects = this.selectedSubject === '科目' ? '' : this.selectedSubject;
const tutoringStar = this.selectedStar === '不限' ? '' : this.selectedStar;
const tutoringCity = this.selectedCity === '全部' ? '' : this.selectedCity;
const tutoringGender = this.selectedGender === '不限' ? '' : this.selectedGender;
//根据不同接口,写上需要传输的参数
const params = {
current: this.current,
pageSize: this.pageSize,
teaching_area: tutoringCity,
teacher_gender: tutoringGender,
star_rating: tutoringStar,
current_address: '',
tutoring_subjects: tutoringSubjects
};
console.log('Params:', params); // 打印筛选条件
uni.showToast({
title: '加载中',
icon: 'loading',
duration: 1000 // 1秒后自动消失
});
setTimeout(() => {
getTutorList(params).then(res => {
console.log('Response:', res);
const data = res.tutors || [];
const total = res.total;
// 合并新数据到列表中
this.list = [...this.list, ...data];
console.log('Updated list:', this.list);
// 更新状态
this.status = data.length < this.pageSize ? 'nomore' : 'loadmore';
this.total = total; // 更新总条数
uni.hideToast();
}).catch(err => {
console.error('Error:', err);
this.status = 'loadmore'; // 请求失败恢复状态
});
}, 300); // 延迟1秒
},
// 下拉刷新
onPullDownRefresh() {
this.current = 1; // 重置为第一页
this.list = []; // 清空当前列表数据
this.findData(); // 请求第一页数据
uni.stopPullDownRefresh(); // 停止下拉刷新
},
//上拉加载
onReachBottom() {
console.log('Reached bottom. Status:', this.status);
if (this.status === 'loading' || this.status === 'nomore') return;
this.status = 'loading';
this.current++; // 增加当前页码
this.findData();
},
},
onLoad() {
this.findData()
}
};
</script>
<style lang="scss" scoped>
.container_teacher {
display: flex;
flex-direction: column;
background-color: #ffffff;
padding: 10px;
overflow: hidden;
/* 确保 container_teacher 不滚动 */
}
.search-bar {
width: 100%;
height: 100rpx;
margin-top: 2%;
}
.search-bar-box {
display: flex;
margin: 0 auto;
width: 620rpx;
height: 74rpx;
border: 5rpx solid #00a8cc;
border-radius: 50rpx;
}
.search-span {
width: 100rpx;
height: 56rpx;
margin-top: 6rpx;
margin-left: 30rpx;
}
.search-text {
width: 100%;
margin-top: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
color: #7f7f81;
}
.search-btn {
background-color: #00a8cc;
/* Green */
color: white;
text-align: center;
display: inline-block;
font-size: 35rpx;
width: 240rpx;
height: 70rpx;
line-height: 65rpx;
border-radius: 30rpx;
letter-spacing: 3rpx;
}
.top {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
padding: 10px;
}
.topItem {
background-color: #ffffff;
// border: 1px solid #dddddd;
border-radius: 5px;
padding: 10px;
width: 24%;
text-align: center;
margin-bottom: 10px;
position: relative;
}
.topItem image {
position: absolute;
right: 3px;
top: 50%;
transform: translateY(-50%);
}
.wrap {
flex: 1;
overflow-y: auto;
padding-bottom: 10px;
/* 确保内容不会贴在底部 */
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.item {
margin-top: 10px;
width: 97%;
padding: 15px;
box-shadow: 0px 0px 6px #ccc;
border-radius: 5px;
background-color: #ffffff;
}
.main_toalbox {
display: flex;
flex-direction: column;
cursor: pointer;
}
.main-box {
display: flex;
}
.main-box_1 {
flex: 1;
display: flex;
align-items: center;
}
.main-box_2 {
flex: 4;
}
.main-box_2 .li_1 {
font-size: 16px;
font-weight: bold;
}
.main-box_2 .li_2 {
color: #666666;
}
.main-box_2 .li_3 {
color: #999999;
}
.main-box_2 .li_4 {
font-size: 14px;
color: #fa7409;
}
.u-border-bottom {
border-bottom: 1px solid #dddddd;
}
.isOver {
font-size: 20px;
margin: 0 auto;
width: 70%;
padding: 5px;
}
.ellipsis {
max-width: 80px;
/* 根据需要调整宽度 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.area-label {
background-color: #eff0fe;
/* 设置背景颜色 */
color: #8a8ba5;
padding: 3px 7px;
margin-right: 3px;
border-radius: 5px;
font-size: 12px;
display: inline-block;
}
.subject-label {
background-color: #dbfcfb;
/* 这里设置统一的背景颜色 */
padding: 3px;
margin-right: 3px;
border-radius: 5px;
/* 圆角 */
display: inline-block;
font-size: 12px;
color: #66d7b2;
}
</style>