mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-17 10:27:30 +08:00
refactor(player): 提取播放栏共享逻辑为 composable
- 新增 useVolumeControl:统一音量管理(volumeSlider、mute、滚轮调节) - 新增 useFavorite:收藏状态与切换 - 新增 usePlaybackControl:播放/暂停、上/下一首 - PlayBar、MiniPlayBar、SimplePlayBar、MobilePlayBar 使用新 composable - 修复音量存储不一致:MiniPlayBar/SimplePlayBar 原先绕过 playerStore 直接操作 localStorage
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { playMusic } from '@/hooks/MusicHook';
|
||||
import { usePlayerStore } from '@/store/modules/player';
|
||||
|
||||
/**
|
||||
* 当前歌曲的收藏状态管理 composable
|
||||
*/
|
||||
export function useFavorite() {
|
||||
const playerStore = usePlayerStore();
|
||||
|
||||
/** 当前歌曲是否已收藏 */
|
||||
const isFavorite = computed(() => {
|
||||
if (!playMusic?.value?.id) return false;
|
||||
return playerStore.favoriteList.includes(playMusic.value.id);
|
||||
});
|
||||
|
||||
/** 切换收藏状态 */
|
||||
const toggleFavorite = (e?: Event) => {
|
||||
e?.stopPropagation();
|
||||
if (!playMusic?.value?.id) return;
|
||||
|
||||
const favoriteId = playMusic.value.id;
|
||||
if (isFavorite.value) {
|
||||
playerStore.removeFromFavorite(favoriteId);
|
||||
} else {
|
||||
playerStore.addToFavorite(favoriteId);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
isFavorite,
|
||||
toggleFavorite
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { playMusic } from '@/hooks/MusicHook';
|
||||
import { usePlayerStore } from '@/store/modules/player';
|
||||
|
||||
/**
|
||||
* 播放控制 composable(播放/暂停、上一首、下一首)
|
||||
*/
|
||||
export function usePlaybackControl() {
|
||||
const playerStore = usePlayerStore();
|
||||
|
||||
/** 是否正在播放 */
|
||||
const isPlaying = computed(() => playerStore.isPlay);
|
||||
|
||||
/** 播放/暂停切换 */
|
||||
const playMusicEvent = async () => {
|
||||
try {
|
||||
await playerStore.setPlay({ ...playMusic.value });
|
||||
} catch (error) {
|
||||
console.error('播放出错:', error);
|
||||
playerStore.nextPlay();
|
||||
}
|
||||
};
|
||||
|
||||
/** 下一首 */
|
||||
const handleNext = () => {
|
||||
playerStore.nextPlay();
|
||||
};
|
||||
|
||||
/** 上一首 */
|
||||
const handlePrev = () => {
|
||||
playerStore.prevPlay();
|
||||
};
|
||||
|
||||
return {
|
||||
isPlaying,
|
||||
playMusicEvent,
|
||||
handleNext,
|
||||
handlePrev
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { usePlayerStore } from '@/store/modules/player';
|
||||
|
||||
/**
|
||||
* 统一的音量控制 composable
|
||||
* 通过 playerStore 管理音量,确保所有播放栏组件的音量状态一致
|
||||
*/
|
||||
export function useVolumeControl() {
|
||||
const playerStore = usePlayerStore();
|
||||
|
||||
/** 音量滑块值 (0-100) */
|
||||
const volumeSlider = computed({
|
||||
get: () => playerStore.volume * 100,
|
||||
set: (value: number) => {
|
||||
playerStore.setVolume(value / 100);
|
||||
}
|
||||
});
|
||||
|
||||
/** 音量图标 class */
|
||||
const volumeIcon = computed(() => {
|
||||
if (playerStore.volume === 0) return 'ri-volume-mute-line';
|
||||
if (playerStore.volume <= 0.5) return 'ri-volume-down-line';
|
||||
return 'ri-volume-up-line';
|
||||
});
|
||||
|
||||
/** 静音切换 (0 ↔ 30%) */
|
||||
const mute = () => {
|
||||
if (volumeSlider.value === 0) {
|
||||
volumeSlider.value = 30;
|
||||
} else {
|
||||
volumeSlider.value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** 鼠标滚轮调整音量 ±5% */
|
||||
const handleVolumeWheel = (e: WheelEvent) => {
|
||||
const delta = e.deltaY < 0 ? 5 : -5;
|
||||
const newValue = Math.min(Math.max(volumeSlider.value + delta, 0), 100);
|
||||
volumeSlider.value = newValue;
|
||||
};
|
||||
|
||||
return {
|
||||
volumeSlider,
|
||||
volumeIcon,
|
||||
mute,
|
||||
handleVolumeWheel
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user