Skip to content

Commit b239b3b

Browse files
author
Taois
committed
feat: 设置界面配置地址优化
优化空间占用和美观效果
1 parent 9536e53 commit b239b3b

File tree

2 files changed

+446
-173
lines changed

2 files changed

+446
-173
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
<template>
2+
<a-modal
3+
v-model:visible="visible"
4+
title="选择播放器"
5+
:width="500"
6+
:mask-closable="false"
7+
@ok="handleConfirm"
8+
@cancel="handleCancel"
9+
>
10+
<div class="player-selector">
11+
<div class="player-list">
12+
<div
13+
v-for="player in playerTypes"
14+
:key="player.value"
15+
class="player-item"
16+
:class="{ active: selectedPlayer === player.value }"
17+
@click="selectedPlayer = player.value"
18+
>
19+
<div class="player-info">
20+
<div class="player-icon">
21+
<icon-play-circle v-if="player.value === 'art'" />
22+
<icon-code v-else-if="player.value === 'ijk'" />
23+
<icon-mobile v-else-if="player.value === 'exo'" />
24+
<icon-desktop v-else-if="player.value === 'mpv'" />
25+
<icon-video-camera v-else-if="player.value === 'vlc'" />
26+
<icon-play-arrow v-else />
27+
</div>
28+
<div class="player-details">
29+
<div class="player-name">{{ player.label }}</div>
30+
<div class="player-desc">{{ player.description }}</div>
31+
</div>
32+
</div>
33+
<div class="player-check">
34+
<icon-check-circle v-if="selectedPlayer === player.value" class="check-icon" />
35+
</div>
36+
</div>
37+
</div>
38+
</div>
39+
</a-modal>
40+
</template>
41+
42+
<script setup>
43+
import { ref, watch } from 'vue'
44+
import {
45+
IconPlayCircle,
46+
IconCode,
47+
IconMobile,
48+
IconDesktop,
49+
IconVideoCamera,
50+
IconPlayArrow,
51+
IconCheckCircle
52+
} from '@arco-design/web-vue/es/icon'
53+
54+
const props = defineProps({
55+
visible: {
56+
type: Boolean,
57+
default: false
58+
},
59+
playerTypes: {
60+
type: Array,
61+
default: () => []
62+
},
63+
currentPlayer: {
64+
type: String,
65+
default: 'ijk'
66+
}
67+
})
68+
69+
const emit = defineEmits(['update:visible', 'confirm'])
70+
71+
const visible = ref(props.visible)
72+
const selectedPlayer = ref(props.currentPlayer)
73+
74+
// 监听props变化
75+
watch(() => props.visible, (newVal) => {
76+
visible.value = newVal
77+
})
78+
79+
watch(() => props.currentPlayer, (newVal) => {
80+
selectedPlayer.value = newVal
81+
})
82+
83+
watch(visible, (newVal) => {
84+
emit('update:visible', newVal)
85+
})
86+
87+
const handleConfirm = () => {
88+
emit('confirm', selectedPlayer.value)
89+
visible.value = false
90+
}
91+
92+
const handleCancel = () => {
93+
selectedPlayer.value = props.currentPlayer // 恢复原始值
94+
visible.value = false
95+
}
96+
</script>
97+
98+
<style scoped>
99+
.player-selector {
100+
padding: 16px 0;
101+
}
102+
103+
.player-list {
104+
display: flex;
105+
flex-direction: column;
106+
gap: 12px;
107+
}
108+
109+
.player-item {
110+
display: flex;
111+
align-items: center;
112+
justify-content: space-between;
113+
padding: 16px;
114+
border: 2px solid #e5e7eb;
115+
border-radius: 12px;
116+
cursor: pointer;
117+
transition: all 0.3s ease;
118+
background: #ffffff;
119+
}
120+
121+
.player-item:hover {
122+
border-color: #3b82f6;
123+
background: #f8faff;
124+
transform: translateY(-2px);
125+
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);
126+
}
127+
128+
.player-item.active {
129+
border-color: #3b82f6;
130+
background: linear-gradient(135deg, #f8faff 0%, #eff6ff 100%);
131+
box-shadow: 0 4px 16px rgba(59, 130, 246, 0.2);
132+
}
133+
134+
.player-info {
135+
display: flex;
136+
align-items: center;
137+
gap: 16px;
138+
}
139+
140+
.player-icon {
141+
width: 48px;
142+
height: 48px;
143+
display: flex;
144+
align-items: center;
145+
justify-content: center;
146+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
147+
border-radius: 12px;
148+
color: white;
149+
font-size: 24px;
150+
}
151+
152+
.player-item.active .player-icon {
153+
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
154+
}
155+
156+
.player-details {
157+
flex: 1;
158+
}
159+
160+
.player-name {
161+
font-size: 16px;
162+
font-weight: 600;
163+
color: #1f2937;
164+
margin-bottom: 4px;
165+
}
166+
167+
.player-desc {
168+
font-size: 14px;
169+
color: #6b7280;
170+
line-height: 1.4;
171+
}
172+
173+
.player-check {
174+
width: 24px;
175+
height: 24px;
176+
display: flex;
177+
align-items: center;
178+
justify-content: center;
179+
}
180+
181+
.check-icon {
182+
font-size: 24px;
183+
color: #3b82f6;
184+
}
185+
186+
/* 响应式设计 */
187+
@media (max-width: 640px) {
188+
.player-item {
189+
padding: 12px;
190+
}
191+
192+
.player-icon {
193+
width: 40px;
194+
height: 40px;
195+
font-size: 20px;
196+
}
197+
198+
.player-info {
199+
gap: 12px;
200+
}
201+
202+
.player-name {
203+
font-size: 15px;
204+
}
205+
206+
.player-desc {
207+
font-size: 13px;
208+
}
209+
}
210+
</style>

0 commit comments

Comments
 (0)