33
33
@play =" handlePlay"
34
34
/>
35
35
<div v-if =" songLoading" class =" loading-more" >{{ t('common.loading') }}</div >
36
+ <div v-else-if =" songPage.hasMore" ref =" songsLoadMoreRef" class =" load-more-trigger" ></div >
36
37
</div >
37
38
</div >
38
39
</n-tab-pane >
54
55
}"
55
56
/>
56
57
<div v-if =" albumLoading" class =" loading-more" >{{ t('common.loading') }}</div >
58
+ <div v-else-if =" albumPage.hasMore" ref =" albumsLoadMoreRef" class =" load-more-trigger" ></div >
57
59
</div >
58
60
</div >
59
61
</n-tab-pane >
@@ -114,6 +116,12 @@ const albumPage = ref({
114
116
hasMore: true
115
117
});
116
118
119
+ // 无限滚动引用
120
+ const songsLoadMoreRef = ref <HTMLElement | null >(null );
121
+ const albumsLoadMoreRef = ref <HTMLElement | null >(null );
122
+ let songsObserver: IntersectionObserver | null = null ;
123
+ let albumsObserver: IntersectionObserver | null = null ;
124
+
117
125
// 加载歌手信息
118
126
const loadArtistInfo = async () => {
119
127
if (! artistId .value ) return ;
@@ -138,12 +146,12 @@ const loadArtistInfo = async () => {
138
146
const resetPagination = () => {
139
147
songPage .value = {
140
148
page: 1 ,
141
- pageSize: 30 ,
149
+ pageSize: 50 ,
142
150
hasMore: true
143
151
};
144
152
albumPage .value = {
145
153
page: 1 ,
146
- pageSize: 30 ,
154
+ pageSize: 50 ,
147
155
hasMore: true
148
156
};
149
157
songs .value = [];
@@ -181,6 +189,8 @@ const loadSongs = async () => {
181
189
songs .value = page === 1 ? newSongs : [... songs .value , ... newSongs ];
182
190
songPage .value .hasMore = newSongs .length === pageSize ;
183
191
songPage .value .page ++ ;
192
+ } else {
193
+ songPage .value .hasMore = false ;
184
194
}
185
195
} catch (error ) {
186
196
console .error (' 加载歌曲失败:' , error );
@@ -207,6 +217,8 @@ const loadAlbums = async () => {
207
217
albums .value = page === 1 ? newAlbums : [... albums .value , ... newAlbums ];
208
218
albumPage .value .hasMore = newAlbums .length === pageSize ;
209
219
albumPage .value .page ++ ;
220
+ } else {
221
+ albumPage .value .hasMore = false ;
210
222
}
211
223
} catch (error ) {
212
224
console .error (' 加载专辑失败:' , error );
@@ -229,29 +241,64 @@ const handlePlay = () => {
229
241
);
230
242
};
231
243
232
- // 添加滚动处理函数
233
- const handleScroll = useThrottleFn ( () => {
234
- const scrollTop = window . pageYOffset || document . documentElement . scrollTop ;
235
- const windowHeight = window . innerHeight ;
236
- const documentHeight = document . documentElement . scrollHeight ;
244
+ // 设置无限滚动观察器
245
+ const setupIntersectionObservers = () => {
246
+ // 清除现有的观察器
247
+ if ( songsObserver ) songsObserver . disconnect () ;
248
+ if ( albumsObserver ) albumsObserver . disconnect () ;
237
249
238
- if (documentHeight - (scrollTop + windowHeight ) < 100 ) {
239
- if (activeTab .value === ' songs' ) {
250
+ // 创建歌曲观察器
251
+ songsObserver = new IntersectionObserver ((entries ) => {
252
+ if (entries [0 ].isIntersecting && ! songLoading .value && songPage .value .hasMore ) {
240
253
loadSongs ();
241
- } else if (activeTab .value === ' albums' ) {
254
+ }
255
+ }, { threshold: 0.1 });
256
+
257
+ // 创建专辑观察器
258
+ albumsObserver = new IntersectionObserver ((entries ) => {
259
+ if (entries [0 ].isIntersecting && ! albumLoading .value && albumPage .value .hasMore ) {
242
260
loadAlbums ();
243
261
}
244
- }
245
- }, 200 );
262
+ }, { threshold: 0.1 });
263
+
264
+ // 监听标签页更改,重新设置观察器
265
+ watch (activeTab , (newTab ) => {
266
+ nextTick (() => {
267
+ if (newTab === ' songs' && songsLoadMoreRef .value && songPage .value .hasMore ) {
268
+ songsObserver ?.observe (songsLoadMoreRef .value );
269
+ } else if (newTab === ' albums' && albumsLoadMoreRef .value && albumPage .value .hasMore ) {
270
+ albumsObserver ?.observe (albumsLoadMoreRef .value );
271
+ }
272
+ });
273
+ });
274
+
275
+ // 监听引用元素的变化
276
+ watch (songsLoadMoreRef , (el ) => {
277
+ if (el && activeTab .value === ' songs' && songPage .value .hasMore ) {
278
+ songsObserver ?.observe (el );
279
+ }
280
+ });
281
+
282
+ watch (albumsLoadMoreRef , (el ) => {
283
+ if (el && activeTab .value === ' albums' && albumPage .value .hasMore ) {
284
+ albumsObserver ?.observe (el );
285
+ }
286
+ });
287
+ };
246
288
247
- // 监听页面滚动
248
289
onMounted (() => {
249
290
loadArtistInfo ();
250
- window .addEventListener (' scroll' , handleScroll );
291
+
292
+ // 添加nextTick以确保DOM已更新
293
+ nextTick (() => {
294
+ setupIntersectionObservers ();
295
+ });
251
296
});
252
297
253
298
onUnmounted (() => {
254
- window .removeEventListener (' scroll' , handleScroll );
299
+ // 清理观察器
300
+ if (songsObserver ) songsObserver .disconnect ();
301
+ if (albumsObserver ) albumsObserver .disconnect ();
255
302
});
256
303
257
304
// 监听路由参数变化
@@ -260,6 +307,10 @@ watch(
260
307
(newId ) => {
261
308
if (newId ) {
262
309
loadArtistInfo ();
310
+ // 添加nextTick以确保DOM已更新
311
+ nextTick (() => {
312
+ setupIntersectionObservers ();
313
+ });
263
314
}
264
315
}
265
316
);
@@ -325,6 +376,10 @@ watch(
325
376
@apply text-center py-4 text-gray-500 dark :text- gray- 400;
326
377
}
327
378
379
+ .load-more-trigger {
380
+ @apply h-4 w-full ;
381
+ }
382
+
328
383
.artist-description {
329
384
.description-content {
330
385
@apply text-sm leading-relaxed whitespace-pre-wrap ;
0 commit comments