feat: 优化 list 加载

This commit is contained in:
alger
2024-12-17 23:23:20 +08:00
parent 9a7d5a3834
commit d28adb61a4
3 changed files with 74 additions and 26 deletions
+51 -24
View File
@@ -25,7 +25,7 @@
<div class="music-info"> <div class="music-info">
<div class="music-cover"> <div class="music-cover">
<n-image <n-image
:src="getImgUrl(listInfo?.coverImgUrl, '300y300')" :src="getImgUrl(cover ? listInfo?.coverImgUrl : displayedSongs[0]?.picUrl, '300y300')"
class="cover-img" class="cover-img"
preview-disabled preview-disabled
:class="setAnimationClass('animate__fadeIn')" :class="setAnimationClass('animate__fadeIn')"
@@ -47,21 +47,23 @@
<!-- 右侧歌曲列表 --> <!-- 右侧歌曲列表 -->
<div class="music-list-container"> <div class="music-list-container">
<div v-loading="loading" class="music-list"> <div class="music-list">
<n-scrollbar @scroll="handleScroll"> <n-scrollbar @scroll="handleScroll">
<div v-loading="loading || !songList.length" class="music-list-content"> <n-spin :show="loadingList || loading">
<div <div class="music-list-content">
v-for="(item, index) in displayedSongs" <div
:key="item.id" v-for="(item, index) in displayedSongs"
class="double-item" :key="item.id"
:class="setAnimationClass('animate__bounceInUp')" class="double-item"
:style="getItemAnimationDelay(index)" :class="setAnimationClass('animate__bounceInUp')"
> :style="getItemAnimationDelay(index)"
<song-item :item="formatDetail(item)" @play="handlePlay" /> >
<song-item :item="formatDetail(item)" @play="handlePlay" />
</div>
<div v-if="isLoadingMore" class="loading-more">加载更多...</div>
<play-bottom />
</div> </div>
<div v-if="isLoadingMore" class="loading-more">加载更多...</div> </n-spin>
<play-bottom />
</div>
</n-scrollbar> </n-scrollbar>
</div> </div>
<play-bottom /> <play-bottom />
@@ -82,22 +84,31 @@ import PlayBottom from './common/PlayBottom.vue';
const store = useStore(); const store = useStore();
const props = defineProps<{ const props = withDefaults(
show: boolean; defineProps<{
name: string; show: boolean;
songList: any[]; name: string;
loading?: boolean; songList: any[];
listInfo?: { loading?: boolean;
trackIds: { id: number }[]; listInfo?: {
[key: string]: any; trackIds: { id: number }[];
}; [key: string]: any;
}>(); };
cover?: boolean;
}>(),
{
loading: false,
cover: true,
},
);
const emit = defineEmits(['update:show', 'update:loading']); const emit = defineEmits(['update:show', 'update:loading']);
const page = ref(0); const page = ref(0);
const pageSize = 20; const pageSize = 20;
const isLoadingMore = ref(false); const isLoadingMore = ref(false);
const displayedSongs = ref<any[]>([]); const displayedSongs = ref<any[]>([]);
const loadingList = ref(false);
// 计算总数 // 计算总数
const total = computed(() => { const total = computed(() => {
@@ -166,6 +177,7 @@ const loadMoreSongs = async () => {
console.error('加载歌曲失败:', error); console.error('加载歌曲失败:', error);
} finally { } finally {
isLoadingMore.value = false; isLoadingMore.value = false;
loadingList.value = false;
} }
}; };
@@ -185,6 +197,16 @@ const handleScroll = (e: Event) => {
} }
}; };
watch(
() => props.show,
(newVal) => {
loadingList.value = newVal;
if (!props.cover) {
loadingList.value = false;
}
},
);
// 监听 songList 变化,重置分页状态 // 监听 songList 变化,重置分页状态
watch( watch(
() => props.songList, () => props.songList,
@@ -194,6 +216,7 @@ watch(
if (newSongs.length > pageSize) { if (newSongs.length > pageSize) {
page.value = 1; page.value = 1;
} }
loadingList.value = false;
}, },
{ immediate: true }, { immediate: true },
); );
@@ -254,6 +277,10 @@ watch(
&-list { &-list {
@apply flex-grow min-h-0; @apply flex-grow min-h-0;
&-content {
@apply min-h-[calc(80vh-60px)];
}
:deep(.n-virtual-list__scroll) { :deep(.n-virtual-list__scroll) {
scrollbar-width: none; scrollbar-width: none;
&::-webkit-scrollbar { &::-webkit-scrollbar {
+22 -2
View File
@@ -20,7 +20,14 @@
</div> </div>
</template> </template>
</div> </div>
<MusicList v-model:show="showMusic" :name="albumName" :song-list="songList" /> <MusicList
v-model:show="showMusic"
:name="albumName"
:song-list="songList"
:cover="false"
:loading="loadingList"
:list-info="albumInfo"
/>
</div> </div>
</template> </template>
@@ -41,15 +48,28 @@ const loadAlbumList = async () => {
const showMusic = ref(false); const showMusic = ref(false);
const songList = ref([]); const songList = ref([]);
const albumName = ref(''); const albumName = ref('');
const loadingList = ref(false);
const albumInfo = ref<any>({});
const handleClick = async (item: any) => { const handleClick = async (item: any) => {
songList.value = [];
albumInfo.value = {};
albumName.value = item.name; albumName.value = item.name;
loadingList.value = true;
showMusic.value = true; showMusic.value = true;
const res = await getAlbum(item.id); const res = await getAlbum(item.id);
songList.value = res.data.songs.map((song: any) => { songList.value = res.data.songs.map((song: any) => {
song.al.picUrl = song.al.picUrl || item.picUrl; song.al.picUrl = song.al.picUrl || item.picUrl;
return song; return song;
}); });
albumInfo.value = {
...res.data.album,
creator: {
avatarUrl: res.data.album.artist.img1v1Url,
nickname: `${res.data.album.artist.name} - ${res.data.album.company}`,
},
description: res.data.album.description,
};
loadingList.value = false;
}; };
onMounted(() => { onMounted(() => {
+1
View File
@@ -53,6 +53,7 @@
v-model:show="showMusic" v-model:show="showMusic"
name="每日推荐列表" name="每日推荐列表"
:song-list="dayRecommendData?.dailySongs" :song-list="dayRecommendData?.dailySongs"
:cover="false"
/> />
</div> </div>
</n-scrollbar> </n-scrollbar>