hookehuyr

refactor(StudyCoursePage): 优化顶部区域高度计算逻辑

使用 ResizeObserver 替代 setTimeout 监听元素尺寸变化,提高响应速度和准确性。移除不必要的延迟,并在组件卸载时取消监听,避免内存泄漏。
...@@ -8,11 +8,7 @@ ...@@ -8,11 +8,7 @@
8 <!-- 固定区域:课程封面和标签页 --> 8 <!-- 固定区域:课程封面和标签页 -->
9 <div class="fixed top-0 left-0 right-0 z-10 top-wrapper bg-white"> 9 <div class="fixed top-0 left-0 right-0 z-10 top-wrapper bg-white">
10 <!-- 课程封面区域 --> 10 <!-- 课程封面区域 -->
11 - <van-image 11 + <van-image class="w-full aspect-video object-cover" :src="course?.coverImage" :alt="course?.title" />
12 - class="w-full aspect-video object-cover"
13 - :src="course?.coverImage"
14 - :alt="course?.title"
15 - />
16 <div class="p-4"> 12 <div class="p-4">
17 <h1 class="text-black text-xl font-bold mb-2">{{ course?.title }}</h1> 13 <h1 class="text-black text-xl font-bold mb-2">{{ course?.title }}</h1>
18 <div class="flex items-center text-gray-500 text-sm"> 14 <div class="flex items-center text-gray-500 text-sm">
...@@ -38,7 +34,8 @@ ...@@ -38,7 +34,8 @@
38 </div> 34 </div>
39 35
40 <!-- 滚动区域:详情、目录和互动内容 --> 36 <!-- 滚动区域:详情、目录和互动内容 -->
41 - <div class="overflow-y-auto flex-1" :style="{paddingTop: topWrapperHeight, height: 'calc(100vh - ' + topWrapperHeight + ')'}"> 37 + <div class="overflow-y-auto flex-1"
38 + :style="{ paddingTop: topWrapperHeight, height: 'calc(100vh - ' + topWrapperHeight + ')' }">
42 <!-- 详情区域 --> 39 <!-- 详情区域 -->
43 <div id="detail" class="py-4 px-4"> 40 <div id="detail" class="py-4 px-4">
44 <div class="text-gray-700 text-sm leading-relaxed" v-html="course?.description"></div> 41 <div class="text-gray-700 text-sm leading-relaxed" v-html="course?.description"></div>
...@@ -50,8 +47,12 @@ ...@@ -50,8 +47,12 @@
50 <!-- 目录区域 --> 47 <!-- 目录区域 -->
51 <div id="catalog" class="py-4"> 48 <div id="catalog" class="py-4">
52 <div class="space-y-4"> 49 <div class="space-y-4">
53 - <div v-for="(lesson, index) in course?.lessons" :key="index" @click="router.push(`/studyDetail/${lesson.id}`)" class="bg-white p-4 cursor-pointer hover:bg-gray-50 transition-colors border-b border-gray-200 relative"> 50 + <div v-for="(lesson, index) in course?.lessons" :key="index"
54 - <div v-if="lesson.progress > 0 && lesson.progress < 100" class="absolute top-2 right-2 px-2 py-1 bg-green-100 text-green-600 text-xs rounded">上次看到</div> 51 + @click="router.push(`/studyDetail/${lesson.id}`)"
52 + class="bg-white p-4 cursor-pointer hover:bg-gray-50 transition-colors border-b border-gray-200 relative">
53 + <div v-if="lesson.progress > 0 && lesson.progress < 100"
54 + class="absolute top-2 right-2 px-2 py-1 bg-green-100 text-green-600 text-xs rounded">
55 + 上次看到</div>
55 <div class="text-black text-base font-medium mb-2">{{ lesson.title }}</div> 56 <div class="text-black text-base font-medium mb-2">{{ lesson.title }}</div>
56 <div class="flex items-center text-sm text-gray-500"> 57 <div class="flex items-center text-sm text-gray-500">
57 <span>视频</span>&nbsp; 58 <span>视频</span>&nbsp;
...@@ -105,17 +106,21 @@ const topWrapperHeight = ref(0); ...@@ -105,17 +106,21 @@ const topWrapperHeight = ref(0);
105 106
106 // 计算topWrapperHeight的函数 107 // 计算topWrapperHeight的函数
107 const updateTopWrapperHeight = () => { 108 const updateTopWrapperHeight = () => {
108 - setTimeout(() => {
109 nextTick(() => { 109 nextTick(() => {
110 const topWrapper = document.querySelector('.top-wrapper'); 110 const topWrapper = document.querySelector('.top-wrapper');
111 if (topWrapper) { 111 if (topWrapper) {
112 - // 确保在DOM更新后获取正确的高度 112 + // 使用 ResizeObserver 监听元素尺寸变化
113 - requestAnimationFrame(() => { 113 + const resizeObserver = new ResizeObserver(() => {
114 topWrapperHeight.value = `${topWrapper.offsetHeight}px`; 114 topWrapperHeight.value = `${topWrapper.offsetHeight}px`;
115 }); 115 });
116 + resizeObserver.observe(topWrapper);
117 +
118 + // 组件卸载时取消监听
119 + onUnmounted(() => {
120 + resizeObserver.disconnect();
121 + });
116 } 122 }
117 }); 123 });
118 - }, 500);
119 }; 124 };
120 125
121 // 初始化时计算topWrapperHeight 126 // 初始化时计算topWrapperHeight
......