本文主要是介绍vue3 web在线音乐项目——蔚蓝音乐 开发记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
前言:
项目技术栈:
项目展示:
主页
歌单编辑
评论编辑
最新/最热 评论编辑
搜索 林俊杰编辑
歌曲mv:
歌词展示编辑
歌词滚动展示视频
详细开发步骤:
一、创建项目
1、使用vite构建项目
2.输入项目名称,默认是 vite-project
3.选择前端框架 Vue
4.选择项目类型 JavaScript
5.创建完毕并运行
二、安装配置插件
三、主页框架布局
四、登录功能
1、二维码生成接口
2、二维码生成接口
3、二维码检测扫码状态接口
五、音乐馆页面
1、轮播图
2、歌单组件
3、视频组件
六、歌单详情页面
1、头部信息区
2、tabs标签页
3、评论切换
4、歌曲列表playList组件
七、播放控件
1、样式布局
2、audio标签播放歌曲
3、暂停继续
4、上一首/下一首
5、播放进度
八、歌曲mv
九、搜索音乐
十、歌词滚动
1、布局
2、毛玻璃背景
3、旋转CD
4、滚动歌词
总结:
前言:
想基于vue3技术独立开发一个前端项目,以前做过一个基于vue2和uniapp仿网易云音乐的微信小程序,于是想再做个web版的。前端菜鸡一枚,仅个人记录,项目存在一些布局问题和逻辑bug。
项目技术栈:
vue3+vuex+vite+Element Plus+iconfont+网易云音乐API
项目展示:
主页
歌单
评论
最新/最热 评论
搜索 林俊杰
搜索 王力宏
歌曲mv:
歌词展示
歌词滚动展示视频
web-music歌词滚动展示
详细开发步骤:
一、创建项目
1、使用vite构建项目
# 使用 npm
npm create vite@latest
# 使用 yarn
yarn create vite
# 使用 pnpm
pnpm create vite
2.输入项目名称,默认是 vite-project
3.选择前端框架 Vue
4.选择项目类型 JavaScript
5.创建完毕并运行
cd 项目名
npm install 初始化
npm run dev 开发环境运行
二、安装配置插件
需要用到Element-Plus、vue-router、vuex,采用npm install
然后再main.js里导入,并app.use()
三、主页框架布局
采用elementplus的 Container 布局容器
左侧Aside 采用Menu菜单组件,不需要二级菜单,并修改激活菜单样式,开启路由模式
Header作为状态栏菜单
Footer作为播放控件
Main作为router-view展示左侧菜单对应路由页面
四、登录功能
因网易增加了网易云盾验证,密码登录暂时不能使用,尽量使用短信验证码登录和二维码登录,否则调用某些接口会触发需要验证的错误
二维码登录有以下步骤:
1、二维码生成接口
接口地址 : /login/qr/key 调用此接口生成一个key
2、二维码生成接口
说明: 调用此接口传入上一个接口生成的 key 可生成二维码图片的 base64 和二维码信息,可使用 base64 展示图片,或者使用二维码信息内容自行使用第三方二维码生成库渲染二维码
必选参数: key
,由第一个接口生成
可选参数: qrimg
传入后会额外返回二维码图片 base64 编码
接口地址 : /login/qr/create
调用例子 : /login/qr/create?key=xxx
3、二维码检测扫码状态接口
说明: 轮询此接口可获取二维码扫码状态,800 为二维码过期,801 为等待扫码,802 为待确认,803 为授权登录成功(803 状态码下会返回 cookies),如扫码后返回502,则需加上noCookie参数,如&noCookie=true
必选参数: key
,由第一个接口生成
接口地址 : /login/qr/check
调用例子 : /login/qr/check?key=xxx
扫码登录成功后返回如下账号信息数据:
将用得到的主要信息保存到vuex里的user模块,并储存到本地
五、音乐馆页面
1、轮播图
使用Carousel 走马灯组件里的卡片模式
调取banners轮播图接口获取数据
调用例子 : /banner
, /banner?type=2
使用v-for 将数组对象里的imgUrl值绑定到卡片里<img>的src属性
2、歌单组件
布局采用flex布局,一行多个歌单组件 flex-direction: row;横向排列,歌单组件内部上面图片和下面文字也采用flex布局flex-direction: column;纵向排列。
样式:鼠标移入有半透明阴影和播放图标,图片上移
定义一个背景为黑色的div遮罩层mask和图片大小圆角都相同,用绝对定位覆盖在图片之上, opacity: 0.5;透明度设置为0.5半透明效果,display:hidden将遮罩层隐藏
通过ref获取mask的dom节点,为外层div设置鼠标移入移出事件@mouseenter="maskShou" @mouseleave="maskHidden"操作ref.style.display控制遮罩层的显示和隐藏, transform: translateY(-10px);可以将盒子上移10px
3、视频组件
和歌单组件同理但是鼠标移入上移的效果变为放大
通过设置 transform: scale(1.2);设置缩放倍数
六、歌单详情页面
1、头部信息区
点击歌单组件通过路由传参把歌单id带入歌单详情页面,通过id调取接口获取详细信息
头部区域左右flex横向布局,右边四行flex纵向布局
歌单详细介绍使用Popover 气泡卡片组件,鼠标移入展示全部文字
2、tabs标签页
使用Tabs 标签页组件,label属性展示标签文字,name属性对应激活高亮样式,将label绑定响应式数据,可以动态展示歌曲数量和评论数量,name绑定响应式数据可以更改默认激活标签页
3、评论切换
评论基本样式为,也为左右 上下flex布局
关键在手写一个tabs切换最新和最热评论,获取评论的接口有sortType参数代表
: 排序方式, 1:按推荐排序, 2:按热度排序, 3:按时间排序
点击传入对应sortType参数即可获取对应排序评论数据。动态绑定,数据变了视图也变了,定义一个响应式数组tabs=["isActive tabs","tabs"],将最新最热的class动态绑定,选中的绑定tabs[0],未选中的绑定tabs[1],也可以实现高亮切换效果
4、歌曲列表playList组件
因为歌曲列表在很多页面都用得到,所以封装成一个组件playList,并且歌曲播放列表是全局页面都可以获取到的,离开歌曲列表页面也能播放歌单里所有歌曲,所以我们将播放列表存入vuex里的songs模块里
我们将播放列表的信息先存放在showData里,playList组件通过计算属性和mapGetters获取showData里的数据使用v-for进行页面展示,将每首歌曲名字、歌手、专辑、时长展示出来
每个songItem都设置鼠标移入移出事件实现高亮效果,并且操作图标盒子的ref实现图标控件的显示和隐藏:
双击播放功能:设计双击事件,双击将对应歌曲id发起获取播放url的请求,将获取到的url保存到vuex里songs模块的state的url,并且将state的isplay改为true表示正在播放歌曲
由于showData只是展示用的歌曲列表,我们还设计了一个播放歌曲列表,所以我们需要将展示列表赋值给播放列表,并且要传入双击歌曲的index知道播放的是列表里的第几首歌
为什么要设计两个歌曲列表:
如果只用一个数组保存歌曲列表会出现点击第一个歌单里的一首歌开始播放音乐,然后退出去点击另一个歌单不双击播放而是点击下面播放控件的下一首会变成第二个歌单里的歌曲,第一个歌单里的播放列表就被第二个歌单给覆盖了,这是不符合逻辑的。所以一个数组用来展示,一个数组用来保存播放队列,只要不双击播放,播放队列不会受到影响
七、播放控件
1、样式布局
还是横向纵向flex布局。根据播放时传入的index值可以知道正在播放的是播放列表里的第几首歌,将正在播放的歌曲信息单独保存在songs的state的playing里,播放控件从playing里获取歌曲的信息并渲染展示。
2、audio标签播放歌曲
audio的src属性绑定歌曲的url,我们将songs.state里的url属性用计算属性获取并动态绑定到src属性,再开启autoplay属性,当url变化时,src动态变化,触发自动播放,即实现播放功能。
3、暂停继续
点击蓝色播放按钮实现歌曲的暂停和继续,同时图标也要切换,我在songs.state中设计了isplay属性来维持播放和暂停的状态,两个图标切换通过v-if实现,歌曲暂停播放通过点击事件实现。
audio标签自带play()和pause()方法来播放和暂停通过获取audio的ref就可以操控该方法
4、上一首/下一首
我用index记录了当前播放歌曲在播放队列的位置,那么下一首歌曲就就让index+1,用新的index去播放列队playData里获取新的歌曲数据并放入正在播放对象playing,playing修改了相关视图也跟着变了。从playing里取出url修改state里的url,audio的src也改变了,切歌功能也就完成了。
当index记录到播放列队最后一首歌时再点击下一首时index要重新变为0,index为0是点击上一首,index也要变为playData.length-1
5、播放进度
歌曲详细信息传过来的时间是以秒为单位的,我们需要转换成00:00的形式
audio有个currentTime属性记录的是歌曲已经播放的时间,有个timeupdate事件会在音频播放进度发生改变时触发。所以播放歌曲时在timeupdate里可以一直获取currentTime。通过audio的ref获取currentTime,通过vuex的getters获取playing里的歌曲总时长,相除即可获得歌曲的播放进度
dt为歌曲总时长,durtime为以播放时长,percent为进度条百分比
八、歌曲mv
这个功能没什么特别的地方所以没过多花心思,只是做了最简单的页面。
路由传参进入mv页面获取路由参数里的歌曲名字,根据歌曲名字调接口获取mv的mvid,再根据mvid调取接口获取mv的url地址赋值给video的src属性。播放mv时把歌曲暂停。
九、搜索音乐
根据搜索的关键词调搜索接口获取数据放入showData里,也是使用playList展示歌曲列表和播放功能。
十、歌词滚动
1、布局
原理和阴影遮罩层一样,覆盖于el-head和el-main之上,点击播放控件的专辑图片可以让歌词界面展示出来,左上角下箭头图标收起歌词界面。界面分左右两部分,左边歌曲名字和专辑照片,右边滚动歌词
2、毛玻璃背景
将背景动态绑定设置为playling里的CDpic(专辑照片),通过filter: blur(220px);设置模糊效果,背景要被一个纯色背景容器包裹,不然会出现边缘模糊溢出和背后容器文字透出的问题
3、旋转CD
给图片容器加上animation: rotate 15s linear infinite;
在外部定义rotate动画,即可实现360度自动旋转,还有歌曲暂停旋转也暂停效果没做
4、滚动歌词
最麻烦的一个功能了,从下午一点写到凌晨一点
根据歌曲id请求获取歌词接口,拿到的歌词是这样的:
[ ]里代表歌词开始的时间,后面歌词内容,\n就要换行下一句,先根据\n将每一句转化为数组,
再根据 ] 将时间和歌词内容分隔,用对象保存obj.time为时间,obj.words为歌词,每句歌词一个对象,再push到一个数组里,并且保存到songs.state里
通过<ul><li> v-for将歌词全部展示出来,超出歌词展示盒子大小要overflow:hidden
要实现歌词随歌曲播放而滚动高亮本质上和进度条还是一样的道理,离不开audio的currentTime值和timeupdate事件,但是我把播放控件封装成了一个组件,而歌词界面在父组件里,就需要在子组件方法里操作父组件的dom节点删除和修改样式,并且点击子组件里的图片才展示父组件里的歌词界面,我们需要把父组件的展示歌词界面、获取歌词和歌词滚动方法都传给子组件
lrcdata为处理后的歌词对象数组,ctime为audio的currentTime,当ctime>lrcdata[i]而小于lrcdata[i+1]时,歌词高亮的位置就为i,将i传入父组件的歌词滚动方法
完整的歌词滚动方法,index为子组件传入的i的值歌词播放的位置,ul为展示歌词的ul标签的dom,lis为ul下所有li的dom数组,没一个li对应一句歌词。
对于index,要分情况讨论:
① 当index==0的时候表示歌曲刚开始播放,可能是刚播放第一首歌,也可能是上一首播完了,下一首了。我们要把所有的li都展示出来,并且把高亮效果都去除,相当于初始化
②当index!=0并且index<=5时,将index位置的歌词高亮,上一句歌词取消高亮
③当index>5时,我们就要开始将歌词从开头一句一句消失,只是视图消失,但是dom节点还在,所以要高亮的index还是没变,同时也要取消上一句歌词高亮。每唱完一行,下一行高亮,但同时顶部少一行,就会出现高亮的位置不变而是歌词在滚动,index>5这个条件取决的就是高亮效果在哪一行开始不变
总结:
只做了我觉得比较核心有趣的几个页面和功能,还有挺多东西可以完善的,等有时间可以慢慢把功能补齐。还可以做做喜欢、收藏歌曲和发表评论,也可以更加深入了解video标签的相关属性事件手写视频播放控制组件。进度条和歌词滚动还有鼠标拖拽进度条和歌词进度没有实现,歌词滚动还存在一点问题,如果是歌放到一半再打开歌词界面,会从歌词第一句快速滚动到目标位置,不会直接就是正在唱的那句。布局也没有考虑多端多种分辨率的适配,有些逻辑功能写的比较繁琐等等。
这篇关于vue3 web在线音乐项目——蔚蓝音乐 开发记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!