hookehuyr

feat(StudyDetailPage): 添加图片轮播和预览功能

在StudyDetailPage页面中,新增了图片轮播组件`van-swipe`和图片预览组件`van-image-preview`,以支持课程图片的展示和预览功能。用户现在可以点击图片进行全屏预览。
...@@ -38,6 +38,7 @@ declare module 'vue' { ...@@ -38,6 +38,7 @@ declare module 'vue' {
38 VanForm: typeof import('vant/es')['Form'] 38 VanForm: typeof import('vant/es')['Form']
39 VanIcon: typeof import('vant/es')['Icon'] 39 VanIcon: typeof import('vant/es')['Icon']
40 VanImage: typeof import('vant/es')['Image'] 40 VanImage: typeof import('vant/es')['Image']
41 + VanImagePreview: typeof import('vant/es')['ImagePreview']
41 VanList: typeof import('vant/es')['List'] 42 VanList: typeof import('vant/es')['List']
42 VanNavBar: typeof import('vant/es')['NavBar'] 43 VanNavBar: typeof import('vant/es')['NavBar']
43 VanPicker: typeof import('vant/es')['Picker'] 44 VanPicker: typeof import('vant/es')['Picker']
...@@ -45,6 +46,8 @@ declare module 'vue' { ...@@ -45,6 +46,8 @@ declare module 'vue' {
45 VanPopup: typeof import('vant/es')['Popup'] 46 VanPopup: typeof import('vant/es')['Popup']
46 VanProgress: typeof import('vant/es')['Progress'] 47 VanProgress: typeof import('vant/es')['Progress']
47 VanRate: typeof import('vant/es')['Rate'] 48 VanRate: typeof import('vant/es')['Rate']
49 + VanSwipe: typeof import('vant/es')['Swipe']
50 + VanSwipeItem: typeof import('vant/es')['SwipeItem']
48 VanTab: typeof import('vant/es')['Tab'] 51 VanTab: typeof import('vant/es')['Tab']
49 VanTabs: typeof import('vant/es')['Tabs'] 52 VanTabs: typeof import('vant/es')['Tabs']
50 VanUploader: typeof import('vant/es')['Uploader'] 53 VanUploader: typeof import('vant/es')['Uploader']
......
...@@ -30,7 +30,22 @@ ...@@ -30,7 +30,22 @@
30 <AudioPlayer :songs="audioList" /> 30 <AudioPlayer :songs="audioList" />
31 </div> 31 </div>
32 <!-- 图片列表展示区域 --> 32 <!-- 图片列表展示区域 -->
33 - <div v-if="course.course_type === 'image'" class="w-full relative">image</div> 33 + <div v-if="course.course_type === 'image'" class="w-full relative">
34 + <van-swipe class="w-full" :autoplay="0" :show-indicators="true">
35 + <van-swipe-item v-for="(item, index) in courseFile?.list" :key="index" @click.native="showImagePreview(index)">
36 + <van-image
37 + :src="item.url"
38 + class="w-full"
39 + fit="cover"
40 + style="aspect-ratio: 16/9;"
41 + >
42 + <template #image>
43 + <img :src="item.url" class="w-full h-full object-cover" />
44 + </template>
45 + </van-image>
46 + </van-swipe-item>
47 + </van-swipe>
48 + </div>
34 <!-- 文件列表展示区域 --> 49 <!-- 文件列表展示区域 -->
35 <div v-if="course.course_type === 'file'" class="w-full relative">file</div> 50 <div v-if="course.course_type === 'file'" class="w-full relative">file</div>
36 <!-- 标签页区域 --> 51 <!-- 标签页区域 -->
...@@ -161,6 +176,17 @@ ...@@ -161,6 +176,17 @@
161 </div> 176 </div>
162 </div> 177 </div>
163 178
179 + <!-- 图片预览组件 -->
180 + <van-image-preview
181 + v-model:show="showPreview"
182 + :images="previewImages"
183 + :close-on-click-image="false"
184 + >
185 + <template #image="{ src, style, onLoad }">
186 + <img :src="src" :style="[{ width: '100%' }, style]" @load="onLoad" />
187 + </template>
188 + </van-image-preview>
189 +
164 <!-- 课程目录弹出层 --> 190 <!-- 课程目录弹出层 -->
165 <van-popup v-model:show="showCatalog" position="bottom" round closeable safe-area-inset-bottom 191 <van-popup v-model:show="showCatalog" position="bottom" round closeable safe-area-inset-bottom
166 style="height: 80%"> 192 style="height: 80%">
...@@ -247,6 +273,16 @@ const handleVideoPause = () => { ...@@ -247,6 +273,16 @@ const handleVideoPause = () => {
247 // 保持视频播放器可见,只在初始状态显示封面 273 // 保持视频播放器可见,只在初始状态显示封面
248 }; 274 };
249 275
276 +// 图片预览相关
277 +const showPreview = ref(false);
278 +const previewImages = ref([]);
279 +
280 +// 显示图片预览
281 +const showImagePreview = (startPosition) => {
282 + previewImages.value = courseFile.value?.list?.map(item => item.url) || [];
283 + showPreview.value = true;
284 +};
285 +
250 // 评论列表分页参数 286 // 评论列表分页参数
251 const popupCommentList = ref([]); 287 const popupCommentList = ref([]);
252 const popupLoading = ref(false); 288 const popupLoading = ref(false);
......