加入加载东湖

This commit is contained in:
future
2026-06-12 15:43:01 +08:00
parent 0402a1e82d
commit b345ceeb42
2 changed files with 155 additions and 25 deletions
@@ -138,7 +138,13 @@
class="course-card"
@tap="handleCourseClick(course)"
>
<!-- 图片容器 -->
<view class="card-image-wrapper">
<!-- 占位符灰色背景 -->
<view class="card-image-placeholder">
<view class="placeholder-spinner"></view>
</view>
<!-- 实际图片 -->
<image
class="card-image"
:src="course.image"
@@ -223,12 +229,14 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref, onMounted, onUnmounted } from 'vue'
import { onPullDownRefresh } from '@dcloudio/uni-app'
// 测试模式
const TEST_MODE = true
// 搜索关键词
const keyword = ref('')
// 当前页
@@ -241,7 +249,7 @@ const hasMore = ref(true)
const loadingMore = ref(false)
// 活动筛选标签
const activeFilter = ref('all')
// 课程列表
// 课程列表(不包含图片URL,只包含基本信息)
const courses = ref([])
// 骨架屏数量
const skeletonCount = ref(pageSize)
@@ -299,6 +307,7 @@ const sortOptions = [
// 处理滚动事件
const handleScroll = (e) => {
// 收起高级筛选
if (showAdvancedFilter.value && !isScrolling.value) {
isScrolling.value = true
showAdvancedFilter.value = false
@@ -633,18 +642,32 @@ const fetchCourses = async (searchKeyword = '', filter = 'all', page = 0, size =
}
if (result && result.content && result.content.length > 0) {
// 课程对象直接包含图片URL
const processedCourses = result.content.map(course => ({
id: course.id,
image: course.image,
tag: course.tag,
tagType: course.tagType,
courseType: course.courseType,
name: course.name,
duration: course.duration,
level: course.level,
participants: course.participants,
rawData: course.rawData
}))
if (append) {
// 追加模式:逐个添加数据,同时移除骨架屏
for (let i = 0; i < result.content.length; i++) {
for (let i = 0; i < processedCourses.length; i++) {
await Promise.resolve()
courses.value.push(result.content[i])
courses.value.push(processedCourses[i])
if (skeletonCount.value > 0) {
skeletonCount.value--
}
}
} else {
// 重置模式:直接替换
courses.value = result.content
courses.value = processedCourses
skeletonCount.value = 0
}
@@ -757,6 +780,14 @@ onMounted(() => {
currentFilterSignature = getFilterSignature()
fetchCourses()
})
// 组件卸载时清理资源
onUnmounted(() => {
// 清理滚动定时器
if (scrollTimer) {
clearTimeout(scrollTimer)
}
})
</script>
<style lang="scss">
@@ -1058,12 +1089,36 @@ onMounted(() => {
width: 100%;
height: 100%;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 2; /* 确保图片在占位符之上 */
.course-card:active & {
transform: scale(1.03);
}
}
/* 图片占位符 */
.card-image-placeholder {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #f1f5f9;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
.placeholder-spinner {
width: 40rpx;
height: 40rpx;
border: 4rpx solid #e2e8f0;
border-top-color: #f97316;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.image-overlay {
position: absolute;
left: 0;