50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Sound Board(音响控制面板)

📅 我们继续 50 个小项目挑战!------ SoundBoard 组件


🎯 组件目标

  • 实现一个响应式按钮面板,点击某一按钮即可播放对应音频。

  • 点击新按钮时自动停止其他音效,确保每次只有一个音频在播放。

  • 利用 Vue3 组合式 API + 原生 DOM 控制,打造高效小巧的功能组件。

🛠️ 技术实现点

  • 使用 Vue3 <script setup> 编写逻辑,简洁明了。

  • 利用 ref 存储音频列表数据,支持动态遍历。

  • 使用 document.getElementById 原生 API 获取音频 DOM 元素,控制播放行为。

  • Tailwind CSS 控制按钮样式及悬停动画,增强交互感。

🧱 组件实现源码(含注释)

html 复制代码
<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 添加组件预览常量:

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 中添加路由选项:

js 复制代码
{
        path: '/SoundBoard',
        name: 'SoundBoard',
        component: () => import('@/projects/SoundBoard.vue'),
    },

🧾 总结

本组件展示了如何在 Vue3 中结合 DOM 操作与响应式数据,实现一个轻量级、趣味性十足的音效选择器,非常适合作为日常 UI 组件库的娱乐增强模块。


👉 下一篇,我们将完成 Dad Jokes组件,一个利用公共的API获取数据随机生成笑话的组件!🚀

相关推荐
IT_陈寒19 小时前
Vite的HMR怎么突然失效了?原来是我太年轻
前端·人工智能·后端
ZC跨境爬虫19 小时前
Apple官网复刻第二阶段day_6:(统一页脚模块封装+CSS公共复用体系落地)
前端·css·ui·重构·html
恋猫de小郭19 小时前
Flutter 凉了没?Flutter 2026 的未来行程和规划,一些有趣的变化
android·前端·flutter
Beginner x_u19 小时前
前端手动实现大文件分片上传调度层:分片计算、并发上传与断点续传
前端·状态模式·断点续传·大文件分片上传
胖纳特19 小时前
Nextcloud 文件预览困局与破局:集成 BaseMetas Fileview 实现全格式在线预览
前端·后端
一个心烑19 小时前
Layui结合springboot读取返回值,前端展示简单示例
前端·spring boot·layui
天天向上102419 小时前
openlayers 加载Shapefile文件
前端·javascript·html
亿元程序员19 小时前
手工拼豆有风险?手把手教你开发个电子版的
前端
wuxianda103019 小时前
苹果App上架4.3a问题3天解决方案汇报总结
开发语言·javascript·uni-app·ecmascript·ios上架·苹果上架
hhhhhh_we19 小时前
再定义“皮肤人格”:从Baumann 16型分型到预颜美历的AI时序人格
前端·图像处理·人工智能·python·aigc