React仿写网易云音乐项目

2023-11-18

一、项目功能说明

  1. 暂停、播放歌曲
  2. 切换上一首、下一首歌曲
  3. 拖动进度条改变播放进度
  4. 随机播放、循环播放、单曲循环
  5. 实时展示歌词
  6. 切换不同分类的歌单、歌手、电台
  7. 实现推荐、排行榜、歌单、主播电台、歌手、新碟上架板块的展示

二、最终效果

首页:
在这里插入图片描述
排行榜:
在这里插入图片描述
歌单:
在这里插入图片描述
主播电台:
在这里插入图片描述
歌手:
在这里插入图片描述
新碟上架:
在这里插入图片描述

三、文件目录结构说明

请添加图片描述

  • assets:存放共用的css、font图标、image
  • common:存放共用的资源,如数据、常量
  • components:存放多个页面共享的组件
  • pages:划分各个页面
  • router:路由配置
  • services:网络请求
  • store:合并所有reducer
  • utils:一些js的工具

四、项目技术栈

  • React 作为前端框架
  • Ant Design 作为前端UI框架
  • Redux 进行状态管理
  • Axios 进行网络请求
  • 通过调用网易云的API来获取数据
  • 使用 react-router-dom 的 Route, Switch 管理路由
  • 使用普通css 及 styled-component 编写 CSS

五、核心技术

1. 配置项目别名: @craco/craco

craco还可以进行wepback 进行自定义配置、antd 组件按需加载、支持 less等操作。不选择 npm run eject 是因为eject是不可逆操作。

  • 安装:npm i @craco/craco
  • 在package.json中的配置:
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },
  • 根目录下创建 craco.config.js
  • 重启项目

2. 使用reset.css进行 css 重置

通过 import './assets/css/reset.css'引入。但 reset.css 存在一个很大的问题是它将所有的浏览器的默认样式清除,从而达到所有浏览器样式的统一的目的,但这么操作会导致浏览器原本的默认样式失去意义。比起 reset.css 我更倾向于使用 normalize.css 来统一样式, normalize.css 是在尽量保留浏览器的默认样式的基础上,不进行太多的重置,这样保留了有价值的默认值,它还可以模块化引入、修复了浏览器的一些 bug、没有复杂的继承链。

3. 使用CSS Sprites 精灵图

本次项目很多地方使用了CSS Sprites 精灵图技术,可以有效减少图片的请求次数,优化性能。

4. 使用 memo 包裹函数式组件,减少渲染次数

React.memo是一个高阶函数,与类组件里面的 PureComponent类似,它传递一个组件进去,返回一个可以记忆的组件,在 props 不变的情况下,这个被包裹的组件是不会重新渲染的,这样就减少了 render 的渲染次数,从而提高了性能。

export default memo(function App() {
  return (
    <div className="App">
    </div>
   )
 })

5. AppHeader以及AppFooter的布局实现:

  • 使用 styled-components 编写css样式,通过 import styled from 'styled-components'引入css 文件
  • 导航栏使用flex布局
  • 导航栏前三项采用 路由跳转、后三项是链接跳转
  • 搜索栏使用了 antd 的样式,通过 import { Input } from 'antd'引入
  • 搜索图标使用了antd 的图标库,通过import { SearchOutlined } from '@ant-design/icons'引入

6. 推荐页轮播图采用 antd 的 Carousel走马灯组件完成

背景的模糊效果使用高斯模糊,通过改变请求的url ?imageView&blur=40x20 实现,css可以用filter: blur(20px);实现

7. 自定义公共组件,实现组件的复用

以下内容都被抽取到 components目录中。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

8. 对于图片及播放次数也做了格式化处理

图片的处理:在 utils 目录的 format-utils 下编写 getSizeImage 函数,根据输入的参数来决定图片的大小
对数字的处理:在 utils 目录的 format-utils 下编写 getCount 函数,格式化歌曲播放数量,让用户可以更直观的知道播放次数
在这里插入图片描述

9. 播放音乐板块

  • 播放/暂停音乐:采用了 html5 的 audio 标签实现,通过点击播放/暂停按钮实现歌曲的播放或暂停,通过isPlaying来获取当前播放状态,从而实现状态切换。
  // 播放/暂停音乐
const playMusic = useCallback(() => {
    isPlaying ? audioRef.current.pause() : audioRef.current.play()
    setIsPlaying(!isPlaying)
  }, [isPlaying])
  • 通过 antd 的 Slider滑动条来改变播放进度:通过Slider自带 value={progress} 属性获取当前播放进度,从而设置audio的播放进度。
//进度改变触发onchange时间,调用该函数
  const sliderChange = useCallback((value) => {
    setIsChanging(true)
    const currentTime = value / 100 * duration / 1000
    setCurrentTime(currentTime * 1000)
    setProgress(value)
  }, [duration])
  • 获取当前状态,切换播歌类型
// 获取状态中的播放类型
    sequence: state.getIn(['player', 'sequence']),
// 点击切换播放类型
<button className="sprite_playbar btn loop" onClick={changeSequence}></button>
// 改变播放类型
  const changeSequence = () => {
    let currentSequence = sequence + 1
    if (currentSequence > 2) { currentSequence = 0 }
    dispatch(changeSequenceAction(currentSequence))
  }
  • 使用 isChanging, setIsChanging = useState(false),来判断当前进度条是否正在改变,以便于当用户正在播放音乐并滑动滚动条时,滚动条可以滑动
  • 利用 antd 的 Slider组件 自带的onChangeonAfterChange的属性可以得到进度条滑动的位置和滑动后结束的位置
  • 使用useCallback减少渲染次数
    原理:把函数以及依赖项作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,这个 memoizedCallback 只有在依赖项有变化的时候才会更新。
    例如:
// 播放歌曲进度条部分
// 滑动中的位置
  const sliderChange = useCallback((value) => {
    setIsChanging(true)
    // 滑动滚动条时,实时更新时间的改变
    const currentTime = value / 100 * duration / 1000
    setCurrentTime(currentTime * 1000)
    setProgress(value)
  }, [duration])
// 滑动后的位置
  const sliderAfterChange = useCallback((value) => {
	//滑动进度条后的进度条时间
    const currentTime = value / 100 * duration / 1000
    audioRef.current.currentTime = currentTime
     // 重新更新进度条时间
    setCurrentTime(currentTime * 1000)
    setIsChanging(false)
	//如果没有播放音乐,当滑动滚动条后开始播放音乐
    if (!isPlaying) {
      playMusic()
    }
  }, [duration, isPlaying, playMusic])

10. 歌词的处理

  • 实现:展示歌词部分使用的是 antd的 Message全局提示
  • 原理:先获取到这首歌的全部歌曲,在 utils/parse-lyric下格式化歌词,原理就是将字符串转为数组,数组的每一项为 一个对象 { time, content }包含了时间及该时间的歌词。

六、遇到的问题

  1. 背景图片不能正常显示:

源代码:

 background-image: url(${require("@/assets/img/recommend-top-bg.png")});

解决方法:为图片添加.default

 background-image: url(${require("@/assets/img/recommend-top-bg.png").default});
  1. 编写代码过程中无法将数据存储到redux的state中,但是看了react devtools 发现代码能够正常执行到action部分,在我编写了两遍 actionCreators.js 和 reducer.js 后发现是因为我没有在总的 store 中合并 reducer,留下悲伤的泪水。
  2. 滑动播放音乐的进度条时,进度条会短暂的回弹到滑动前位置。
    错误原因:在获取当前音乐播放时间时,利用setCurrentTime(e.target.currentTime * 1000),但是e.target.currentTime无法更加实时的获得当前滑动的数据,所以出现回弹。
    解决方法:在滑动结束后的回调函数冲重新更新进度条时间。
  const sliderAfterChange = useCallback((value) => {
  	// 获取滑动进度条后的进度条时间
    const currentTime = value / 100 * duration / 1000
    // 设置当前时间
    audioRef.current.currentTime = currentTime
    setCurrentTime(currentTime * 1000)
  }, [duration])

七、github链接

react仿写网易云音乐项目

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React仿写网易云音乐项目 的相关文章

  • React中的“计算属性”

    React中的 计算属性 相信许多学习过vue的小伙伴对计算属性都不陌生吧 计算属性能帮我们数据进行一些计算操作 计算属性是依赖于data里面的数据的 在vue中只要计算属性依赖的data值发生改变 则计算属性就会调用 那React中也有计
  • react项目按需加载报错 .libraryName is not a valid Plugin property

    babel presets react app plugins import libraryName antd style true 原配置如上会报错 libraryName is not a valid Plugin property g
  • Antd DatePicker 设置默认值报clone.weekday is not a function

    代码 dayjs版本1 11 7 页面 当点击页面日期框会报clone weekday is not a function 解决方法 在jsx文件中添加如下js import dayjs from dayjs import advanced
  • React Native 环境搭建, 新建项目, 运行和调试

    React Native 可以理解为一个基于 JavaScript 具备动态配置能力 面向前端开发者的移动端开发框架 目前为止虽然一直还没有V1 0 0版本 但是相信很多小伙伴都了解过或者已经入坑了 为什么RN那么有人气呢 我们可以先简单分
  • React仿写网易云音乐项目

    文章目录 一 项目功能说明 二 最终效果 三 文件目录结构说明 四 项目技术栈 五 核心技术 1 配置项目别名 craco craco 2 使用reset css进行 css 重置 3 使用CSS Sprites 精灵图 4 使用 memo
  • React 初识之Umi项目搭建实战

    一 创建项目 创建之前需要安装 Node js 和 npm yarn 这俩个环境 在WebStorm里面创建一个项目 输入命令 yarn create umi 弹出选项 这里我们选择第二项APP 选择是否使用typescript 这里选no
  • 对useReducer的理解

    useReducer是React提供的一个高级Hook 它不像useEffect useState useRef等必须hook一样 没有它我们也可以正常完成需求的开发 但useReducer可以使我们的代码具有更好的可读性 可维护性 可预测
  • ant design pro v5 配置拦截器,header

    ant design pro v5 配置拦截器 header 1 资料文档 https umijs org zh CN plugins plugin request requestinterceptors 2 编写app tsx 我这里是自
  • 如何在 Ubuntu 20.04 上使用 React 前端设置 Ruby on Rails v7 项目

    作者选择了电子前沿基金会接受捐赠作为为捐款而写程序 介绍 红宝石 on Rails是一个流行的服务器端 Web 应用程序框架 它为当今网络上存在的许多流行应用程序提供支持 例如GitHub Basecamp 声云 Airbnb and Tw
  • Ionic3开发教程 - 开发(2)

    Ionic3开发系列教程Ionic3开发教程 环境准备 1 Ionic3开发教程 开发 2 Ionic3开发教程 发布Android版本 3 Ionic3开发教程 发布IOS版本 4 Ionic3开发教程 更新 5 本文中介绍的Ionic3
  • 三、react中类组件和函数组件

    简介 本篇我们只要介绍react中类组件与函数组件两种组件的写法 两者的优缺点 同时对在我们的项目开发中该使用类组件还是函数组件进行思考分析 废话不多说进入正题 类组件 设计思路 类组件时面向对象编程的思想 在其中我们去设计类组件时使用st
  • 【react】新旧生命周期对比

    componentWillUpdate componentWillReceiveProps componentWillMount 上述这三个生命周期在V18以上的版本中 使用时要加上UNSELF name
  • react组件状态同步-状态提升

    假设定义组件TemperatureInputSon import React from react class TemperatureInputSon extends React Component constructor props su
  • React中使用if else 条件判断

    在react中用jsx渲染dom的时候经常会遇到if条件判断 然而在jsx中竟是不允许if条件判断的 以下有几种判断方式 可以根据自己的应用场景 挑选适合的 方案一 class HelloMessage extends React Comp
  • 前端学科面试题大全

    作用域和值类型引用类型的传递 变量作用域 作用域变量访问区域 变量值存在栈中 变量赋值相当于值赋值 值传递与引用传递有哪些区别 函数内部 变量会先声明 形式参数变量声明提升 整个函数体有var声明的变量 如果没有访问全局定义的num2 函数
  • react 上传文件(多选)功能入的坑

    1 这里报错是因为onChange的this指向不对 解决方法在constructor中写 this onChange this onChange bind this 或者在绑定事件的时候写 onChange this onChange b
  • 值得收藏的UmiJS 教程

    点击上方关注 前端技术江湖 一起学习 天天进步 前言 网上的umi教程是真的少 很多人都只写了一点点 很多水文 所以打算自己写一篇 自己搭建umi 并封装了一下常用的功能 并用到公司实际项目中 umi介绍 Umi 是什么 Umi 中文可发音
  • reactJS 干货(reactjs 史上最详细的解析干货)

    一 State和 Props state是状态机 应该包括 那些可能被组件的事件处理器改变并触发用户界面更新的数据 譬如需要对用户输入 服务器请求或者时间变化等作出响应 不应该包括 计算所得数据 React组件 在render 里使用pro
  • 自定义hooks

    自定义传参hooks 把大多数的通用代码 或者props 抽成一个hooks 用hooks实现上下文 就不用再一一传参了 实现原理 主要是通过createContext useContext 生产 消费者模式 用于大量props一层一层传参
  • 黑马React:基础拓展

    黑马React D10 基础拓展 Date December 18 2023 useReducer 基础使用 作用 让 React 管理多个 相对关联 的状态数据 补充 和useState的作用类似 用来管理相对复杂的状态数据 特点 use

随机推荐

  • DC-DC自举电容(BOOT)几个问题

    在BUCK电路中 经常会看到一个电容连接在芯片的SW和boot管脚之间 这个电容称之为自举电容 关于这个电容 有以下几个问题 自举电容有什么用 以MPS的buck芯片MP1484为例 规格书中芯片的BS管脚说明如下 在BS和SW之间接一个0
  • 51单片机C语言跑马灯,51单片机上实现控制跑马灯

    在MCS一51单片机的控制系统中 它的四个并行8位输入输出端口P0一P3是我们经常使用的 在并行端口的编程学习中 跑马灯 是单片机并行端口输出控制的典型实例 所谓跑马灯 是指将八个发光二极管分别连接到单片机的某一并行端口的八根线上 通过编程
  • wordpress 4.6 RCE漏洞利用(CVE-2016-10033)

    一 漏洞描述 当WordPress 使用 PHPMailer 组件向用户发送邮件 攻击者在找回密码时会使用PHPmailer发送重置密码的邮件 利用substr 字符串截取函数 run 系统调用函数 等构造payload 即可进行远程命令执
  • 区块链:Solidity值类型(布尔Boolens&整型Integer)

    Solidity Types 布尔 Booleans bool 可能的取值为常量值true和false 支持的运算符 逻辑非 逻辑与 逻辑或 等于 不等于 备注 运算符 和 是短路运算符 如f x g y 当f x 为真时 则不会继续执行g
  • HTTP请求返回状态码

    消息 代表请求已被接收 需要继续处理 临时响应 100 Continue 告知客户部分响应已被服务器接收 客户端应继续发送请求 成功 服务器已经接收理解并接受请求 200 OK 请求成功 返回想要的数据 正常状态 201 Created 已
  • 软件测试方法汇总

    软件测试方法种类繁多 记忆起来混乱 如果把软件测试方法进行分类 就会清晰很多 我参考一些书籍和网上的资料 把常用的软件测试方法列出来 让大家对软件测试行业有个总体的看法 从测试设计方法分类 测试名称 测试内容 Black box黑盒测试 把
  • 洛谷-【入门4】数组

    1 小鱼比可爱 题目描述 人比人 气死人 鱼比鱼 难死鱼 小鱼最近参加了一个 比可爱 比赛 比的是每只鱼的可爱程度 参赛的鱼被从左到右排成一排 头都朝向左边 然后每只鱼会得到一个整数数值 表示这只鱼的可爱程度 很显然整数越大 表示这只鱼越可
  • 实战wxPython:049 - 实现一个登录窗口

    在很多GUI程序中 常常在应用启动开始的时候 需要一个用户登录对话框 在那里用户必须输入用户名和密码 如果密码和用户名正确 那么程序就继续加载 显示程序的主界面 下面我们将实现一个登录窗口 它具有以下功能 输入用户名及密码 登录 如果用户名
  • spring boot 2.2.6.RELEASE集成 eureka启动报错

    1 报错信息 org springframework cloud client discovery health DiscoveryCompositeHealthIndicator DiscoveryCompositeHealthIndic
  • MongoDB创建与删除集合(collection)

    一 创建集合 MongoDB的集合相当于关系型数据库的表 不过在创建集合时 执行指定集合名称与选项即可 无需指定类似RDBMS的列名 创建集合的语法为 db createCollection name option 其中 name是集合的名
  • 前端面试题--计算机网络

    文章目录 1 七层网络协议体系结构的理解 2 五层协议中各自对应的网络协议 3 ARP 协议的工作原理 4 IP 地址分类的理解 5 TCP 的主要特点 exclamation exclamation Transmission Contro
  • 推荐几个容易中的计算机EI源刊(基本百发百中)

    转自小木虫 作者 pcmagic 收录 2012 05 27 发布 2012 05 20 根据多年的经验 以下计算机EI源刊可以说是百发百中 只要有工作量 并不需要什么创新性均可录用 Journal of Computers JCP ISS
  • SDUTOJ KMP简单应用 【KMP】

    KMP简单应用 Time Limit 1000MS Memory limit 65536K 题目描述 给定两个字符串string1和string2 判断string2是否为string1的子串 输入 输入包含多组数据 每组测试数据包含两行
  • 单片机外设基本概念_嵌入式单片机教学(一)

    01 引言 哈喽各位 好久不见 看到标题应该知道 小白 又要 给大家 开启一系列的新教程了 肯定有人说我跨度还蛮大的 从ROS到神经网络又到嵌入式教学 其实这些都是小白在本科期间学到的一些知识啦 这边分享给大家 让不知道怎么做项目的小小白能
  • Ubuntu16.04及ROS Kinetic环境下安装使用RealSense SR300

    Ubuntu16 04及ROS Kinetic环境下安装使用RealSense SR300 1 准备条件 需要安装Ubuntu16 04及ROS Kinetic 2 安装驱动 安装realsense的驱动流程可以根据Github上的官方推荐
  • C#获取本机主机名—三种方式

    前提条件 引用名称空间 using System Net 建议 使用方式3 本人使用前2种方式都存在字符串自动截取的情况 方式1 Environment 获取本地计算机名 string machineName System Environm
  • 前端基础--主流浏览器及其内核

    IE trident Chrome webkit blink firefox Gecko Opera presto Safari webkit 内核主要分成两部分 渲染引擎 layout engineer或 Rendering Engine
  • Wrapper中的QueryWrapper常用ge,gt,lt,le具体含义

    英文缩写 英文全拼 含义 EQ equal 等于 NE not equal 不等于 GT greater than 大于 LT less than 小于 GE greater than or equal 大于等于 LE less than
  • centos7.3安装mysql5.7 && 解决 Access denied for user 'root'@'localhost' (using password: NO)

    开始查找自带的mariadb rpm qa grep mariadb 找到安装包并卸载 rpm e mariadb安装包 卸载完之后 我们就可以开始安装mysql5 7了 在这里可以找到我们需要的点击这里 鼠标放在最下面那个No thank
  • React仿写网易云音乐项目

    文章目录 一 项目功能说明 二 最终效果 三 文件目录结构说明 四 项目技术栈 五 核心技术 1 配置项目别名 craco craco 2 使用reset css进行 css 重置 3 使用CSS Sprites 精灵图 4 使用 memo