Skip to content

🪝 Composables 组合式函数

🎧 useAudio

音频播放控制的核心组合式函数,封装了播放器的所有操作。

📁 文件位置src/composables/useAudio.ts

📤 返回值

📊 状态

属性类型说明
currentSongComputedRef<Song | null>当前播放歌曲
isPlayingComputedRef<boolean>是否正在播放
isLoadingComputedRef<boolean>是否加载中
playlistComputedRef<Song[]>播放列表
playModeComputedRef<PlayMode>播放模式
volumeComputedRef<number>音量 (0-1)
currentTimeComputedRef<number>当前播放时间(秒)
durationComputedRef<number>歌曲总时长(秒)
progressComputedRef<number>播放进度 (0-100)
hasNextComputedRef<boolean>是否有下一首
hasPreviousComputedRef<boolean>是否有上一首
formattedCurrentTimeComputedRef<string>格式化当前时间 mm:ss
formattedDurationComputedRef<string>格式化总时长 mm:ss
playModeTextComputedRef<string>播放模式文本
playModeIconComputedRef<string>播放模式图标类名

▶️ 播放控制

方法参数说明
play(song?, index?)Song, number播放指定歌曲
pause()-暂停播放
resume()-继续播放
togglePlay()-切换播放/暂停
next()-下一首
previous()-上一首
stop()-停止播放

🔁 播放模式

方法参数说明
togglePlayMode()-循环切换播放模式
setPlayMode(mode)PlayMode设置指定播放模式

🔊 音量控制

方法参数说明
setVolume(vol)number (0-1)设置音量
toggleMute()-切换静音

⏱️ 进度控制

方法参数说明
setProgress(prog)number (0-100)设置播放进度百分比
setCurrentTime(time)number设置播放时间(秒)

📋 播放列表管理

方法参数说明
addSong(song)Song添加歌曲到列表
addSongs(songs)Song[]批量添加歌曲
removeSong(id)string | number移除歌曲
removeSongs(ids)Array<string | number>批量移除
clearPlaylist()-清空播放列表
setPlaylist(songs, startIndex?)Song[], number设置播放列表
playByIndex(index)number播放指定索引歌曲
moveSong(from, to)number, number移动歌曲位置
queueNext(id)string | number添加到下一首播放

🔧 其他

方法说明
clearHistory()清空播放历史
clearError()清除错误信息
handleKeyboard(event)处理键盘事件
setupMediaSession()设置系统媒体控制

💡 使用示例

vue
<script setup lang="ts">
import { useAudio } from '@/composables/useAudio'

const {
  currentSong,
  isPlaying,
  progress,
  formattedCurrentTime,
  formattedDuration,
  togglePlay,
  next,
  previous,
  setProgress,
} = useAudio()
</script>

<template>
  <div class="player">
    <div v-if="currentSong">
      <img :src="currentSong.cover" />
      <span>{{ currentSong.name }} - {{ currentSong.artist }}</span>
    </div>
    
    <div class="controls">
      <button @click="previous">上一首</button>
      <button @click="togglePlay">
        {{ isPlaying ? '暂停' : '播放' }}
      </button>
      <button @click="next">下一首</button>
    </div>
    
    <div class="progress">
      <span>{{ formattedCurrentTime }}</span>
      <input
        type="range"
        :value="progress"
        @input="setProgress($event.target.value)"
      />
      <span>{{ formattedDuration }}</span>
    </div>
  </div>
</template>

📝 useLyrics

歌词解析与同步的组合式函数。

📁 文件位置src/composables/useLyrics.ts

📘 类型定义

ts
interface LyricLine {
  time: number      // 时间戳(秒)
  ori: string       // 原文歌词
  tran?: string     // 翻译歌词
  roma?: string     // 罗马音
}

📤 返回值

属性/方法类型说明
lyricsOriginalRef<RawLyricLine[]>原始歌词数组
lyricsTransRef<RawLyricLine[]>翻译歌词数组
lyricsRomaRef<RawLyricLine[]>罗马音数组
showTransRef<boolean>是否显示翻译
showRomaRef<boolean>是否显示罗马音
mergedLinesComputedRef<LyricLine[]>合并后的歌词行
activeSingleLyricsComputedRef<LyricLine[]>活动歌词列表
activeTimelineComputedRef<number[]>时间轴数组
loadingRef<boolean>是否加载中
fetchLyrics(id, force?)Function获取歌词
timeForIndex(index)Function获取指定索引的时间

💡 使用示例

vue
<script setup lang="ts">
import { useLyrics } from '@/composables/useLyrics'
import { useAudio } from '@/composables/useAudio'

const { activeSingleLyrics, fetchLyrics, loading } = useLyrics()
const { currentSong, currentTime } = useAudio()

watch(() => currentSong.value?.id, (id) => {
  if (id) fetchLyrics(id)
})

const currentLineIndex = computed(() => {
  const time = currentTime.value
  let idx = 0
  for (let i = 0; i < activeSingleLyrics.value.length; i++) {
    if (activeSingleLyrics.value[i].time <= time) idx = i
    else break
  }
  return idx
})
</script>

<template>
  <div class="lyrics">
    <div v-if="loading">加载中...</div>
    <div
      v-for="(line, i) in activeSingleLyrics"
      :key="i"
      :class="{ active: i === currentLineIndex }"
    >
      <p class="ori">{{ line.ori }}</p>
      <p v-if="line.tran" class="tran">{{ line.tran }}</p>
    </div>
  </div>
</template>

⌨️ useGlobalKeyboard

全局键盘快捷键支持。

📁 文件位置src/composables/useAudio.ts

📤 返回值

方法说明
enableGlobalKeyboard()启用全局键盘监听
disableGlobalKeyboard()禁用全局键盘监听

💡 使用示例

vue
<script setup lang="ts">
import { useGlobalKeyboard } from '@/composables/useAudio'

const { enableGlobalKeyboard, disableGlobalKeyboard } = useGlobalKeyboard()

onMounted(() => {
  enableGlobalKeyboard()
})

onUnmounted(() => {
  disableGlobalKeyboard()
})
</script>

🎹 支持的快捷键

按键功能
Space播放/暂停
ArrowLeft快退 10 秒
ArrowRight快进 10 秒
Ctrl + ArrowLeft上一首
Ctrl + ArrowRight下一首
ArrowUp音量 +10%
ArrowDown音量 -10%
M静音切换
R切换播放模式

基于 PolyForm-Noncommercial-1.0.0 许可发布