改进下拉

This commit is contained in:
田岩
2025-09-17 09:42:05 +08:00
parent badfc55df7
commit 6411ea98ff
18 changed files with 493 additions and 831 deletions
@@ -1,68 +1,41 @@
<template>
<view class="scroll_div">
<scroll-view scroll-y="true" class="scroll-Y" @scrolltolower="scrolltolower" :show-scrollbar="false">
<itemVue :item="item" v-for="(item, index) in data_list"></itemVue>
<list-no-data v-if="total === 0 && status == 'nomore'">暂无记录</list-no-data>
<uv-load-more v-if="total !== 0" :status="status" loadmore-text="轻轻上拉加载" :height="30"></uv-load-more>
</scroll-view>
</view>
<z-paging
ref="pagingRef"
v-model="data_list"
@query="queryList"
class="scroll_div"
:auto="false"
empty-view-text="暂无记录"
>
<view class="scroll-Y">
<itemVue :item="item" v-for="item in data_list"></itemVue>
</view>
</z-paging>
</template>
<script setup>
<script setup lang="ts">
import itemVue from './examRecordItem.vue';
import { ref, reactive } from 'vue';
import { ref, reactive, onMounted, watch } from 'vue';
import { queryCrsExamRecordPaging } from '@/api/courseRecord.js';
const status = ref('loading'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
const limit = 20;
const total = ref(-1);
const page = ref(0);
const data_list = reactive([]);
const getData = (from = '') => {
if (from === 'first') {
if (total.value !== -1) {
return;
}
status.value = 'loading';
total.value = -1;
page.value = 1;
data_list.length = 0;
} else {
if (status.value !== 'loadmore' && status.value !== '') return;
status.value = 'loading';
page.value++;
}
queryCrsExamRecordPaging({
page: page.value,
limit: limit
})
.then((res) => {
total.value = res.total;
data_list.push(...res.body);
})
.finally(() => {
if (data_list.length >= total.value) {
status.value = 'nomore';
} else {
status.value = 'loadmore';
}
});
};
const scrolltolower = () => {
getData();
};
defineExpose({
getData
import useZpaging from '@/composables/useZpaging';
const { pagingRef, queryList, data_list, reload, total } = useZpaging({
fetchFunction: queryCrsExamRecordPaging
});
const props = defineProps<{
tabIndex: number;
currentIndex: number;
}>();
onMounted(() => {
watch(
() => props.currentIndex,
(v) => v === props.tabIndex && total.value === -1 && reload(),
{ immediate: true }
);
});
</script>
<style scoped lang="scss">
.scroll_div {
background-color: #f1f5fa;
}
.scroll-Y {
height: calc(100vh - var(--status-bar-height) - 88rpx - 88rpx - 30rpx);
background-color: #f1f5fa;
height: 100%;
}
</style>
@@ -1,68 +1,41 @@
<template>
<view class="scroll_div">
<scroll-view scroll-y="true" class="scroll-Y" @scrolltolower="scrolltolower" :show-scrollbar="false">
<itemVue :item="item" v-for="(item, index) in data_list"></itemVue>
<list-no-data v-if="total === 0 && status == 'nomore'">暂无记录</list-no-data>
<uv-load-more v-if="total !== 0" :status="status" loadmore-text="轻轻上拉加载" :height="30"></uv-load-more>
</scroll-view>
</view>
<z-paging
ref="pagingRef"
v-model="data_list"
@query="queryList"
class="scroll_div"
:auto="false"
empty-view-text="暂无记录"
>
<view class="scroll-Y">
<itemVue :item="item" v-for="item in data_list"></itemVue>
</view>
</z-paging>
</template>
<script setup>
<script setup lang="ts">
import itemVue from './practiceRecordItem.vue';
import { ref, reactive } from 'vue';
import { ref, reactive, onMounted, watch } from 'vue';
import useZpaging from '@/composables/useZpaging';
import { queryPracticeRecordPaging } from '@/api/courseRecord.js';
const status = ref('loading'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
const limit = 20;
const total = ref(-1);
const page = ref(0);
const data_list = reactive([]);
const getData = (from = '') => {
if (from === 'first') {
if (total.value !== -1) {
return;
}
status.value = 'loading';
total.value = -1;
page.value = 1;
data_list.length = 0;
} else {
if (status.value !== 'loadmore' && status.value !== '') return;
status.value = 'loading';
page.value++;
}
queryPracticeRecordPaging({
page: page.value,
limit: limit
})
.then((res) => {
total.value = res.total;
data_list.push(...res.body);
})
.finally(() => {
if (data_list.length >= total.value) {
status.value = 'nomore';
} else {
status.value = 'loadmore';
}
});
};
const scrolltolower = () => {
getData();
};
defineExpose({
getData
const { pagingRef, queryList, data_list, reload, total } = useZpaging({
fetchFunction: queryPracticeRecordPaging
});
const props = defineProps<{
tabIndex: number;
currentIndex: number;
}>();
onMounted(() => {
watch(
() => props.currentIndex,
(v) => v === props.tabIndex && total.value === -1 && reload(),
{ immediate: true }
);
});
</script>
<style scoped lang="scss">
.scroll_div {
background-color: #f1f5fa;
}
.scroll-Y {
height: calc(100vh - var(--status-bar-height) - 88rpx - 88rpx - 30rpx);
background-color: #f1f5fa;
height: 100%;
}
</style>
@@ -58,6 +58,7 @@
</template>
<script setup>
console.log('学习组件');
import { computed } from 'vue';
import common from '@/common/common';
import { queryStdyBatchByCrsId } from '@/api/courseRecord.js';
@@ -1,70 +1,42 @@
<template>
<view class="scroll_div">
<scroll-view scroll-y="true" class="scroll-Y" @scrolltolower="scrolltolower" :show-scrollbar="false">
<itemVue :item="item" v-for="(item, index) in data_list" ></itemVue>
<list-no-data v-if="total === 0 && status == 'nomore'">暂无记录</list-no-data>
<uv-load-more v-if="total !== 0" :status="status" loadmore-text="轻轻上拉加载" :height="30"></uv-load-more>
</scroll-view>
</view>
<z-paging
ref="pagingRef"
v-model="data_list"
@query="queryList"
class="scroll_div"
:auto="false"
empty-view-text="暂无记录"
>
<view class="scroll-Y">
<itemVue :item="item" v-for="item in data_list"></itemVue>
</view>
</z-paging>
</template>
<script setup>
<script setup lang="ts">
import itemVue from './studyRecordItem.vue';
import { ref, reactive} from 'vue';
import { ref, reactive, onMounted, watch } from 'vue';
import { queryStdyRecordPaging } from '@/api/courseRecord.js';
const status = ref('loading'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
const limit = 20;
const total = ref(-1);
const page = ref(0);
const data_list = reactive([]);
const getData = (from = '') => {
if (from === 'first') {
if (total.value !== -1) {
return;
}
status.value = 'loading';
total.value = -1;
page.value = 1;
data_list.length = 0;
} else {
if (status.value !== 'loadmore' && status.value !== '') return;
status.value = 'loading';
page.value++;
}
queryStdyRecordPaging({
page: page.value,
limit: limit
})
.then((res) => {
total.value = res.total;
data_list.push(...res.body);
})
.finally(() => {
if (data_list.length >= total.value) {
status.value = 'nomore';
} else {
status.value = 'loadmore';
}
});
};
const scrolltolower = () => {
getData();
};
defineExpose({
getData
import useZpaging from '@/composables/useZpaging';
const { pagingRef, queryList, data_list, reload, total } = useZpaging({
fetchFunction: queryStdyRecordPaging
});
const props = defineProps<{
tabIndex: number;
currentIndex: number;
}>();
onMounted(() => {
watch(
() => props.currentIndex,
(v) => v === props.tabIndex && total.value === -1 && reload(),
{ immediate: true }
);
});
</script>
<style scoped lang="scss">
.scroll_div {
.scroll-Y {
background-color: #f1f5fa;
height: 100%;
}
.scroll-Y {
height: calc(100vh - var(--status-bar-height) - 88rpx - 88rpx - 30rpx);
}
</style>
+51 -71
View File
@@ -1,54 +1,63 @@
<template>
<view class="max_page detail-main">
<nav-bar :is_seat="false"></nav-bar>
<view class="fixed_search_div">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
<z-paging-swiper>
<template #top>
<view class="detail-main">
<nav-bar :is_seat="false"></nav-bar>
<view class="fixed_search_div">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
<view class="title font_pf">课程记录</view>
</view>
<view class="detail-body">
<view class="body-tab">
<uv-tabs
class="font_pf my_tabs"
:current="tabAct"
:list="tabList"
@change="tabChange"
:scrollable="false"
line-color="#0066FF"
:inactive-style="{ color: '#333333', fontSize: '30rpx', fontWeight: '600' }"
:activeStyle="{ color: '#0066FF', fontSize: '30rpx', fontWeight: '600' }"
:lineColor="`url(${LineBg}) 10% 10%`"
></uv-tabs>
</view>
</view>
</view>
<view class="title font_pf">课程记录</view>
</view>
<view class="detail-body">
<view class="body-tab">
<uv-tabs
class="font_pf my_tabs"
:current="tabAct"
:list="tabList"
@change="tabChange"
:scrollable="false"
line-color="#0066FF"
:inactive-style="{ color: '#333333', fontSize: '30rpx', fontWeight: '600' }"
:activeStyle="{ color: '#0066FF', fontSize: '30rpx', fontWeight: '600' }"
:lineColor="`url(${LineBg}) 10% 10%`"
></uv-tabs>
</view>
<view class="uni-margin-wrap no-overflow">
<swiper class="swiper" :current="tabAct" :indicator-dots="false" @change="swiperChange">
<swiper-item>
<studyRecordList :ref="(el) => (listItemRefs[0] = el)"></studyRecordList>
</swiper-item>
<swiper-item>
<practiceRecordList :ref="(el) => (listItemRefs[1] = el)"></practiceRecordList>
</swiper-item>
<swiper-item>
<examRecordList :ref="(el) => (listItemRefs[2] = el)"></examRecordList>
</swiper-item>
</swiper>
</view>
</view>
</view>
</template>
<swiper class="swiper" :current="tabAct" :indicator-dots="false" @change="swiperChange">
<swiper-item class="swiper-item">
<studyRecordList
:ref="(el) => (listItemRefs[0] = el)"
:tabIndex="0"
:currentIndex="tabAct"
></studyRecordList>
</swiper-item>
<swiper-item class="swiper-item">
<practiceRecordList
:ref="(el) => (listItemRefs[1] = el)"
:tabIndex="1"
:currentIndex="tabAct"
></practiceRecordList>
</swiper-item>
<swiper-item class="swiper-item">
<examRecordList :ref="(el) => (listItemRefs[2] = el)" :tabIndex="2" :currentIndex="tabAct"></examRecordList>
</swiper-item>
</swiper>
</z-paging-swiper>
</template>
<script setup>
import { LineBg } from '@/enum.js';
import studyRecordList from './components/studyRecordList.vue';
import practiceRecordList from './components/practiceRecordList.vue';
import examRecordList from './components/examRecordList.vue';
import { ref, onMounted, watch } from 'vue';
import common from '@/common/common.js';
const listItemRefs = ref([]);
const tabAct = ref(0);
import useIndexList from '@/composables/useIndexList.js';
const { tabAct, listItemRefs, tabChange, swiperChange } = useIndexList();
const tabList = ref([
{
name: '学习记录'
@@ -60,30 +69,10 @@
name: '考试记录'
}
]);
const tabChange = (item) => {
tabAct.value = item.index;
};
const swiperChange = (item) => {
tabAct.value = item.detail.current;
};
onMounted(() => {
watch(
tabAct,
(newValue) => {
typeof listItemRefs.value[newValue]?.getData === 'function' &&
listItemRefs.value[newValue]?.getData('first');
},
{
immediate: true
}
);
});
</script>
<style lang="scss" scoped>
$bg-margin-left: 50rpx;
.my_tabs {
// 解决这个圆角的图片,开穿透
:deep(.uv-tabs__wrapper__nav__line) {
@@ -95,21 +84,12 @@
}
.swiper {
/*
状态栏 var(--status-bar-height)
标题高度88rpx
tab切换栏高度88rpx
下方滑动区域上下边距各10共20rpx
**/
height: calc(100vh - var(--status-bar-height) - 88rpx - 88rpx - 30rpx);
height: 100%;
}
.swiper-item {
display: block;
height: 100%;
line-height: 300rpx;
text-align: center;
background-color: #f1f5fa;
}
.detail-body {