大概步骤:
目标效果
七、点击歌曲li
- 要点:
- 与排行榜歌曲列表的歌曲li点击对比
- 是把获取到的所有歌曲列表设置为vuex中的播放列表
- 而搜索结果的歌曲li是把一首歌添加进播放列表,而且不是简单push,而是插入正在播放
- 因此要和排行榜歌曲li一样要操作的mutations是多个,利用到actions,来操作多个mutations
- 与排行榜歌曲列表的歌曲li点击对比
(一)、点击触发actions事件
↓searchSuggest.vue
import {mapActions} from 'vuex' //引入点击存入数据方法的vuex
/*****跳转路由,歌手详情页*********/
selectItem(item){
//判断是歌手,并把歌手数据提取出出来
if(item.type===TYPE_SINGER){
}else{
//点击是歌曲,修改歌曲列表数据
this.insertSong(item)
}
},
/*******选择歌曲插入歌曲列表数据*************/
...mapActions([
'insertSong',
])
},
(二)、把当前歌曲添加进播放相关vuex数据中
↓store- ->actions.js
- 把当前歌曲添加进播放列表playlist
- 把当前歌曲添加进歌曲列表sequenceList,添加进最后面
1)获取当前已有的播放列表、歌曲列表、当前歌曲序列(得当前歌曲)
/*******点击搜索结果li,添加歌曲数据******************/
export const insertSong = function ({commit,state},song){
//获取当前已有的歌曲列表
let playlist = state.playlist.slice()
let sequenceList = state.sequenceList
let currentIndex = state.currentIndex
let currentSong = playlist[currentIndex]
2)把点击歌曲添加进播放列表
- 当前播放列表已有这首歌
- 在正在播放的后面,则把这首歌变成立即播放,后面的删掉
- 在正在播放的前面(播放完了),则同样立即播放,前面的删掉
- 当前播放列表没有这首歌,立即播放即可
原方法arr.findIndex(回调函数),这里自定义了为findIndex(arr,判断标志的数组)
正在播放的歌曲序列+1,插入的歌曲为currentIndex
利用 arr.splice(序列,删除几个,插入内容) 方法,操作播放列表数据
判断已有情况下,删除前面还是删除后面的歌曲(要删除的歌曲index因为插入了歌曲而改变了)
/***插入播放列表******/
// 查找列表是否已有当前歌曲
let fpIndex = findIndex(playlist,song) //变量名find playlist index
currentIndex++ //插入歌曲索引+1
// 插入数组方法splice(序列,删除几个,插入内容)
playlist.splice(currentIndex,0,song)
// 插入完成后,已有歌曲要删除
if(fpIndex > -1){
if(currentIndex>fpIndex){
playlist.splice(fpIndex,1) //当重复项在插入前面
currentIndex-- //插入的位置要减一
}else{
playlist.splice(fpIndex+1,1) //当重复项在插入项后面
}
}
3)把点击歌曲添加进歌曲列表
- 当前歌曲列表已有这首歌
- 在正在播放的后面,把歌曲插到正在播放的后一首,后面的删掉
- 在正在播放的前面(播放完了),则同样插到正确位置,前面的删掉
- 当前播放列表没有这首歌,插入到正在播放的歌曲在歌曲列表的序列后
设置新变量为当前播放在歌曲列表的序列,插入到播放的序列后
因为插入的位置是播放的后一位,没有影响歌曲列表的前面序列,
因此与上一步不一样
/****插入歌曲列表******/
// 当前的currentIndex是播放列表的序列,因此歌曲列表的已有序列要自己找
let currentSIndex = findIndex(sequenceList,currentSong)+1 //加一是要插入的序列位置
// 查找列表中是否已有歌曲
let fsIndex = findIndex(sequenceList,song)
// 插入歌曲
sequenceList.splice(currentSIndex,0,song)
//插入后删除重复
if(fsIndex > -1){
if(currentSIndex > fsIndex){
sequenceList.splice(fsIndex,1)
}else{
sequenceList.splice(fsIndex+1,1)
}
}
4)把添加进来后的播放列表、歌曲列表、播放序列、打开播放器存进vuex,自动给播放器组件执行
/******修改了数据之后,存入vuex***********/
commit(types.SET_PLAYLIST,playlist) //存入当前播放列表
commit(types.SET_CURRENT_INDEX,currentIndex) //存入当前歌曲序列
commit(types.SET_SEQUENCE_LIST,sequenceList) //存入歌曲列表
commit(types.SET_FULL_SCREEN,true) //存入当前展开状态
commit(types.SET_PLAYING_STATE,true) //存入当前播放状态
}
5)报错,watcher not mutate vuex store state outside mutation
说我们在mutation外改变了state ,但是我们都是在actions中操作的,没有在外部使用过state啊
是在获取state数据后我们对他的播放列表等进行操作,所以这里把数据数组用slice()备份一下,就不是直接操作state了
let playlist = state.playlist.slice() //因为这样在splice直接操作了数据,不允许,设置副本
let sequenceList = state.sequenceList.slice()
let currentIndex = state.currentIndex //值类型,只是赋值,没有直接操作
播放器组件会自动与vuex中的数据关联,即可实现打开播放器,排行榜页面的歌曲列表也是操作actions即可打开播放了
- 调试在mutation出展开能看到pre next的数据变化,可以多点几首歌,并检查序列有没有按预期的插入和正确删除。
项目来源:慕课网
如有建议和疑问可联系
QQ:1017386624
邮箱:1017386624@qq.com