前言
前言
项目预览和源码
最近更新
更新功能
登录功能:
- 暂时只支持“163邮箱”或“手机号”登录
- 每日推荐歌单(只有登录成功才能查看)
- 个人主页 & 个人收藏歌单 & 评论歌曲 & 点赞歌曲评论 & 创建歌单
本地存储歌曲列表:
- 不管之后是否刷新浏览器,只要在歌曲列表中就会持久化存储
- (刷新浏览器,歌曲列表依然存在)
歌曲列表:
- 对歌曲列表支持拖拽排序,并会对播放顺序进行改变
搜索音乐框:
- 优化在搜索歌曲时,支持键盘"↑"+"↓"来切换搜索歌曲内容
头部进度条:
- 在页面路由跳转&网络请求时"添加头部进度条"显示
404页:
- 添加404页,在路由没有匹配的页面时,会显示404页面
修改BUG&ToDoList
点击查看👉近期优化调整
点击查看👉TO-DO-LIST
界面功能展示(新开发)
歌曲搜索(↑↓选择)
支持对歌曲列表进行拖拽排序
登录演示
每日推荐
个人主页
音乐列表
1.页面布局搭建
- 页面布局搭建
- 点击按钮显示和隐藏(播放列表) 和 添加过渡效果
- 和歌词展示控件互斥.(歌词列表显示,关闭歌词展示)
- Conten内容搭建
实现点击一项,播放对应的音乐,并且背景高亮
- 在点击当前项后,将
id
传递函数,根据id
派发action
,请求播放列表详情信息 - 将播放音乐函数传递给子组件
实现当音乐播放结束或手动点击上一首或后下一首:
- 对应
item
背景高亮跟着切换 (根据保存在redux
中的currentSongIndex
)
- 对应
- 在点击当前项后,将
- 实现点击删除按钮,阻止事件冒泡和清除点击播放歌曲
- 点击清除全部按钮,清除全部音乐,并播放下一首音乐
2.歌词高亮效果
歌词接口
请求接口:
对请求下来的歌词进行解析
- 在上一节咱们已经存放到
redux
当中,参考👉歌词格式化
- 在上一节咱们已经存放到
- 实现当前播放的歌词高亮显示,获取当前是否播放状态滚动歌词
3.歌词滚动效果
- 根据当前播放歌词的
index
,实现滚动效果 - 获取
DOM
,计算scrollTop
,实现滚动
音乐列表拖拽排序sortablejs
说明
<font color='red'>当需要对某些表格的行或者列进行拖拽排序时</font>
- 并不局限表格
- 只要是你想拖拽的某一行都可以
使用拖拽排序步骤
- 安装
npm install sortablejs --save
yarn add sortablejs
- 导入
import Sortable from 'sortablejs';
- 配置参数
import React, { useRef } from 'react';
// other hook
const playlistRef = useRef();// 用于获取DOM元素
useEffect(() => {
// 获取列表项父元素
const el = playlistRef.current.querySelector('.main-playlist');
new Sortable(el, {
sort: true,
animation: 200,
onEnd: function (evt) { // 拖拽结束发生该事件
let tempPlayList = playList
tempPlayList.splice(evt.newIndex, 0, playList.splice(evt.oldIndex, 1)[0]);
// 更改播放列表顺序
dispatch(changePlayListAction(tempPlayList))
},
});
}, [playList, dispatch]);
- 完成效果
本地存储音乐列表
默认歌曲列表
在我们每次请求歌曲的时候,其实只需要知道歌曲id
就可以了,这样我们只需要将在第一次初始化的的时候将歌曲id
进行存储在本地就可以了,不过需要对本地存储的歌曲id
进行去重就可以了(重复的歌曲id
不进行本地存储)
实现效果
歌曲顺序(异步问题)
思路
(1)解决方案:promise + setinterval(定时器)
(2)可能有同学会问,为什么使用定时器呢?(不一定使用要使用定时器+promise这种方案)
(3)这是因为在咱们发送ajax时,不能很好的进行控制,使用一个标识变量来进行控制ajax是否发送(默认为true)
(4)在每次开始定时器时,首先判断标识变量是否为true如果为true就发送ajax,
在本次请求ajax时设置标识变量为false(即在定时器中不会再发送网络请求),在本次ajax完成时(即异步操作成功时),改变标识变量为true
这样就能进行很好的控制,简单的总结一下:就是必须控制本次ajax发送请求成功时,才能进行下一次ajax
(核心在于使用标识变量,来控制ajax请求,且只有上次ajax请求成功,才能进行下一次ajax)
代码
export const getSongDetailArrayAction = (listId) => {
return (dispatch, getState) => {
// 1.获取歌曲列表
const playList = getState().getIn(['player', 'playList'])
let i = 0
let timer = null
let excuteRun = true // 控制ajax
timer = setInterval(() => {
let idx = listId[i]
new Promise((resolve, reject) => {
excuteRun &&
getSongDetail(idx).then((res) => {
excuteRun = false
// console.log(res.songs[0])
// (0)歌曲ID添加到本地存储
addPlaylistId(idx)
const song = res.songs && res.songs[0]
// console.log(song)
if (!song) return
// (1)添加到播放列表中
playList.push(song)
dispatch(changePlayListAction(playList))
// (2)更改当前播放的索引
const songIndex = playList.length - 1
dispatch(changeSongIndexAction(songIndex))
// (3)更改当前播放歌曲
dispatch(changeCurrentSongAction(song))
// (4)请求歌曲的歌词
dispatch(getLyricAction(idx))
// (5)更新歌曲数量
dispatch(changePlayListCount(playList.length))
resolve(i)
})
}).then((value) => {
excuteRun = true
})
i++
if (i >= listId.length) {
clearInterval(timer)
}
})
}
}
效果
- 这下不管刷新多少次,都会按照咱们的本地存储中歌曲列表
id
数组顺序进行请求了
以优化
支持记忆歌曲列表
- 刷新页面后,音乐播放列表可以记忆上次播放顺序
记忆在关闭页面前播放的音乐
- 刷新页面后,关闭页面前记忆当前播放的歌曲,再次打开时默认歌曲是关闭前播放的歌曲