CourseList.vue 2.9 KB
<!--
 * @Date: 2025-04-07
 * @Description: 课程列表组件
-->
<template>
    <div class="course-list">
        <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
            <div v-for="course in courses" :key="course.id"
                class="course-item bg-white p-3 rounded-lg overflow-hidden flex cursor-pointer" @click="router.push(`/studyDetail/${course.id}`)">
                <div class="relative w-[120px] h-full flex-shrink-0">
                    <van-image :src="course.thumbnail" width="120" height="100%" fit="cover" class="item-cover">
                        <div class="absolute bg-white/80 px-2 py-0.5 text-xs rounded"
                            style="right: 0.25rem; bottom: 0.5rem">
                            {{ course.type === 'video' ? '视频' : '音频' }}
                        </div>
                    </van-image>
                </div>
                <div class="flex-1 p-3 flex flex-col" style="padding-top: 0; padding-right: 0">
                    <div class="text-sm font-medium mb-2 mt-0">{{ course.title }}</div>
                    <div class="mt-auto">
                        <div class="flex items-center w-full">
                            <span class="text-sm text-gray-400 shrink-0" style="font-size: 0.75rem; width: 5rem">已学习 {{
                                formatDuration(course.studyTime) }}</span>
                            <div class="flex-1 mx-4">
                                <van-progress :percentage="course.progress" :stroke-width="4" color="#4080ff"
                                    :show-pivot="false" />
                            </div>
                            <span class="text-sm text-gray-400 shrink-0 text-center"
                                style="font-size: 0.75rem; width: 2rem; text-align: right">{{ course.progress }}%</span>
                        </div>
                    </div>
                </div>
            </div>
        </van-list>
    </div>
</template>

<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";

const router = useRouter();

// 接收课程列表数据
const props = defineProps({
    courses: {
        type: Array,
        default: () => [],
    },
});

// 列表加载状态
const loading = ref(false);
const finished = ref(true); // 由于使用的是传入的静态数据,所以直接设置为完成状态

// 加载更多
const onLoad = () => {
    loading.value = false;
};

// 格式化时长显示
const formatDuration = (seconds) => {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    if (hours > 0) {
        return `${hours}小时${minutes}分钟`;
    }
    return `${minutes}分钟`;
};
</script>

<style scoped>
.course-list {
    padding: 0rem;
}

.course-item {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

:deep(.van-image__img) {
    border-radius: 0.5rem;
}
</style>