前言

前言

项目预览和源码

最近更新

更新功能

  • 登录功能:

    • 暂时只支持“163邮箱”或“手机号”登录
    • 每日推荐歌单(只有登录成功才能查看)
    • 个人主页 & 个人收藏歌单 & 评论歌曲 & 点赞歌曲评论 & 创建歌单
  • 本地存储歌曲列表:

    • 不管之后是否刷新浏览器,只要在歌曲列表中就会持久化存储
    • (刷新浏览器,歌曲列表依然存在)
  • 歌曲列表:

    • 对歌曲列表支持拖拽排序,并会对播放顺序进行改变
  • 搜索音乐框:

    • 优化在搜索歌曲时,支持键盘"↑"+"↓"来切换搜索歌曲内容
  • 头部进度条:

    • 在页面路由跳转&网络请求时"添加头部进度条"显示
  • 404页:

    • 添加404页,在路由没有匹配的页面时,会显示404页面

修改BUG&ToDoList

点击查看👉近期优化调整

点击查看👉TO-DO-LIST

界面功能展示(新开发)

歌曲搜索(↑↓选择)

支持对歌曲列表进行拖拽排序

登录演示

每日推荐

个人主页

音乐列表

1.页面布局搭建

  1. 页面布局搭建

  1. 点击按钮显示和隐藏(播放列表) 和 添加过渡效果

  1. 和歌词展示控件互斥.(歌词列表显示,关闭歌词展示)

  1. Conten内容搭建

  1. 实现点击一项,播放对应的音乐,并且背景高亮

    • 在点击当前项后,将id传递函数,根据id派发action,请求播放列表详情信息
    • 将播放音乐函数传递给子组件
    • 实现当音乐播放结束或手动点击上一首或后下一首:

      • 对应item背景高亮跟着切换 (根据保存在redux中的currentSongIndex)

  1. 实现点击删除按钮,阻止事件冒泡和清除点击播放歌曲
  2. 点击清除全部按钮,清除全部音乐,并播放下一首音乐

2.歌词高亮效果

歌词接口

3.歌词滚动效果

  • 根据当前播放歌词的 index,实现滚动效果
  • 获取DOM,计算scrollTop,实现滚动

音乐列表拖拽排序sortablejs

说明

  • <font color='red'>当需要对某些表格的行或者列进行拖拽排序时</font>

    • 并不局限表格
    • 只要是你想拖拽的某一行都可以

使用拖拽排序步骤

  1. 安装
npm install sortablejs --save
yarn add sortablejs
  1. 导入
import Sortable from 'sortablejs';
  1. 配置参数
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]);
  1. 完成效果

本地存储音乐列表

默认歌曲列表

在我们每次请求歌曲的时候,其实只需要知道歌曲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数组顺序进行请求了

以优化

  • 支持记忆歌曲列表

    • 刷新页面后,音乐播放列表可以记忆上次播放顺序
  • 记忆在关闭页面前播放的音乐

    • 刷新页面后,关闭页面前记忆当前播放的歌曲,再次打开时默认歌曲是关闭前播放的歌曲

感谢

  • 非常感谢王红元老师的React核心技术实战让我学习到很多 react 的知识。
  • 非常感谢后台提供者Binaryify,接口很稳定,文档很完善
03-05 22:30