CourseListPage.vue
2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<!--
* @Date: 2025-03-21 14:31:21
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-21 14:54:47
* @FilePath: /mlaj/src/views/courses/CourseListPage.vue
* @Description: 文件描述
-->
<template>
<AppLayout title="课程列表">
<div class="pb-16">
<!-- Search Bar -->
<div class="pb-2">
<SearchBar placeholder="搜索" v-model="keyword" @search="handleSearch" @blur="handleBlur" />
</div>
<!-- Course List -->
<div class="px-4">
<div class="space-y-4">
<CourseCard v-for="course in courses" :key="course.id" :course="course" />
</div>
<!-- Load More -->
<div
v-if="hasMore"
class="py-4 text-center text-gray-500 text-sm"
@click="loadMore"
>
加载更多
</div>
<div
v-else
class="py-4 text-center text-gray-400 text-sm"
>
没有更多课程了
</div>
</div>
</div>
</AppLayout>
</template>
<script setup>
import { ref, onMounted, watchEffect } from 'vue';
import { useRoute } from 'vue-router';
import AppLayout from '@/components/layout/AppLayout.vue';
import SearchBar from '@/components/ui/SearchBar.vue';
import CourseCard from '@/components/ui/CourseCard.vue';
import { courses as mockCourses } from '@/utils/mockData';
const $route = useRoute();
const courses = ref([]);
const hasMore = ref(true);
const page = ref(1);
const keyword = ref('');
// 搜索课程列表
const searchCourses = () => {
// 实际项目中这里会调用搜索API
const filteredCourses = keyword.value
? mockCourses.filter(course =>
(course.title?.toLowerCase().includes(keyword.value.toLowerCase()) ||
course.description?.toLowerCase().includes(keyword.value.toLowerCase())) ?? false
)
: [...mockCourses];
courses.value = filteredCourses;
hasMore.value = filteredCourses.length >= 10;
page.value = 1;
};
// 监听路由参数变化
watchEffect(() => {
const queryKeyword = $route.query.keyword;
if (keyword.value !== queryKeyword) {
keyword.value = queryKeyword || '';
searchCourses();
}
});
// Search handler
const handleSearch = (query) => {
keyword.value = query;
searchCourses();
};
// Blur handler
const handleBlur = (query) => {
keyword.value = query;
searchCourses();
};
// Load more courses
const loadMore = () => {
// 实际项目中这里会调用分页API
if (page.value < 3) {
const filteredCourses = keyword.value
? mockCourses.filter(course =>
course.title.toLowerCase().includes(keyword.value.toLowerCase()) ||
course.description.toLowerCase().includes(keyword.value.toLowerCase())
)
: [...mockCourses];
courses.value = [...courses.value, ...filteredCourses];
console.warn(courses.value);
page.value += 1;
hasMore.value = page.value < 3;
} else {
hasMore.value = false;
}
};
</script>