📅 我们继续 50 个小项目挑战!—— SoundBoard
组件
🎯 组件目标
实现一个响应式按钮面板,点击某一按钮即可播放对应音频。
点击新按钮时自动停止其他音效,确保每次只有一个音频在播放。
利用 Vue3 组合式 API + 原生 DOM 控制,打造高效小巧的功能组件。
🛠️ 技术实现点
使用
Vue3
<script setup>
编写逻辑,简洁明了。利用
ref
存储音频列表数据,支持动态遍历。使用
document.getElementById
原生API
获取音频DOM
元素,控制播放行为。Tailwind CSS
控制按钮样式及悬停动画,增强交互感。
🧱 组件实现源码(含注释)
<template>
<div class="flex h-screen items-center gap-10 justify-center text-black">
<!-- 遍历音效列表,渲染按钮,每个按钮对应一个 <audio> 元素 -->
<div
class="rounded-lg border-2 bg-gray-300 px-8 py-4 hover:scale-105 hover:bg-gray-400"
v-for="(item, index) in soundList"
:key="item.id"
@click="handlePlayAudio(index)">
{{ item.name }}
<audio :id="item.id" :src="item.src"></audio>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
// 音效播放控制函数
const handlePlayAudio = (index) => {
// 暂停所有音效,重置播放进度
soundList.value.forEach((sound) => {
const audio = document.getElementById(sound.id)
audio.pause()
audio.currentTime = 0
})
// 播放当前选中的音效
const selectedAudio = document.getElementById(soundList.value[index].id)
selectedAudio.play()
}
// 音效列表:可以根据需求拓展为动态加载或远程配置
const soundList = ref([
{ id: 1, name: 'applause 👏', src: '/src/assets/sounds/applause.mp3' },
{ id: 2, name: 'boo 😒', src: '/src/assets/sounds/boo.mp3' },
{ id: 3, name: 'gasp 😲', src: '/src/assets/sounds/gasp.mp3' },
{ id: 4, name: 'tada 🎉', src: '/src/assets/sounds/tada.mp3' },
{ id: 5, name: 'victory 🏆', src: '/src/assets/sounds/victory.mp3' },
{ id: 6, name: 'wrong ❌', src: '/src/assets/sounds/wrong.mp3' },
])
</script>
💡 样式与逻辑讲解
- 样式部分
类名 | 功能描述 |
---|---|
flex h-screen items-center justify-center |
垂直居中音效按钮面板 |
gap-10 |
按钮之间间距 |
rounded-lg border-2 px-8 py-4 |
按钮基础样式 |
hover:scale-105 hover:bg-gray-400 |
鼠标悬停时的放大 + 背景变化动画 |
text-black |
文字颜色 |
- 逻辑部分
函数 | 功能 |
---|---|
handlePlayAudio(index) |
播放第 index 个音效,并停止其他音频 |
soundList |
音效数据源,每个元素包含 id、name、src 三个字段 |
document.getElementById() |
获取原生 DOM 元素,用于控制 标签 |
🧾 常量定义 + 组件路由建议
constants/index.js
添加组件预览常量:
export const projectList = [
{
id: 9,
title: 'Sound Board',
image: 'https://50projects50days.com/img/projects-img/9-sound-board.png',
link: 'SoundBoard',
},
]
router/index.js
中添加路由选项:
{
path: '/SoundBoard',
name: 'SoundBoard',
component: () => import('@/projects/SoundBoard.vue'),
},
🧾 总结
本组件展示了如何在 Vue3 中结合 DOM 操作与响应式数据,实现一个轻量级、趣味性十足的音效选择器,非常适合作为日常 UI 组件库的娱乐增强模块。
👉 下一篇,我们将完成 Dad Jokes
组件,一个利用公共的API
获取数据随机生成笑话的组件!🚀