mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-18 11:37:31 +08:00
feat: 优化收藏和历史列表组件,添加加载状态管理和动画效果
This commit is contained in:
@@ -80,6 +80,7 @@
|
|||||||
:key="song.id"
|
:key="song.id"
|
||||||
:item="song"
|
:item="song"
|
||||||
:favorite="false"
|
:favorite="false"
|
||||||
|
class="favorite-list-item"
|
||||||
:class="setAnimationClass('animate__bounceInLeft')"
|
:class="setAnimationClass('animate__bounceInLeft')"
|
||||||
:style="getItemAnimationDelay(index)"
|
:style="getItemAnimationDelay(index)"
|
||||||
:selectable="isSelecting"
|
:selectable="isSelecting"
|
||||||
@@ -103,7 +104,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref, watch } from 'vue';
|
import { computed, ref, watch, onMounted } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
@@ -339,20 +340,27 @@ const handleBatchDownload = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hasLoaded = ref(false);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
if (!hasLoaded.value) {
|
||||||
await playerStore.initializeFavoriteList();
|
await playerStore.initializeFavoriteList();
|
||||||
await getFavoriteSongs();
|
await getFavoriteSongs();
|
||||||
|
hasLoaded.value = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听收藏列表变化
|
// 监听收藏列表变化,变化时重置并重新加载
|
||||||
watch(
|
watch(
|
||||||
favoriteList,
|
favoriteList,
|
||||||
() => {
|
async () => {
|
||||||
|
hasLoaded.value = false;
|
||||||
currentPage.value = 1;
|
currentPage.value = 1;
|
||||||
noMore.value = false;
|
noMore.value = false;
|
||||||
getFavoriteSongs();
|
await getFavoriteSongs();
|
||||||
|
hasLoaded.value = true;
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePlay = () => {
|
const handlePlay = () => {
|
||||||
@@ -505,7 +513,9 @@ const handleBatchDownload = async () => {
|
|||||||
|
|
||||||
.favorite-list {
|
.favorite-list {
|
||||||
@apply space-y-2 pb-4 px-4;
|
@apply space-y-2 pb-4 px-4;
|
||||||
|
&-item {
|
||||||
|
@apply bg-light-100 dark:bg-dark-100 hover:bg-light-200 dark:hover:bg-dark-200 transition-all;
|
||||||
|
}
|
||||||
&-more {
|
&-more {
|
||||||
@apply mt-4;
|
@apply mt-4;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue';
|
import { ref, onMounted, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { getBilibiliProxyUrl, getBilibiliVideoDetail } from '@/api/bilibili';
|
import { getBilibiliProxyUrl, getBilibiliVideoDetail } from '@/api/bilibili';
|
||||||
@@ -42,11 +42,6 @@ import { useMusicHistory } from '@/hooks/MusicHistoryHook';
|
|||||||
import { usePlayerStore } from '@/store/modules/player';
|
import { usePlayerStore } from '@/store/modules/player';
|
||||||
import type { SongResult } from '@/type/music';
|
import type { SongResult } from '@/type/music';
|
||||||
import { setAnimationClass, setAnimationDelay } from '@/utils';
|
import { setAnimationClass, setAnimationDelay } from '@/utils';
|
||||||
|
|
||||||
defineOptions({
|
|
||||||
name: 'History'
|
|
||||||
});
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { delMusic, musicList } = useMusicHistory();
|
const { delMusic, musicList } = useMusicHistory();
|
||||||
const scrollbarRef = ref();
|
const scrollbarRef = ref();
|
||||||
@@ -54,6 +49,7 @@ const loading = ref(false);
|
|||||||
const noMore = ref(false);
|
const noMore = ref(false);
|
||||||
const displayList = ref<SongResult[]>([]);
|
const displayList = ref<SongResult[]>([]);
|
||||||
const playerStore = usePlayerStore();
|
const playerStore = usePlayerStore();
|
||||||
|
const hasLoaded = ref(false);
|
||||||
|
|
||||||
// 无限滚动相关配置
|
// 无限滚动相关配置
|
||||||
const pageSize = 100;
|
const pageSize = 100;
|
||||||
@@ -178,10 +174,26 @@ const handlePlay = () => {
|
|||||||
playerStore.setPlayList(displayList.value);
|
playerStore.setPlayList(displayList.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
getHistorySongs();
|
if (!hasLoaded.value) {
|
||||||
|
await getHistorySongs();
|
||||||
|
hasLoaded.value = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 监听历史列表变化,变化时重置并重新加载
|
||||||
|
watch(
|
||||||
|
musicList,
|
||||||
|
async () => {
|
||||||
|
hasLoaded.value = false;
|
||||||
|
currentPage.value = 1;
|
||||||
|
noMore.value = false;
|
||||||
|
await getHistorySongs();
|
||||||
|
hasLoaded.value = true;
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
// 重写删除方法,需要同时更新 displayList
|
// 重写删除方法,需要同时更新 displayList
|
||||||
const handleDelMusic = async (item: SongResult) => {
|
const handleDelMusic = async (item: SongResult) => {
|
||||||
delMusic(item);
|
delMusic(item);
|
||||||
@@ -205,7 +217,7 @@ const handleDelMusic = async (item: SongResult) => {
|
|||||||
.history-item {
|
.history-item {
|
||||||
@apply flex items-center justify-between;
|
@apply flex items-center justify-between;
|
||||||
&-content {
|
&-content {
|
||||||
@apply flex-1;
|
@apply flex-1 bg-light-100 dark:bg-dark-100 hover:bg-light-200 dark:hover:bg-dark-200 transition-all;
|
||||||
}
|
}
|
||||||
&-count {
|
&-count {
|
||||||
@apply px-4 text-lg text-center;
|
@apply px-4 text-lg text-center;
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex gap-4 h-full pb-4">
|
<div class="flex gap-4 h-full pb-4">
|
||||||
<favorite class="flex-item" />
|
<favorite class="flex-item" />
|
||||||
<history class="flex-item" />
|
<history-list class="flex-item" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
defineOptions({
|
||||||
|
name: 'History'
|
||||||
|
});
|
||||||
|
|
||||||
import Favorite from '@/views/favorite/index.vue';
|
import Favorite from '@/views/favorite/index.vue';
|
||||||
import History from '@/views/history/index.vue';
|
import HistoryList from '@/views/history/index.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user