Vue3全家桶实战:从零搭建网易云音乐Web端完整项目
2026/9/17 11:52:48 网站建设 项目流程

2026年了,前端面试和毕业设计早就不看“会不会用Vue”,而是看“能不能拿一个完整项目讲清楚组件、状态、路由、接口联调、性能优化”。这次要聊的这个 Vue3 网易云音乐实战项目,正好就是打在这两个点上:技术栈是 Vue3 全家桶,业务是一个可演示、可截图的音乐播放器,还带源码和文档。

先一句话说清楚它能干什么:从零开始搭一个前后端分离的网易云音乐 Web 端项目,包括推荐歌单、排行榜、搜索、播放器、歌词展示、登录态处理这些高频功能。源码目录完整,文档覆盖从环境准备到部署上线的过程,既能当毕设交差,也能当面试项目讲。

这篇博客会按实际开发顺序,把项目从环境准备、接口服务启动、前端工程创建、核心功能实现,一直讲到调试、打包、面试怎么讲。源码可以下载,但建议先把我下面的流程走一遍,至少两小时能跑通。

1. 核心能力速览

能力项说明
项目类型前后端分离的单页应用(SPA)实战项目
前端技术栈Vue3 + Vite + Pinia + Vue Router + Axios
后端数据源网易云音乐公开接口服务,本地启动,通过 HTTP 请求获取音乐数据
主要功能推荐页、排行榜、歌单详情、搜索、播放器、歌词展示、登录态保存
播放能力通过音频链接播放,支持播放/暂停/上一首/下一首/进度条切换
登录方式二维码登录或邮箱登录,登录后获取 cookie 并保存到本地
启动方式先启动接口服务,再启动前端开发服务器
是否支持 API支持,项目内封装统一请求模块,可二次开发
是否支持批量任务不涉及批量任务,但支持列表数据按分页加载
适合人群Vue3 初学者、前端应届生、毕业设计学生、需要面试项目经验的开发者

从资料看,这个项目的重点不是把界面做得像网易云,而是让你跑通一条完整链路:前端页面 -> 请求封装 -> 接口服务 -> 音乐数据 -> 播放器渲染。这条链路就是你面试时能讲清楚的核心。

2. 适用场景与使用边界

这个项目适合三类人。

第一类是准备毕业设计的同学。音乐播放器需求明确、功能边界清楚、可截图可录屏,答辩时展示效果好,而且“接口对接”本身就是加分项。

第二类是准备前端面试的人。Vue3 面试题里常问的refreactivecomputedwatchPiniaVue RouterAxios拦截器,在这套源码里都能找到对应实现。你不需要背题,直接讲“我项目里在哪用了、为什么这么用”就可以。

第三类是刚学完 Vue3 基础、想找一个完整项目练手的人。比起重复写 TodoList,这种带真实接口、有异步数据、有播放器状态管理的项目,能帮你把零散知识点串起来。

使用边界也要说清楚。

接口服务本质是逆向网易云音乐网页版接口,只适合学习、个人测试和毕设演示,不能用于商用,也不能直接部署上线对外提供服务。登录功能涉及用户 cookie,本地开发时不要把自己的账号 cookie 提交到公开仓库。如果需要公开源码,建议把登录接口和 cookie 相关逻辑做脱敏处理,或者只保留游客模式。

另外,项目里的音乐资源版权归网易云音乐官方所有。演示时使用免费歌曲或试听片段没有问题,但不要把这些音频资源打包进项目分发,更不要用于任何商业场景。

一句话总结:本地跑通、学习原理、毕业展示,没问题;商用或大量分发,不行。

3. 环境准备与前置条件

从标题看,项目是“从零开始手把手教学”,所以环境准备部分必须干净。下面给出一套通用检查清单,具体版本号以你本机安装结果为准。

3.1 安装 Node.js

Vue3 和 Vite 都运行在 Node.js 环境上。建议安装 Node.js 的 LTS 版本,通常 18 或 20 以上即可。安装完成后,在终端执行:

node -v npm -v

如果两个命令都能输出版本号,说明 Node.js 环境正常。

如果你喜欢用 pnpm 或 yarn,也可以装一个:

npm install -g pnpm

3.2 准备接口服务

网易云音乐 Vue3 实战项目通常依赖一个独立的接口服务来提供音乐数据,常见方案是开源的 NeteaseCloudMusicApi 项目。你需要把它单独下载到本地某个目录,然后启动。

git clone https://github.com/Binaryify/NeteaseCloudMusicApi.git cd NeteaseCloudMusicApi npm install npm start

默认情况下,接口服务会运行在http://localhost:3000。启动成功后,浏览器直接访问这个地址,能看到接口文档首页。

这里有一个常见的坑:如果你下载的代码版本较新,可能需要更高版本的 Node.js。如果npm install报错,优先检查 Node.js 版本,而不是反复重装依赖。

3.3 准备前端项目源码

假设你已经下载了本项目的源码压缩包或克隆到了douyin-music之类的前端目录。目录结构可能长这样:

douyin-music ├── public ├── src │ ├── api │ ├── assets │ ├── components │ ├── router │ ├── stores │ ├── views │ ├── App.vue │ └── main.js ├── .env.development ├── package.json └── README.md

src/api是接口请求封装目录,src/stores是 Pinia 状态管理目录,src/views是页面视图目录。先记住这几个目录的位置,后面调试和面试讲项目都会用到。

3.4 常见问题:端口被占用

接口服务默认占用 3000 端口,前端开发服务器默认占用 5173 端口。如果这两个端口被其他程序占用,启动时会报错。排查方式:

lsof -i :3000 lsof -i :5173

如果端口占用,要么关掉对应进程,要么在配置里改端口。后面第 8 节会详细讲。

4. 安装部署与启动方式

环境准备好之后,按照下面的顺序启动。先启动接口服务,再启动前端工程,不要倒过来。

4.1 启动网易云音乐接口服务

打开终端,进入接口服务目录:

cd NeteaseCloudMusicApi npm start

启动日志里会显示端口号,通常是3000。验证方式:打开浏览器输入http://localhost:3000,能看到接口文档地址或者返回 JSON,说明服务正常。

为了保险,可以先请求一个最简单的接口:

curl http://localhost:3000/personalized?limit=3

如果返回 JSON 数据,里面包含推荐歌单列表,说明接口通了。

4.2 安装前端项目依赖

切换到前端项目目录:

cd douyin-music npm install

安装过程可能耗时几分钟。如果某些依赖安装失败,可以尝试:

npm install --registry=https://registry.npmmirror.com

这是国内镜像源,下载速度更快,也能解决部分网络问题。

4.3 配置接口地址环境变量

很多实战项目会把接口地址放到.env.development文件里,这样写代码的时候不用把域名写死。

VITE_BASE_API=http://localhost:3000

如果接口服务地址不同,改这个文件就行。改完后需要重启前端开发服务器才会生效。

4.4 启动前端开发服务器

npm run dev

启动成功后,终端会输出本地访问地址,通常是http://localhost:5173

在浏览器打开这个地址,如果能看到页面,并且首页能加载出推荐歌单或排行榜数据,说明前后端已经打通。

4.5 打包构建

毕设或面试前需要部署演示,执行:

npm run build

构建产物会输出到dist目录。把dist目录放到任意静态服务器上即可访问。Vite 默认用绝对路径,如果你要部署到子路径,需要改base配置,这里先不展开。

5. 核心功能模块与测试验证

项目跑通之后,逐项验证核心功能。下面按照“页面 -> 测试步骤 -> 预期结果”的方式列出,每项都能截图和录屏。

5.1 首页推荐

打开首页,通常包含轮播图和推荐歌单列表。

测试步骤:

  1. 确认首页能看到轮播图,图片能正常加载。
  2. 下拉页面,推荐歌单列表能显示专辑封面和名称。
  3. 点击一个推荐歌单,跳转到歌单详情页。

预期结果:

  1. 数据来自接口服务,不是写死在前端的。
  2. 歌单封面图加载速度正常,没有大量裂图。

如果首页空白,先打开浏览器开发者工具 Network 面板,看接口请求是否返回 200。如果请求 404,检查接口地址配置。

5.2 排行榜

进入排行榜页面,至少验证三个点:

  1. 榜单分类是否显示完整。
  2. 点击榜单后,歌曲列表是否加载。
  3. 歌曲列表是否有评分或播放次数等字段。

排行榜接口的特点是返回数据大,容易因为渲染性能问题造成页面卡顿。如果数据量很大,可以观察列表滚动是否流畅,这对应着后面的性能优化。

5.3 搜索

搜索是前端面试里高频考点,很多项目会把搜索框、防抖、请求时序控制放在一起考察。

测试步骤:

  1. 在顶部搜索框输入关键词,比如“周杰伦”或“海阔天空”。
  2. 查看搜索结果是否包含“单曲”“歌手”“专辑”“歌单”等多个分类。
  3. 快速多次输入不同关键词,观察页面是否出现旧数据覆盖新数据的问题。

预期结果:

  1. 搜索结果按分类展示。
  2. 最后一次输入的关键词结果,不会被前一次搜索结果覆盖。

这个测试点很重要,背后对应的是请求竞态处理,面试时可以重点讲。

5.4 播放器

播放器是这个项目最大的亮点,也是最容易出问题的模块。

测试步骤:

  1. 点击任意一首歌曲的播放按钮。
  2. 观察底部播放器是否出现歌曲名、歌手名、专辑封面。
  3. 点击播放/暂停,确认按钮状态切换正常。
  4. 拖动进度条,确认音频跳转位置正确。
  5. 点击“下一首”,确认播放列表按顺序切换。

预期结果:

  1. 歌曲可以正常播放,没有跨域或 403 错误。
  2. 播放器状态和页面状态联动,比如当前播放歌曲的列表项有特殊高亮。

这里最常见的报错是音频 URL 403。原因是部分音乐链接需要携带正确的 Referer 头,如果接口服务处理不好,音频会拒绝播放。遇到这个问题,优先检查接口服务和前端页面的域名是否一致,或者查看接口文档里关于音频 URL 的说明。

5.5 歌词展示

歌词功能能体现一个项目做没做完整。

测试步骤:

  1. 播放一首歌词接口能返回的歌曲。
  2. 播放时,页面是否展示歌词。
  3. 随着播放进度变化,歌词是否逐行高亮。

预期结果:

  1. 歌词能随播放进度滚动。
  2. 当前歌词行高亮显示。

如果歌词一直为空,先确认歌曲本身是否提供歌词接口,再检查接口返回的数据结构,看看是lrc字段还是lyric字段。

5.6 登录态

登录功能这里要特别强调:只建议用于学习测试,不要用真实高频账号。

测试步骤:

  1. 点击登录按钮,选择二维码或邮箱登录。
  2. 登录成功后,页面右上角显示用户头像或昵称。
  3. 刷新页面,确认登录状态是否保留。

预期结果:

  1. 登录后能获取用户相关信息。
  2. 刷新后通过 cookie 恢复登录状态。

如果刷新后登录态丢失,重点检查登录接口返回的 cookie 是否被正确保存,以及 Axios 请求配置是否设置了withCredentials

5.7 收藏与歌单

如果项目包含收藏功能,测试关注:

  1. 点击收藏按钮,按钮状态是否变化。
  2. 重新进入页面,收藏状态是否保持。

收藏功能涉及用户维度的数据,通常依赖登录态。未登录状态下点击收藏,预期应跳转登录或给出提示。

6. 接口层设计与请求封装

接口层是前后端分离项目里最重要的工程化设计之一。面试时,这一节讲清楚了,比你背十道 Vue3 面试题都有用。

6.1 统一 Axios 请求封装

项目里一般会有一个src/api/request.jssrc/utils/request.js,核心作用是把 Axios 实例、拦截器、错误处理统一起来。

import axios from 'axios' const request = axios.create({ baseURL: import.meta.env.VITE_BASE_API, timeout: 10000 }) request.interceptors.request.use(config => { const cookie = localStorage.getItem('music_cookie') if (cookie) { config.headers.Cookie = cookie } return config }) request.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { return Promise.reject(new Error(res.message || '请求失败')) } return res }, error => { return Promise.reject(error) } ) export default request

这段代码体现了三个面试点:baseURL从环境变量读取、请求拦截器注入 cookie、响应拦截器统一处理错误码。

6.2 接口模块拆分

页面里不要直接写request.get('/personalized'),而是把接口按业务模块拆分到src/api目录。

import request from '@/utils/request' export function getPersonalized() { return request({ url: '/personalized', method: 'get' }) } export function getSongUrl(id) { return request({ url: '/song/url', method: 'get', params: { id } }) } export function getLyric(id) { return request({ url: '/lyric', method: 'get', params: { id } }) }

这样做的收益是:接口地址集中管理,修改接口路径不用全局搜索;组件的代码更干净;接口模块可以单独做单元测试。

6.3 搜索接口的竞态处理

搜索框快速输入时,先发的请求可能后返回,导致旧结果覆盖新结果。常见解决方案是保存一个请求序号,或者使用 AbortController 取消上一次请求。

import { ref } from 'vue' const searchLoading = ref(false) let reqId = 0 async function handleSearch(keyword) { const currentId = ++reqId searchLoading.value = true const res = await searchMusic(keyword) if (currentId === reqId) { searchList.value = res.result.songs searchLoading.value = false } }

这段逻辑在面试里很加分,因为它说明你不只是会调接口,还理解异步竞态。

7. 性能优化与资源占用观察

7.1 路由懒加载

Vue3 实战项目工程化好不好,第一个看路由配置。路由懒加载能减少首屏加载时间。

const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', name: 'Home', component: () => import('@/views/Home.vue') }, { path: '/playlist/:id', name: 'PlaylistDetail', component: () => import('@/views/PlaylistDetail.vue') } ] })

7.2 图片懒加载

歌单封面和排行榜图片数量多,全量加载会拖慢首屏。可以在项目里安装vue-lazyload或使用原生loading="lazy"

<img v-lazy="playlist.coverImgUrl" alt="封面" />

7.3 组件拆分

一个页面几十行是正常的,但一个页面几百行就该拆组件了。以播放器为例,合理的拆分方式:

components ├── Player │ ├── PlayerBar.vue │ ├── PlayerLyric.vue │ └── PlayList.vue

播放器作为全局组件挂在App.vue里,用 Pinia 管理播放状态,页面只负责触发播放。

7.4 资源占用观察

前端项目不像 AI 模型那样有显存占用,但没有明确材料依据,不要编造。可以用浏览器开发者工具的 Performance 面板和 Vue Devtools 观察:

  1. 打开浏览器 DevTools,进入 Network 面板,看首屏请求数量和资源体积。
  2. 切到 Performance 面板,点击录制,然后操作页面,观察主线程占用和长任务。
  3. 如果列表滚动卡顿,检查是不是渲染了大量 DOM 节点。

优化方向是明确的:减少首屏无关请求、路由懒加载、图片懒加载、列表虚拟滚动。

8. 常见问题与排查方法

问题现象可能原因排查方式解决方案
首页数据加载不出来接口服务未启动或地址配置错误访问 http://localhost:3000 看是否返回 JSON启动接口服务,检查.env.development里的VITE_BASE_API
接口返回 404接口路径写错或某个接口需要额外参数对比接口文档,Network 面板查看请求 URL修正请求路径或补全参数
音频无法播放,控制台报 403音频 URL 缺少 Referer 头或已过期Network 面板查看音频请求响应确认接口服务版本;前端可尝试携带合理 Referer
播放器切歌后歌词不同步歌词接口返回的是原始歌词,没有按时间解析console 打印歌词数据结构查看歌词数据字段,如果返回的是字符串,需要做 lrc 格式解析
登录后刷新掉登录态cookie 未保存或请求未携带 cookie查看 localStorage 中是否保存 cookie,请求头是否带 Cookie设置withCredentials,并在请求拦截器注入 cookie
点击播放后没有声音播放器 audio 元素没有正确绑定 srcVue Devtools 查看当前播放歌曲 URL检查getSongUrl接口返回的 URL 字段名
npm install 报错Node 版本过低或依赖冲突终端查看完整报错日志升级 Node.js,换镜像源安装
端口被占用服务启动时提示 address already in uselsof -i :3000查看占用进程换端口启动或关闭占用进程

这 8 个问题是这个类型项目的主要故障点,排查时一定按顺序来:先看接口服务通不通,再看前端请求到不到位,最后看渲染层。

9. 最佳实践与改造建议

9.1 毕设答辩演示顺序

不要一上来就点开播放器。建议按这个顺序演示:

  1. 先打开接口服务终端,展示接口请求日志。
  2. 再打开前端页面,展示推荐页。
  3. 从点击歌单,到进入详情,再到点击播放。
  4. 最后展示搜索功能和登录态。

这套顺序体现了“前后端分离”这个关键词,比直接播歌更有说服力。

9.2 目录结构管理

模型文件、源码、文档、接口服务分开目录。比如:

project ├── doc # 项目文档 ├── douyin-music # 前端源码 ├── NeteaseCloudMusicApi # 接口服务 └── README.md

这样无论是自己后续开发,还是交给指导老师审查,都不会乱。

9.3 面试怎么讲

面试官如果问“这个项目你负责哪些模块”,不要回答“我都写了”。建议选 2 到 3 个模块讲深一点:

  • 播放器模块:讲 Pinia 状态设计,播放列表如何管理,切歌逻辑如何实现。
  • 搜索模块:讲防抖、竞态处理、接口拆分。
  • 接口层设计:讲 Axios 封装、环境变量配置、cookie 处理。

每个模块都能落到具体代码位置,比背题效果强得多。

9.4 可扩展的方向

跑通项目之后,可以尝试加这些功能:

  • 收藏歌曲:涉及登录态和用户维度接口。
  • 历史播放记录:用 localStorage 持久化,前端面试常问。
  • 评论模块:涉及时间格式化、分页加载和按热度排序。
  • 响应式适配:移动端下播放器和歌单展示如何调整。

每加一个功能,项目简历上都多一个可展开的点。

10. 总结与下一步

这个 Vue3 网易云音乐实战项目最值得尝试的点有两处,一个是前端工程链路完整,另一个是播放器状态管理有真实业务复杂度,这两个点足够撑起一次毕业答辩或一轮前端技术面试。

先说建议优先验证的功能:首页推荐数据和播放器播放。这两个打通了,项目后续基本能顺畅跑起来。

再说最容易踩的坑:接口服务和前端项目的启动顺序,以及音频 URL 403。启动顺序错了,页面一片空白;音频 403 了,播放器看着是好的但就是没声音。这两个问题排查一次就记住了。

接下来可以做什么?第一,把项目源码完整读一遍,特别是src/apisrc/storessrc/components/Player这三个目录。第二,挑一个自己薄弱的功能模块,比如搜索或歌词解析,重新写一遍。第三,把日志、错误处理、加载状态补齐,让项目从“能跑”提升为“像工业级项目”。

如果你打算把它作为面试项目,建议在 README 里写清楚技术栈、启动方式和核心模块说明,面试官第一眼就能看到你的项目价值。收藏这篇文章,部署的时候照着操作,基本能一次跑通。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询