refactor(HomePage): 优化首页组件代码结构和注释
重构首页组件代码,添加详细的注释说明,提升代码可读性和可维护性。主要修改包括: - 添加组件功能模块和状态管理的详细描述 - 为视频播放、轮播图、打卡等功能添加注释 - 优化代码结构,使其更清晰易读
Showing
2 changed files
with
67 additions
and
34 deletions
| ... | @@ -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 | ... | ... |
-
Please register or login to post a comment