musiclist的绘制ui与其功能为强耦合导致无法复用,只能我自己写点函数凑合用

pull/2369/head
QiuLiang-99 2025-05-04 01:09:09 +08:00
parent 5ded7c7e19
commit 0affe04683
2 changed files with 105 additions and 39 deletions

View File

@ -1,48 +1,81 @@
<template> <template>
<div class="playlist-window"> <div class="playlist-window">
<button class="close-button" @click="emitClose"></button> <button class="close-button" @click="emitClose"></button>
<h2 class="title">播放列表</h2> <h2 class="title">播放列表</h2>
<div class="song-list"> <div class="song-list">
<div v-for="(song, index) in songs" :key="index" class="song-item"> <div
<div class="song-index">{{ index + 1 }}</div> v-for="(song, index) in songs"
<div class="song-info"> :key="index"
<div class="song-title">{{ song.title }}</div> class="song-item"
<div class="song-meta">{{ song.artist }} · {{ song.album }}</div> :class="[
</div> { active: currentPlayIndexValue === index },
{ selected: selectedIndex === index || rightClickSelectedIndex === index }
]"
@click="handleListItemClick(index)"
@contextmenu.prevent="handleListItemRightClick(index, $event)"
>
<div class="song-index">{{ index + 1 }}</div>
<div class="song-info">
<div class="song-title">{{ song.title }}</div>
<div class="song-meta">{{ song.artist }} · {{ song.album }}</div>
</div> </div>
</div> </div>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, computed } from 'vue' import { ref, computed, toRef } from 'vue'
import { tempPlayList, currentPlaybackOrder } from '@renderer/store/player/state' import { tempPlayList, currentPlaybackOrder, currentPlayIndex } from '@renderer/store/player/state'
// 便使 .value
const currentPlayIndexValue = toRef(currentPlayIndex, 'value')
const emit = defineEmits(['close']) const emit = defineEmits(['close'])
// todo item
// todo item // ref reactive
const playlist = ref(tempPlayList) const playlist = ref(tempPlayList)
//
const songs = computed(() => { const songs = computed(() => {
let showlist = [] const showlist = []
for (const index of currentPlaybackOrder.value) { for (const idx of currentPlaybackOrder.value) {
const playMusicInfo = playlist.value[index] const info = playlist.value[idx]
showlist.push({ if (info && info.musicInfo) {
title: playMusicInfo.musicInfo.name, showlist.push({
artist: playMusicInfo.musicInfo.singer, title: info.musicInfo.name,
album: playMusicInfo.musicInfo.meta.albumName, artist: info.musicInfo.singer,
}) album: info.musicInfo.meta.albumName,
})
}
} }
return showlist return showlist
}, })
)
const emitClose = () => { //
const selectedIndex = ref(null)
const rightClickSelectedIndex = ref(null)
//
function handleListItemClick(index) {
selectedIndex.value = index
// currentPlayIndex
currentPlayIndex.value = index
}
//
function handleListItemRightClick(index, event) {
rightClickSelectedIndex.value = index
// event.clientX/Y
}
//
function emitClose() {
emit('close') emit('close')
} }
</script> </script>
<style scoped> <style scoped>
.playlist-window { .playlist-window {
background-color: #222; background-color: #222;
color: white; color: white;
@ -51,18 +84,11 @@ const emitClose = () => {
width: 320px; width: 320px;
max-height: 80%; max-height: 80%;
overflow-y: auto; overflow-y: auto;
position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.title { /* 关闭按钮 */
margin-bottom: 15px;
font-size: 18px;
font-weight: bold;
text-align: center;
}p
.close-button { .close-button {
position: absolute; position: absolute;
top: 10px; top: 10px;
@ -74,48 +100,88 @@ const emitClose = () => {
cursor: pointer; cursor: pointer;
} }
/* 标题 */
.title {
margin-bottom: 15px;
font-size: 18px;
font-weight: bold;
text-align: center;
color: white;
}
/* 歌曲列表容器 */
.song-list { .song-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px;
} }
/* 交替背景:奇数白色,偶数浅灰 */
.song-item:nth-child(2n-1) {
background-color: #ffffff;
}
.song-item:nth-child(2n) {
background-color: #f5f5f5; /* 很浅的灰 */
}
/* 通用样式 */
.song-item { .song-item {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 10px; padding: 10px;
border-radius: 6px; border-radius: 6px;
background-color: #2c2c2c;
transition: background-color 0.2s; transition: background-color 0.2s;
cursor: pointer;
color: black; /* 字体统一黑色 */
} }
/* hover 状态稍微加深一下 */
.song-item:hover { .song-item:hover {
background-color: #3a3a3a; background-color: #eaeaea;
} }
/* 当前播放项高亮(深灰) */
.active {
background-color: #555555 !important;
color: black !important;
}
/* 选中(左键或右键)状态,更深的灰 */
.selected {
background-color: #333333 !important;
color: black !important;
}
/* 序号 */
.song-index { .song-index {
width: 24px; width: 24px;
text-align: right; text-align: right;
margin-right: 10px; margin-right: 10px;
color: #aaa; color: #666666;
font-size: 14px; font-size: 14px;
flex-shrink: 0;
} }
/* 歌曲信息 */
.song-info { .song-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
} }
/* 标题 */
.song-title { .song-title {
font-size: 16px; font-size: 16px;
font-weight: 500;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
color: black;
} }
/* 元信息(歌手 · 专辑) */
.song-meta { .song-meta {
font-size: 12px; font-size: 12px;
color: #888; color: #444444;
margin-top: 2px;
} }
</style> </style>

View File

@ -69,7 +69,7 @@ export const playInfo = shallowReactive<LX.Player.PlayInfo>({
export const playedList = window.lxData.playedList = shallowReactive<LX.Player.PlayMusicInfo[]>([]) export const playedList = window.lxData.playedList = shallowReactive<LX.Player.PlayMusicInfo[]>([])
export const tempPlayList = shallowReactive<LX.Player.PlayMusicInfo[]>([])//todo export const tempPlayList = shallowReactive<LX.Player.PlayMusicInfo[]>([])
export const currentPlayIndex = ref<number>(0) export const currentPlayIndex = ref<number>(0)