hookehuyr

refactor(HomePage): 优化首页组件代码结构和注释

重构首页组件代码,添加详细的注释说明,提升代码可读性和可维护性。主要修改包括:
- 添加组件功能模块和状态管理的详细描述
- 为视频播放、轮播图、打卡等功能添加注释
- 优化代码结构,使其更清晰易读
...@@ -63,10 +63,6 @@ const videoOptions = computed(() => ({ ...@@ -63,10 +63,6 @@ const videoOptions = computed(() => ({
63 ...props.options, 63 ...props.options,
64 })); 64 }));
65 65
66 -const onPlayerReady = (instance) => {
67 - player = instance;
68 -};
69 -
70 const handleMounted = (payload) => { 66 const handleMounted = (payload) => {
71 state.value = payload.state; 67 state.value = payload.state;
72 player.value = payload.player; 68 player.value = payload.player;
......
1 <!-- 1 <!--
2 * @Date: 2025-03-20 19:55:21 2 * @Date: 2025-03-20 19:55:21
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-03-24 16:17:17 4 + * @LastEditTime: 2025-03-24 17:41:55
5 * @FilePath: /mlaj/src/views/HomePage.vue 5 * @FilePath: /mlaj/src/views/HomePage.vue
6 - * @Description: 文件描述 6 + * @Description: 亲子学院首页组件
7 + *
8 + * 主要功能模块:
9 + * 1. 用户欢迎区:显示用户信息和每日打卡
10 + * 2. 夏令营推广:展示特色夏令营活动
11 + * 3. 精选课程:轮播展示推荐课程
12 + * 4. 内容分类:推荐、直播、精选三个标签页
13 + * 5. 视频播放:支持在线视频播放和切换
14 + *
15 + * 状态管理:
16 + * - 用户认证状态:通过useAuth hook管理
17 + * - 打卡状态:包括选择的打卡类型和提交状态
18 + * - 轮播状态:当前轮播位置和滚动控制
19 + * - 视频播放状态:当前播放的视频索引
20 + *
21 + * 组件依赖:
22 + * - AppLayout:页面布局组件
23 + * - FrostedGlass:毛玻璃效果容器
24 + * - CourseCard:课程卡片组件
25 + * - LiveStreamCard:直播卡片组件
26 + * - ActivityCard:活动卡片组件
27 + * - SummerCampCard:夏令营卡片组件
28 + * - VideoPlayer:视频播放器组件
7 --> 29 -->
30 +
8 <template> 31 <template>
9 <AppLayout title="亲子学院" :rightContent="rightContent"> 32 <AppLayout title="亲子学院" :rightContent="rightContent">
10 <div class="pb-16 bg-gradient-to-b from-white via-green-50/10 to-blue-50/10"> 33 <div class="pb-16 bg-gradient-to-b from-white via-green-50/10 to-blue-50/10">
...@@ -489,8 +512,11 @@ ...@@ -489,8 +512,11 @@
489 </template> 512 </template>
490 513
491 <script setup lang="jsx"> 514 <script setup lang="jsx">
515 +// 导入所需的Vue核心功能和组件
492 import { ref, onMounted, onUnmounted, defineComponent, h } from 'vue' 516 import { ref, onMounted, onUnmounted, defineComponent, h } from 'vue'
493 import { useRoute, useRouter } from 'vue-router' 517 import { useRoute, useRouter } from 'vue-router'
518 +
519 +// 导入布局和UI组件
494 import AppLayout from '@/components/layout/AppLayout.vue' 520 import AppLayout from '@/components/layout/AppLayout.vue'
495 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 521 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
496 import CourseCard from '@/components/ui/CourseCard.vue' 522 import CourseCard from '@/components/ui/CourseCard.vue'
...@@ -498,43 +524,53 @@ import LiveStreamCard from '@/components/ui/LiveStreamCard.vue' ...@@ -498,43 +524,53 @@ import LiveStreamCard from '@/components/ui/LiveStreamCard.vue'
498 import ActivityCard from '@/components/ui/ActivityCard.vue' 524 import ActivityCard from '@/components/ui/ActivityCard.vue'
499 import SummerCampCard from '@/components/ui/SummerCampCard.vue' 525 import SummerCampCard from '@/components/ui/SummerCampCard.vue'
500 import VideoPlayer from '@/components/ui/VideoPlayer.vue' 526 import VideoPlayer from '@/components/ui/VideoPlayer.vue'
527 +
528 +// 导入模拟数据和工具函数
501 import { courses, liveStreams, activities, checkInTypes, userRecommendations } from '@/utils/mockData' 529 import { courses, liveStreams, activities, checkInTypes, userRecommendations } from '@/utils/mockData'
502 import { useTitle } from '@vueuse/core' 530 import { useTitle } from '@vueuse/core'
503 import { useAuth } from '@/contexts/auth' 531 import { useAuth } from '@/contexts/auth'
504 import { showToast } from 'vant' 532 import { showToast } from 'vant'
505 import 'vant/lib/toast/style' 533 import 'vant/lib/toast/style'
506 534
507 -const activeVideoIndex = ref(null); 535 +// 视频播放状态管理
508 -const videoPlayerRefs = ref([]); 536 +const activeVideoIndex = ref(null); // 当前播放的视频索引
537 +const videoPlayerRefs = ref([]); // 视频播放器组件引用数组
509 538
539 +// 播放视频处理函数
510 const playVideo = (index, videoUrl) => { 540 const playVideo = (index, videoUrl) => {
541 + // 如果当前有其他视频在播放,先暂停它
511 if (activeVideoIndex.value !== null && activeVideoIndex.value !== index) { 542 if (activeVideoIndex.value !== null && activeVideoIndex.value !== index) {
512 videoPlayerRefs.value[activeVideoIndex.value]?.pause(); 543 videoPlayerRefs.value[activeVideoIndex.value]?.pause();
513 } 544 }
545 + // 更新当前播放的视频索引
514 activeVideoIndex.value = index; 546 activeVideoIndex.value = index;
515 }; 547 };
516 548
549 +// 视频播放事件处理
517 const handleVideoPlay = (index) => { 550 const handleVideoPlay = (index) => {
551 + // 确保同一时间只有一个视频在播放
518 if (activeVideoIndex.value !== null && activeVideoIndex.value !== index) { 552 if (activeVideoIndex.value !== null && activeVideoIndex.value !== index) {
519 videoPlayerRefs.value[activeVideoIndex.value]?.pause(); 553 videoPlayerRefs.value[activeVideoIndex.value]?.pause();
520 } 554 }
521 }; 555 };
522 556
557 +// 路由相关
523 const $route = useRoute() 558 const $route = useRoute()
524 -const $router = useRouter() 559 +useTitle($route.meta.title) // 设置页面标题
525 -useTitle($route.meta.title)
526 560
527 -// 获取认证状态 561 +// 获取用户认证状态
528 const { currentUser } = useAuth() 562 const { currentUser } = useAuth()
529 563
530 -// 响应式状态 564 +// 响应式状态管理
531 -const activeTab = ref('推荐') 565 +const activeTab = ref('推荐') // 当前激活的内容标签页
532 -const selectedCheckIn = ref(null) 566 +const selectedCheckIn = ref(null) // 选中的打卡类型
533 -const checkInContent = ref('') 567 +const checkInContent = ref('') // 打卡内容
534 -const currentSlide = ref(0) 568 +const currentSlide = ref(0) // 当前轮播图索引
535 -const isCheckingIn = ref(false) 569 +const isCheckingIn = ref(false) // 打卡提交状态
536 -const checkInSuccess = ref(false) 570 +const checkInSuccess = ref(false) // 打卡成功状态
537 -const carouselRef = ref(null) 571 +const carouselRef = ref(null) // 轮播图容器引用
572 +
573 +// 右侧导航组件:搜索和消息通知
538 574
539 // 右侧内容组件 575 // 右侧内容组件
540 const RightContent = defineComponent({ 576 const RightContent = defineComponent({
...@@ -558,39 +594,40 @@ const RightContent = defineComponent({ ...@@ -558,39 +594,40 @@ const RightContent = defineComponent({
558 594
559 const rightContent = h(RightContent) 595 const rightContent = h(RightContent)
560 596
561 -// 图片加载错误处理 597 +// 工具函数:处理图片加载错误,设置默认头像
562 const handleImageError = (e) => { 598 const handleImageError = (e) => {
563 - e.target.onerror = null 599 + e.target.onerror = null // 防止循环触发错误
564 - e.target.src = 'https://cdn.ipadbiz.cn/mlaj/images/user-avatar-2.jpg' 600 + e.target.src = 'https://cdn.ipadbiz.cn/mlaj/images/user-avatar-2.jpg' // 设置默认头像
565 } 601 }
566 602
567 -// 格式化今天的日期 603 +// 工具函数:格式化今天的日期为中文格式
568 const formatToday = () => { 604 const formatToday = () => {
569 const today = new Date() 605 const today = new Date()
570 - const options = { month: 'long', day: 'numeric', weekday: 'long' } 606 + const options = { month: 'long', day: 'numeric', weekday: 'long' } // 设置日期格式选项
571 - return today.toLocaleDateString('zh-CN', options) 607 + return today.toLocaleDateString('zh-CN', options) // 返回中文格式的日期
572 } 608 }
573 609
574 -// 轮播图滚动到指定位置 610 +// 轮播图控制:滚动到指定位置
575 const scrollToSlide = (index) => { 611 const scrollToSlide = (index) => {
576 if (carouselRef.value) { 612 if (carouselRef.value) {
577 - const slideWidth = carouselRef.value.offsetWidth 613 + const slideWidth = carouselRef.value.offsetWidth // 获取轮播图容器宽度
578 carouselRef.value.scrollTo({ 614 carouselRef.value.scrollTo({
579 - left: index * slideWidth, 615 + left: index * slideWidth, // 计算目标滚动位置
580 - behavior: 'smooth' 616 + behavior: 'smooth' // 使用平滑滚动效果
581 }) 617 })
582 - currentSlide.value = index 618 + currentSlide.value = index // 更新当前轮播图索引
583 } 619 }
584 } 620 }
585 621
586 -// 处理打卡类型选择 622 +// 打卡功能:处理打卡类型选择
587 const handleCheckInSelect = (checkInType) => { 623 const handleCheckInSelect = (checkInType) => {
588 - selectedCheckIn.value = checkInType 624 + selectedCheckIn.value = checkInType // 更新选中的打卡类型
589 - checkInContent.value = '' 625 + checkInContent.value = '' // 清空打卡内容
590 } 626 }
591 627
592 -// 处理打卡提交 628 +// 打卡功能:处理打卡提交
593 const handleCheckInSubmit = () => { 629 const handleCheckInSubmit = () => {
630 + // 表单验证
594 if (!selectedCheckIn.value) { 631 if (!selectedCheckIn.value) {
595 showToast('请选择打卡项目') 632 showToast('请选择打卡项目')
596 return 633 return
......