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

View File

@@ -25,7 +25,7 @@
<div class="music-info">
<div class="music-cover">
<n-image
:src="getImgUrl(listInfo?.coverImgUrl, '300y300')"
:src="getImgUrl(cover ? listInfo?.coverImgUrl : displayedSongs[0]?.picUrl, '300y300')"
class="cover-img"
preview-disabled
:class="setAnimationClass('animate__fadeIn')"
@@ -47,21 +47,23 @@
<!-- 右侧歌曲列表 -->
<div class="music-list-container">
<div v-loading="loading" class="music-list">
<div class="music-list">
<n-scrollbar @scroll="handleScroll">
<div v-loading="loading || !songList.length" class="music-list-content">
<div
v-for="(item, index) in displayedSongs"
:key="item.id"
class="double-item"
:class="setAnimationClass('animate__bounceInUp')"
:style="getItemAnimationDelay(index)"
>
<song-item :item="formatDetail(item)" @play="handlePlay" />
<n-spin :show="loadingList || loading">
<div class="music-list-content">
<div
v-for="(item, index) in displayedSongs"
:key="item.id"
class="double-item"
:class="setAnimationClass('animate__bounceInUp')"
:style="getItemAnimationDelay(index)"
>
<song-item :item="formatDetail(item)" @play="handlePlay" />
</div>
<div v-if="isLoadingMore" class="loading-more">加载更多...</div>
<play-bottom />
</div>
<div v-if="isLoadingMore" class="loading-more">加载更多...</div>
<play-bottom />
</div>
</n-spin>
</n-scrollbar>
</div>
<play-bottom />
@@ -82,22 +84,31 @@ import PlayBottom from './common/PlayBottom.vue';
const store = useStore();
const props = defineProps<{
show: boolean;
name: string;
songList: any[];
loading?: boolean;
listInfo?: {
trackIds: { id: number }[];
[key: string]: any;
};
}>();
const props = withDefaults(
defineProps<{
show: boolean;
name: string;
songList: any[];
loading?: boolean;
listInfo?: {
trackIds: { id: number }[];
[key: string]: any;
};
cover?: boolean;
}>(),
{
loading: false,
cover: true,
},
);
const emit = defineEmits(['update:show', 'update:loading']);
const page = ref(0);
const pageSize = 20;
const isLoadingMore = ref(false);
const displayedSongs = ref<any[]>([]);
const loadingList = ref(false);
// 计算总数
const total = computed(() => {
@@ -166,6 +177,7 @@ const loadMoreSongs = async () => {
console.error('加载歌曲失败:', error);
} finally {
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 变化,重置分页状态
watch(
() => props.songList,
@@ -194,6 +216,7 @@ watch(
if (newSongs.length > pageSize) {
page.value = 1;
}
loadingList.value = false;
},
{ immediate: true },
);
@@ -254,6 +277,10 @@ watch(
&-list {
@apply flex-grow min-h-0;
&-content {
@apply min-h-[calc(80vh-60px)];
}
:deep(.n-virtual-list__scroll) {
scrollbar-width: none;
&::-webkit-scrollbar {

View File

@@ -20,7 +20,14 @@
</div>
</template>
</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>
</template>
@@ -41,15 +48,28 @@ const loadAlbumList = async () => {
const showMusic = ref(false);
const songList = ref([]);
const albumName = ref('');
const loadingList = ref(false);
const albumInfo = ref<any>({});
const handleClick = async (item: any) => {
songList.value = [];
albumInfo.value = {};
albumName.value = item.name;
loadingList.value = true;
showMusic.value = true;
const res = await getAlbum(item.id);
songList.value = res.data.songs.map((song: any) => {
song.al.picUrl = song.al.picUrl || item.picUrl;
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(() => {

View File

@@ -53,6 +53,7 @@
v-model:show="showMusic"
name="每日推荐列表"
:song-list="dayRecommendData?.dailySongs"
:cover="false"
/>
</div>
</n-scrollbar>