用VUEJS(2.x)做一個網(wǎng)易云音樂
前言:自己学习VUEJS也一段时间,但一直没有做出来一东西。我自己一直喜欢用网易云音乐app,于是乎就做了这个app。
技术栈
vue全家桶 (vue vue-router vuex)
axios
Muse-UI(一个基于Vue2.x的material design 风格UI框架)
功能与思路分析
我之前学习JS的时候对Html5 audio研究过,也写过一些例子,那时的功能并不是很全面。在写这个程序之前,我好好的查阅了当前的HTML5中的audio标签,发现园子上一位园友总结的很不错(这里)。于是就先把网易云音乐最基本的功能实现,歌单部分(这也是我喜欢网易云音乐的原因这一),然后实现音乐的上一曲、下一曲,播放、暂停。列表功能。
后台
后台采用.net做为后台提供系统请求所用的API( 项目结构 说项目的路由之前,先来看一张效果图 对于整个项目来说:视图区别在于顶部导航,下面的bar的是否出来取决于,当前系统列表中是否有歌曲,如果有就会出现。 router.js核心部分 vuex部分 这部分,主要是歌曲这一块,因为不同的页面有不同的使用到了歌曲信息,把把这部分数据放到vuex中做统一的数据处理! 最后上点项目截图 github项目地址:https://github.com/javaSwing/NeteaseCloudWebApp 目前只完成app歌单部分,也是最核心的部分。这个项目会一直更新!如果觉的不错就给个star吧vuejs部分
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── playBar.vue
│ └── ...
└── store
│ └── index.js # 整个项目的vuex部分
└── router
│ └── router.js # 整个项目的路由
└── utils # 一些工具类模块
│
└── views # 项目中的一些route-view
const router = new VueRouter({ mode: 'history', routes: [{ path: '/index', component: require('../views/index'), children: [
{ path: 'rage', component: require('../views/rage')
},
{ path: 'songList', component: require('../views/songList')
},
{ path: 'leaderBoard', component: require('../views/leaderBoard')
},
{ path: 'hotSinger', component: require('../views/hotSinger')
}
]
}, { name: 'playerDetail', path: '/playerDetail/:id', component: require('../views/playerDetail')
}, { path: '/playListDetail/:id', name: 'playListDetail', component: require('../views/playListDetail')
}, { path: '*', redirect: '/index/rage'
}], // 让每个页面都滚动到顶部,改变模式为mode: history
scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition
} else { return { x: 0, y: 0 }
}
}
})
sotre/index.jsconst store = new Vuex.Store({ state: { audio: { 'id': 0, 'name': '歌曲名称', 'singer': '演唱者', 'albumPic': '/static/player-bar.png', 'location': '', 'album': ''
}, lyric: '正在加载中。。', currentIndex: 0, // 当前播放的歌曲位置
playing: false, // 是否正在播放
loading: false, // 是否正在加载中
showDetail: false, songList: [], // 播放列表
currentTime: 0, tmpCurrentTime: 0, durationTime: 0, bufferedTime: 0, change: false // 判断是更改的时间还是播放的时间
}, getters: { audio: state => state.audio, playing: state => state.playing, loading: state => state.loading, showDetail: state => state.showDetail, durationTime: state => state.durationTime, currentIndex: state => state.currentIndex, bufferedTime: state => state.bufferedTime, tmpCurrentTime: state => state.tmpCurrentTime, songList: state => state.songList, change: state => state.change, currentTime: state => state.currentTime, prCurrentTime: state => { return state.currentTime / state.durationTime * 100
}, prBufferedTime: state => { return state.bufferedTime / state.durationTime * 100
}
}, mutations: {
play (state) {
state.playing = true
},
pause (state) {
state.playing = false
},
toggleDetail (state) {
state.showDetail = !state.showDetail
},
setAudio (state) {
state.audio = state.songList[state.currentIndex - 1]
},
setAudioIndex (state, index) {
state.audio = state.songList[index]
state.currentIndex = index + 1
},
removeAudio (state, index) {
state.songList.splice(index, 1)
state.audio = state.songList[index - 1]
state.currentIndex = state.currentIndex - 1
if (state.songList.length === 0) {
state.audio = { 'id': 0, 'name': '歌曲名称', 'singer': '演唱者', 'albumPic': '/static/player-bar.png', 'location': '', 'album': ''
}
state.playing = false
}
},
setChange (state, flag) {
state.change = flag
},
setLocation (state, location) {
state.audio.location = location
},
updateCurrentTime (state, time) {
state.currentTime = time
},
updateDurationTime (state, time) {
state.durationTime = time
},
updateBufferedTime (state, time) {
state.bufferedTime = time
},
changeTime (state, time) {
state.tmpCurrentTime = time
},
openLoading (state) {
state.loading = true
},
closeLoading (state) {
state.loading = false
},
resetAudio (state) {
state.currentTime = 0
},
playNext (state) { // 播放下一曲
state.currentIndex++ if (state.currentIndex > state.songList.length) {
state.currentIndex = 1
}
state.audio = state.songList[state.currentIndex - 1]
},
playPrev (state) { // 播放上一曲
state.currentIndex-- if (state.currentIndex < 1) {
state.currentIndex = state.songList.length
}
state.audio = state.songList[state.currentIndex - 1]
},
addToList (state, item) { var flag = false
state.songList.forEach(function (element, index) { // 检测歌曲重复
if (element.id === item.id) {
flag = true
state.currentIndex = index + 1
}
}) if (!flag) {
state.songList.push(item)
state.currentIndex = state.songList.length
}
},
setLrc (state, lrc) {
state.lyric = lrc
}
}, // 异步的数据操作
actions: {
getSong ({commit, state}, id) {
commit('openLoading')
Axios.get(api.getSong(id)).then(res => { // 统一数据模型,方便后台接口的改变
var url = res.data.data[0].url
commit('setAudio')
commit('setLocation', url)
})
},
getLrc ({commit, state}, id) {
commit('setLrc', '[txt](加载中。。。')
Axios.get(api.getLrc(id)).then(res => { // 1、先判断是否有歌词
if (res.data.nolyric) {
commit('setLrc', '[txt](⊙0⊙) 暂无歌词')
} else { console.log(res.data.lrc.lyric)
commit('setLrc', res.data.lrc.lyric)
}
})
}
}
})
作者:前端er
链接:https://www.jianshu.com/p/ee9d4dea5f79
共同學習,寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章