hookehuyr

feat(收藏): 实现课程收藏功能并优化相关页面

- 新增 `favorite.js` API 文件,提供收藏列表、新增和取消收藏的接口
- 在 `CourseDetailPage.vue` 中实现收藏和取消收藏的逻辑,并添加交互反馈
- 在 `MyFavoritesPage.vue` 中替换模拟数据为真实接口调用,优化收藏课程加载逻辑
- 调整 `jsconfig.json` 配置文件,包含新增的 API 文件路径
...@@ -24,6 +24,6 @@ ...@@ -24,6 +24,6 @@
24 "esModuleInterop": true, 24 "esModuleInterop": true,
25 "skipLibCheck": true 25 "skipLibCheck": true
26 }, 26 },
27 - "include": ["src/**/*", "build/**/*", "vite.config.js"], 27 + "include": ["src/**/*", "build/**/*", "vite.config.js", "src/api/.js"],
28 "exclude": ["node_modules", "dist"] 28 "exclude": ["node_modules", "dist"]
29 } 29 }
......
1 +/*
2 + * @Date: 2025-04-16 16:21:37
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-04-17 10:04:30
5 + * @FilePath: /mlaj/src/api/favorite.js
6 + * @Description: 收藏相关接口
7 + */
8 +import { fn, fetch } from './fn'
9 +
10 +const Api = {
11 + GROUP_FAVORITE_LIST: '/srv/?a=group_favorite_list',
12 + FAVORITE_ADD: '/srv/?a=group_favorite',
13 + FAVORITE_CANCEL: '/srv/?a=group_unfavorite',
14 +}
15 +
16 +/**
17 + * @description: 获取课程收藏列表
18 + * @param: page 页码
19 + * @param: limit 每页数量
20 + * @return: data: { id: 收藏ID, title: 课程名称, price: 优惠价格, original_price: 原价, feature: 课程特色, highlights: 课程亮点, learning_goal: 学习目标, count: 课程章节数, cover: 封面图 }
21 + */
22 +export const getGroupFavoriteListAPI = (params) => fn(fetch.get(Api.GROUP_FAVORITE_LIST, params))
23 +
24 +/**
25 + * @description: 新增收藏
26 + * @param: group_id 课程ID
27 + * @return: data: { }
28 + */
29 +export const addFavoriteAPI = (params) => fn(fetch.post(Api.FAVORITE_ADD, params))
30 +
31 +/**
32 + * @description: 取消收藏
33 + * @param: group_id 课程ID
34 + * @return: data: { }
35 + */
36 +export const cancelFavoriteAPI = (params) => fn(fetch.post(Api.FAVORITE_CANCEL, params))
...@@ -37,28 +37,20 @@ ...@@ -37,28 +37,20 @@
37 37
38 <!-- Course Image --> 38 <!-- Course Image -->
39 <div class="mb-6"> 39 <div class="mb-6">
40 - <img 40 + <img :src="course?.cover || 'https://cdn.ipadbiz.cn/mlaj/images/default_block.png'" :alt="course?.title"
41 - :src="course?.cover || 'https://cdn.ipadbiz.cn/mlaj/images/default_block.png'" 41 + class="w-full h-auto rounded-xl shadow-md" />
42 - :alt="course?.title"
43 - class="w-full h-auto rounded-xl shadow-md"
44 - />
45 </div> 42 </div>
46 43
47 <!-- Tab Navigation --> 44 <!-- Tab Navigation -->
48 <FrostedGlass class="mb-6 rounded-xl overflow-hidden"> 45 <FrostedGlass class="mb-6 rounded-xl overflow-hidden">
49 <div class="border-b border-gray-200"> 46 <div class="border-b border-gray-200">
50 <div class="flex"> 47 <div class="flex">
51 - <button 48 + <button v-for="(item, index) in curriculumItems" :key="index" @click="activeTab = item.title" :class="[
52 - v-for="(item, index) in curriculumItems"
53 - :key="index"
54 - @click="activeTab = item.title"
55 - :class="[
56 'flex-1 py-3 font-medium text-center', 49 'flex-1 py-3 font-medium text-center',
57 activeTab === item.title 50 activeTab === item.title
58 ? 'text-green-600 border-b-2 border-green-600 bg-green-50/50' 51 ? 'text-green-600 border-b-2 border-green-600 bg-green-50/50'
59 : 'text-gray-500' 52 : 'text-gray-500'
60 - ]" 53 + ]">
61 - >
62 {{ item.title }} 54 {{ item.title }}
63 </button> 55 </button>
64 </div> 56 </div>
...@@ -83,8 +75,10 @@ ...@@ -83,8 +75,10 @@
83 <p class="text-sm text-gray-600 mt-1">{{ item.duration }}分钟 · {{ item.schedule_time || 'N/A' }}个小节</p> 75 <p class="text-sm text-gray-600 mt-1">{{ item.duration }}分钟 · {{ item.schedule_time || 'N/A' }}个小节</p>
84 </div> 76 </div>
85 <div v-if="course?.schedule?.length > 4" class="flex justify-center mt-4"> 77 <div v-if="course?.schedule?.length > 4" class="flex justify-center mt-4">
86 - <button @click="toggleSchedule" class="p-2 rounded-full hover:bg-green-50 text-green-600 hover:text-green-700 transition-all duration-300"> 78 + <button @click="toggleSchedule"
87 - <van-icon :name="isScheduleExpanded ? 'arrow-up' : 'arrow-down'" class="text-xl transform transition-transform duration-300" /> 79 + class="p-2 rounded-full hover:bg-green-50 text-green-600 hover:text-green-700 transition-all duration-300">
80 + <van-icon :name="isScheduleExpanded ? 'arrow-up' : 'arrow-down'"
81 + class="text-xl transform transition-transform duration-300" />
88 </button> 82 </button>
89 </div> 83 </div>
90 </div> 84 </div>
...@@ -109,12 +103,8 @@ ...@@ -109,12 +103,8 @@
109 <h3 class="text-lg font-bold text-gray-800 mb-3">主讲老师</h3> 103 <h3 class="text-lg font-bold text-gray-800 mb-3">主讲老师</h3>
110 <div class="flex items-center"> 104 <div class="flex items-center">
111 <div class="w-16 h-16 rounded-full overflow-hidden mr-4"> 105 <div class="w-16 h-16 rounded-full overflow-hidden mr-4">
112 - <img 106 + <img :src="teacher?.avatar || 'https://cdn.ipadbiz.cn/mlaj/images/default_block.png'" alt="Teacher"
113 - :src="teacher?.avatar || 'https://cdn.ipadbiz.cn/mlaj/images/default_block.png'" 107 + class="w-full h-full object-cover" @error="handleImageError" />
114 - alt="Teacher"
115 - class="w-full h-full object-cover"
116 - @error="handleImageError"
117 - />
118 </div> 108 </div>
119 <div> 109 <div>
120 <h4 class="font-bold text-gray-900">{{ teacher?.name || '没字段' }}</h4> 110 <h4 class="font-bold text-gray-900">{{ teacher?.name || '没字段' }}</h4>
...@@ -129,17 +119,10 @@ ...@@ -129,17 +119,10 @@
129 <h3 class="text-lg font-bold text-gray-800 mb-3">学员评价</h3> 119 <h3 class="text-lg font-bold text-gray-800 mb-3">学员评价</h3>
130 <div class="flex items-center mb-3"> 120 <div class="flex items-center mb-3">
131 <div class="flex text-yellow-400 mr-2"> 121 <div class="flex text-yellow-400 mr-2">
132 - <svg 122 + <svg v-for="star in 5" :key="star" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20"
133 - v-for="star in 5" 123 + fill="currentColor">
134 - :key="star"
135 - xmlns="http://www.w3.org/2000/svg"
136 - class="h-5 w-5"
137 - viewBox="0 0 20 20"
138 - fill="currentColor"
139 - >
140 <path 124 <path
141 - d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" 125 + d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
142 - />
143 </svg> 126 </svg>
144 </div> 127 </div>
145 <div class="text-gray-700">4.9 (126条评论)</div> 128 <div class="text-gray-700">4.9 (126条评论)</div>
...@@ -167,10 +150,8 @@ ...@@ -167,10 +150,8 @@
167 </div> 150 </div>
168 </div> 151 </div>
169 152
170 - <button 153 + <button @click="router.push(`/courses/${course?.id}/reviews`)"
171 - @click="router.push(`/courses/${course?.id}/reviews`)" 154 + class="w-full text-center text-green-600 mt-3 text-sm">
172 - class="w-full text-center text-green-600 mt-3 text-sm"
173 - >
174 查看全部评价 155 查看全部评价
175 </button> 156 </button>
176 </FrostedGlass> 157 </FrostedGlass>
...@@ -213,20 +194,12 @@ ...@@ -213,20 +194,12 @@
213 </svg> 194 </svg>
214 分享 195 分享
215 </button> --> 196 </button> -->
216 - <button class="flex flex-col items-center text-gray-500 text-xs transition-transform duration-300" @click="toggleFavorite" :class="{ 'animate-favorite': isFavorite }"> 197 + <button class="flex flex-col items-center text-gray-500 text-xs transition-transform duration-300"
217 - <svg 198 + @click="toggleFavorite" :class="{ 'animate-favorite': isFavorite }">
218 - xmlns="http://www.w3.org/2000/svg" 199 + <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 transition-transform duration-300"
219 - class="h-6 w-6 transition-transform duration-300" 200 + :fill="isFavorite ? 'red' : 'none'" viewBox="0 0 24 24" :stroke="isFavorite ? 'red' : 'currentColor'">
220 - :fill="isFavorite ? 'red' : 'none'" 201 + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
221 - viewBox="0 0 24 24" 202 + d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
222 - :stroke="isFavorite ? 'red' : 'currentColor'"
223 - >
224 - <path
225 - stroke-linecap="round"
226 - stroke-linejoin="round"
227 - stroke-width="2"
228 - d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
229 - />
230 </svg> 203 </svg>
231 收藏 204 收藏
232 </button> 205 </button>
...@@ -238,34 +211,16 @@ ...@@ -238,34 +211,16 @@
238 ¥{{ Math.round((course?.price || 0) * 1.2) }} 211 ¥{{ Math.round((course?.price || 0) * 1.2) }}
239 </div> 212 </div>
240 </div> 213 </div>
241 - <van-button 214 + <van-button v-if="!isPurchased" @click="handlePurchase" round block
242 - v-if="!isPurchased" 215 + color="linear-gradient(to right, #22c55e, #16a34a)" class="shadow-md">
243 - @click="handlePurchase"
244 - round
245 - block
246 - color="linear-gradient(to right, #22c55e, #16a34a)"
247 - class="shadow-md"
248 - >
249 立即购买 216 立即购买
250 </van-button> 217 </van-button>
251 - <van-button 218 + <van-button v-else-if="!isReviewed" @click="showReviewPopup = true" round block
252 - v-else-if="!isReviewed" 219 + color="linear-gradient(to right, #3b82f6, #2563eb)" class="shadow-md">
253 - @click="showReviewPopup = true"
254 - round
255 - block
256 - color="linear-gradient(to right, #3b82f6, #2563eb)"
257 - class="shadow-md"
258 - >
259 立即评论 220 立即评论
260 </van-button> 221 </van-button>
261 - <van-button 222 + <van-button v-else @click="router.push(`/courses/${course?.id}/reviews`)" round block
262 - v-else 223 + color="linear-gradient(to right, #6b7280, #4b5563)" class="shadow-md">
263 - @click="router.push(`/courses/${course?.id}/reviews`)"
264 - round
265 - block
266 - color="linear-gradient(to right, #6b7280, #4b5563)"
267 - class="shadow-md"
268 - >
269 查看评论 224 查看评论
270 </van-button> 225 </van-button>
271 </div> 226 </div>
...@@ -273,10 +228,7 @@ ...@@ -273,10 +228,7 @@
273 </div> 228 </div>
274 229
275 <!-- Review Popup --> 230 <!-- Review Popup -->
276 - <ReviewPopup 231 + <ReviewPopup v-model:show="showReviewPopup" @submit="handleReviewSubmit" />
277 - v-model:show="showReviewPopup"
278 - @submit="handleReviewSubmit"
279 - />
280 </AppLayout> 232 </AppLayout>
281 </template> 233 </template>
282 234
...@@ -286,13 +238,14 @@ import { useRoute, useRouter } from 'vue-router' ...@@ -286,13 +238,14 @@ import { useRoute, useRouter } from 'vue-router'
286 import AppLayout from '@/components/layout/AppLayout.vue' 238 import AppLayout from '@/components/layout/AppLayout.vue'
287 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 239 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
288 import ReviewPopup from '@/components/ui/ReviewPopup.vue' 240 import ReviewPopup from '@/components/ui/ReviewPopup.vue'
289 -import { courses } from '@/utils/mockData' 241 +// import { courses } from '@/utils/mockData'
290 import { useCart } from '@/contexts/cart' 242 import { useCart } from '@/contexts/cart'
291 import { useTitle } from '@vueuse/core'; 243 import { useTitle } from '@vueuse/core';
292 import { showToast } from 'vant'; 244 import { showToast } from 'vant';
293 245
294 // 导入接口 246 // 导入接口
295 import { getCourseDetailAPI } from "@/api/course"; 247 import { getCourseDetailAPI } from "@/api/course";
248 +import { addFavoriteAPI, cancelFavoriteAPI } from "@/api/favorite";
296 249
297 const $route = useRoute(); 250 const $route = useRoute();
298 const $router = useRouter(); 251 const $router = useRouter();
...@@ -315,9 +268,25 @@ const showReviewPopup = ref(false) ...@@ -315,9 +268,25 @@ const showReviewPopup = ref(false)
315 const { addToCart, proceedToCheckout } = useCart() 268 const { addToCart, proceedToCheckout } = useCart()
316 269
317 // Handle favorite toggle 270 // Handle favorite toggle
318 -const toggleFavorite = () => { 271 +// 收藏/取消收藏操作
272 +const toggleFavorite = async () => {
273 + if (isFavorite.value) {
274 + const { code, msg } = await cancelFavoriteAPI({
275 + group_id: course.value.id
276 + })
277 + if (code) {
319 isFavorite.value = !isFavorite.value 278 isFavorite.value = !isFavorite.value
320 - // TODO: 后续对接收藏接口 279 + showToast('取消收藏')
280 + }
281 + } else {
282 + const { code, msg } = await addFavoriteAPI({
283 + group_id: course.value.id
284 + })
285 + if (code) {
286 + isFavorite.value = !isFavorite.value
287 + showToast('收藏成功')
288 + }
289 + }
321 } 290 }
322 291
323 // Curriculum items 292 // Curriculum items
...@@ -384,7 +353,7 @@ const handleReviewSubmit = (review) => { ...@@ -384,7 +353,7 @@ const handleReviewSubmit = (review) => {
384 onMounted(async () => { 353 onMounted(async () => {
385 const id = route.params.id 354 const id = route.params.id
386 // 调用接口获取课程详情 355 // 调用接口获取课程详情
387 - const res = await getCourseDetailAPI({i: id}); 356 + const res = await getCourseDetailAPI({ i: id });
388 if (res.code) { 357 if (res.code) {
389 const foundCourse = res.data; 358 const foundCourse = res.data;
390 if (foundCourse) { 359 if (foundCourse) {
...@@ -431,9 +400,11 @@ const toggleSchedule = () => { ...@@ -431,9 +400,11 @@ const toggleSchedule = () => {
431 0% { 400 0% {
432 transform: scale(1); 401 transform: scale(1);
433 } 402 }
403 +
434 50% { 404 50% {
435 transform: scale(1.3); 405 transform: scale(1.3);
436 } 406 }
407 +
437 100% { 408 100% {
438 transform: scale(1); 409 transform: scale(1);
439 } 410 }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
2 <div class="bg-gradient-to-b from-green-50/70 to-white/90 min-h-screen pb-20"> 2 <div class="bg-gradient-to-b from-green-50/70 to-white/90 min-h-screen pb-20">
3 <!-- 分类切换 --> 3 <!-- 分类切换 -->
4 <div class="px-4 py-3"> 4 <div class="px-4 py-3">
5 - <van-tabs v-model:active="activeTab" sticky swipeable title-active-color="#4caf50" color="#4caf50"> 5 + <van-tabs v-model:active="activeTab" @click-tab="onClickTab" sticky swipeable title-active-color="#4caf50" color="#4caf50">
6 <van-tab title="课程" name="courses"> 6 <van-tab title="课程" name="courses">
7 <van-list 7 <van-list
8 v-model:loading="coursesLoading" 8 v-model:loading="coursesLoading"
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 </van-tab> 24 </van-tab>
25 25
26 <van-tab title="活动" name="activities"> 26 <van-tab title="活动" name="activities">
27 - <van-list 27 + <!--<van-list
28 v-model:loading="activitiesLoading" 28 v-model:loading="activitiesLoading"
29 :finished="activitiesFinished" 29 :finished="activitiesFinished"
30 finished-text="没有更多了" 30 finished-text="没有更多了"
...@@ -34,13 +34,13 @@ ...@@ -34,13 +34,13 @@
34 <ActivityCard v-for="activity in favoriteActivities" :key="activity.id" :activity="activity" /> 34 <ActivityCard v-for="activity in favoriteActivities" :key="activity.id" :activity="activity" />
35 </van-list> 35 </van-list>
36 36
37 - <!-- 无数据提示 --> 37 + <!~~ 无数据提示 ~~>
38 <div v-if="!activitiesLoading && favoriteActivities.length === 0" class="flex flex-col items-center justify-center py-12"> 38 <div v-if="!activitiesLoading && favoriteActivities.length === 0" class="flex flex-col items-center justify-center py-12">
39 <svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-gray-300" fill="none" viewBox="0 0 24 24" stroke="currentColor"> 39 <svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-gray-300" fill="none" viewBox="0 0 24 24" stroke="currentColor">
40 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" /> 40 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
41 </svg> 41 </svg>
42 <p class="mt-4 text-gray-500">暂无收藏活动</p> 42 <p class="mt-4 text-gray-500">暂无收藏活动</p>
43 - </div> 43 + </div>-->
44 </van-tab> 44 </van-tab>
45 </van-tabs> 45 </van-tabs>
46 </div> 46 </div>
...@@ -55,6 +55,9 @@ import ActivityCard from '@/components/ui/ActivityCard.vue'; ...@@ -55,6 +55,9 @@ import ActivityCard from '@/components/ui/ActivityCard.vue';
55 import { courses as mockCourses, activities as mockActivities } from '@/utils/mockData'; 55 import { courses as mockCourses, activities as mockActivities } from '@/utils/mockData';
56 import { useTitle } from '@vueuse/core'; 56 import { useTitle } from '@vueuse/core';
57 57
58 +// 导入接口
59 +import { getGroupFavoriteListAPI } from '@/api/favorite';
60 +
58 const $route = useRoute(); 61 const $route = useRoute();
59 const $router = useRouter(); 62 const $router = useRouter();
60 useTitle($route.meta.title); 63 useTitle($route.meta.title);
...@@ -67,8 +70,8 @@ const favoriteActivities = ref([]); ...@@ -67,8 +70,8 @@ const favoriteActivities = ref([]);
67 // 课程列表加载状态 70 // 课程列表加载状态
68 const coursesLoading = ref(false); 71 const coursesLoading = ref(false);
69 const coursesFinished = ref(false); 72 const coursesFinished = ref(false);
70 -const coursePage = ref(1); 73 +const coursePage = ref(0);
71 -const coursePageSize = 10; 74 +const courseLimit = ref(5);
72 75
73 // 活动列表加载状态 76 // 活动列表加载状态
74 const activitiesLoading = ref(false); 77 const activitiesLoading = ref(false);
...@@ -77,42 +80,41 @@ const activitiesPage = ref(1); ...@@ -77,42 +80,41 @@ const activitiesPage = ref(1);
77 const activitiesPageSize = 10; 80 const activitiesPageSize = 10;
78 81
79 // 加载收藏课程 82 // 加载收藏课程
80 -const onCoursesLoad = () => { 83 +const onCoursesLoad = async () => {
81 - coursesLoading.value = true; 84 + const nextPage = coursePage.value;
82 - // 模拟异步加载 85 + const res = await getGroupFavoriteListAPI({ limit: courseLimit.value, page: nextPage });
83 - setTimeout(() => { 86 + if (res.code) {
84 - const start = (coursePage.value - 1) * coursePageSize; 87 + favoriteCourses.value = [...favoriteCourses.value, ...res.data];
85 - const end = start + coursePageSize; 88 + coursesFinished.value = res.data.length < courseLimit.value;
86 - const newCourses = mockCourses.slice(start, end); 89 + coursePage.value = nextPage + 1;
87 -
88 - favoriteCourses.value.push(...newCourses);
89 - coursesLoading.value = false;
90 -
91 - if (newCourses.length < coursePageSize) {
92 - coursesFinished.value = true;
93 - } else {
94 - coursePage.value += 1;
95 } 90 }
96 - }, 1000); 91 + coursesLoading.value = false;
97 }; 92 };
98 93
99 // 加载收藏活动 94 // 加载收藏活动
100 -const onActivitiesLoad = () => { 95 +// const onActivitiesLoad = () => {
101 - activitiesLoading.value = true; 96 +// activitiesLoading.value = true;
102 - // 模拟异步加载 97 +// // 模拟异步加载
103 - setTimeout(() => { 98 +// setTimeout(() => {
104 - const start = (activitiesPage.value - 1) * activitiesPageSize; 99 +// const start = (activitiesPage.value - 1) * activitiesPageSize;
105 - const end = start + activitiesPageSize; 100 +// const end = start + activitiesPageSize;
106 - const newActivities = mockActivities.slice(start, end); 101 +// const newActivities = mockActivities.slice(start, end);
102 +
103 +// favoriteActivities.value.push(...newActivities);
104 +// activitiesLoading.value = false;
107 105
108 - favoriteActivities.value.push(...newActivities); 106 +// if (newActivities.length < activitiesPageSize) {
109 - activitiesLoading.value = false; 107 +// activitiesFinished.value = true;
108 +// } else {
109 +// activitiesPage.value += 1;
110 +// }
111 +// }, 1000);
112 +// };
110 113
111 - if (newActivities.length < activitiesPageSize) { 114 +// 切换标签页
112 - activitiesFinished.value = true; 115 +const onClickTab = ({ name, title }) => {
113 - } else { 116 + if (name === 'activities') {
114 - activitiesPage.value += 1; 117 + location.href = 'http://www.baidu.com'
115 } 118 }
116 - }, 1000);
117 }; 119 };
118 </script> 120 </script>
......