由于本人比较喜欢听歌,所以这次跟着慕课网的实战课程做了这个项目。
视频地址:Vue 2.0 高级实战-开发移动端音乐 WebApp

概述

基于vue.js的音乐播放器,数据来源于QQ音乐。大部分接口都是JSONP,抓取较容易,其中有些接口限制了host,需要设置header,所以自己编写接口转发请求来绕过host的限制。具体代码参考build目录下dev-server.js 或者 prod.server.js。使用的技术栈:vue2.0+vuex+vue-router;另外使用了很多第三方插件。

启动

项目源码

1
2
npm i
npm start

效果预览

src目录

─src
│ App.vue
│ main.js // 打包入口
├─api // 数据抓取
├─base // 基础可复用组件
├─common // 共用字体,图片,js方法,样式等
├─components // 业务组件
├─router // 路由
└─store // 状态管理

数据处理

由于很多JSONP请求,这里使用了一个第三方插件jsonp,这个插件使用很简单,有兴趣的可以学习一下。使用时,将请求的参数拼接到url上,调用他的jsonp方法即可。我们对请求回来的数据做了Promise化,方便我们后面使用数据。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import originJSONP from 'jsonp'
export default function jsonp(url, data, option) {
let subUrl = param(data).length > 0 ? `?${param(data)}` : ''
url += subUrl
return new Promise((resolve, reject) => {
originJSONP(url, option, (err, data) => {
if(!err) {
resolve(data)
} else {
reject(err)
}
})
})
}
function param(data) {
let url = ''
for(let p in data) {
let value = data[p] === undefined ? '' : data[p]
url += `&${p}=${encodeURIComponent(value)}`
}
url = url.length > 0 ? url.substring(1) : ''
return url
}

播放器内核是这个项目的重点,vuex的设计非常重要,这里设计好了,后面的代码书写起来才更轻松。

1
2
3
4
5
6
7
8
9
10
11
12
singer: {}, // 当前歌手
playing: false, // 播放状态
fullScreen: false, // 播放器状态(全屏/迷你)
playlist: [], // 播放列表(不同的播放模式不一样)
sequenceList: [], // 播放列表(任何模式都一样)
mode: playMode.sequence, // 播放模式(循环播放,单曲循环,随机播放)
currentIndex: -1, // 当前歌曲在列表中的索引
disc: {}, // 当前歌单
topList: {}, // 当前排行榜
searchHistory: loadSearch(),// 搜索历史
playHistory: loadPlay(), // 播放历史
likeList: loadLike() // 收藏列表

细节

1.去除移动端点击事件300ms延迟,也是用的第三方插件,fastclick,文档在这里

1
fastclick.attach(document.body)

2.图片懒加载:项目中使用的是vue-lazyload,使用方法参考文档,代码如下:

1
2
3
4
5
Vue.use(VueLazyload, {
preLoad: 1.3,
loading: require('common/image/default.jpg'),
attempt: 1
})

然后在需要使用图片懒加载的地方使用v-lazy替代:src即可

3.项目中有很多业务逻辑多个组件是可以共用的,所以使用了mixins,具体可以参考官方文档

混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。以组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。

可以把它看做一个组件,它也是一个对象,可以把各个组件中的共用代码写在里面,然后在组件中引入即可。

4.项目中使用了很多audioAPI,比如 timeupdate,play,ended 等。这都大大方便了我们的开发,比如 timeupdate 可以然我们准确得到当前播放的时间,进度条的实现就依赖这个方法。另外还要注意的是这里没有使用 canplay 而是使用了 play。我们设置了一个标志位songReady,当它为true的时候才能切换歌曲,如果我们将它设为true的时间是canplay的话,快速切换歌曲后点击暂停的话vuex中的状态虽然已经改变,但歌曲并没有停止播放。所以这里使用了play,只有当歌曲确实播放了才会将songReady置为true,这样即使点击再快也不会出现问题。

5.项目作者为了更好的交互体验,很多地方用到了滚动,上拉加载更多等。这里面用到了作者自己写的一个第三方库,better-scroll,确实很好用。很多地方也用到了vue的 transition 动画,比如页面之间的切换,播放器的打开和缩放到迷你播放器,这个动画比较好玩,用到了 transition 组件的几个事件:enter,after-enter,leave,after-leave。具体实现参考官方文档

6.路由懒加载:直接上文档吧!简单粗暴

7……

最后

确实用了好多插件啊!stuck_out_tongue_winking_eye

在这个项目中学到了很多,再次感受到组件化,模块化开发的方便,也遇到了很多问题,最后都解决了。继续爬行吧!少年!smile