最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React模仿網(wǎng)易云音樂(lè)實(shí)現(xiàn)一個(gè)音樂(lè)項(xiàng)目詳解流程

 更新時(shí)間:2022年08月16日 14:06:10   作者:litchi dream  
這篇文章主要介紹了React模仿網(wǎng)易云音樂(lè)實(shí)現(xiàn)一個(gè)音樂(lè)項(xiàng)目的詳細(xì)流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、項(xiàng)目功能說(shuō)明

  1. 暫停、播放歌曲
  2. 切換上一首、下一首歌曲
  3. 拖動(dòng)進(jìn)度條改變播放進(jìn)度
  4. 隨機(jī)播放、循環(huán)播放、單曲循環(huán)
  5. 實(shí)時(shí)展示歌詞
  6. 切換不同分類(lèi)的歌單、歌手、電臺(tái)
  7. 實(shí)現(xiàn)推薦、排行榜、歌單、主播電臺(tái)、歌手、新碟上架板塊的展示

二、最終效果

首頁(yè):

排行榜:

歌單:

主播電臺(tái):

歌手:

新碟上架:

三、文件目錄結(jié)構(gòu)說(shuō)明

  • assets:存放共用的css、font圖標(biāo)、image
  • common:存放共用的資源,如數(shù)據(jù)、常量
  • components:存放多個(gè)頁(yè)面共享的組件
  • pages:劃分各個(gè)頁(yè)面
  • router:路由配置
  • services:網(wǎng)絡(luò)請(qǐng)求
  • store:合并所有reducer
  • utils:一些js的工具

四、項(xiàng)目技術(shù)棧

  • React 作為前端框架
  • Ant Design 作為前端UI框架
  • Redux 進(jìn)行狀態(tài)管理
  • Axios 進(jìn)行網(wǎng)絡(luò)請(qǐng)求
  • 通過(guò)調(diào)用網(wǎng)易云的API來(lái)獲取數(shù)據(jù)
  • 使用 react-router-dom 的 Route, Switch 管理路由
  • 使用普通css 及 styled-component 編寫(xiě) CSS

五、核心技術(shù)

  • 配置項(xiàng)目別名:@craco/craco

craco還可以進(jìn)行wepback 進(jìn)行自定義配置、antd 組件按需加載、支持 less等操作。不選擇 npm run eject 是因?yàn)閑ject是不可逆操作。

安裝:npm i @craco/craco

在package.json中的配置:

  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

根目錄下創(chuàng)建 craco.config.js

重啟項(xiàng)目

  • 使用reset.css進(jìn)行 css 重置

通過(guò) import './assets/css/reset.css'引入。但 reset.css 存在一個(gè)很大的問(wèn)題是它將所有的瀏覽器的默認(rèn)樣式清除,從而達(dá)到所有瀏覽器樣式的統(tǒng)一的目的,但這么操作會(huì)導(dǎo)致瀏覽器原本的默認(rèn)樣式失去意義。比起 reset.css 我更傾向于使用 normalize.css 來(lái)統(tǒng)一樣式, normalize.css 是在盡量保留瀏覽器的默認(rèn)樣式的基礎(chǔ)上,不進(jìn)行太多的重置,這樣保留了有價(jià)值的默認(rèn)值,它還可以模塊化引入、修復(fù)了瀏覽器的一些 bug、沒(méi)有復(fù)雜的繼承鏈。

  • 使用CSS Sprites 精靈圖

本次項(xiàng)目很多地方使用了CSS Sprites 精靈圖技術(shù),可以有效減少圖片的請(qǐng)求次數(shù),優(yōu)化性能。

  • 使用 memo 包裹函數(shù)式組件,減少渲染次數(shù)

React.memo是一個(gè)高階函數(shù),與類(lèi)組件里面的 PureComponent類(lèi)似,它傳遞一個(gè)組件進(jìn)去,返回一個(gè)可以記憶的組件,在 props 不變的情況下,這個(gè)被包裹的組件是不會(huì)重新渲染的,這樣就減少了 render 的渲染次數(shù),從而提高了性能。

export default memo(function App() {
  return (
    <div className="App">
    </div>
   )
 })
  •  AppHeader以及AppFooter的布局實(shí)現(xiàn)

使用 styled-components 編寫(xiě)css樣式,通過(guò) import styled from 'styled-components'引入css 文件

導(dǎo)航欄使用flex布局

導(dǎo)航欄前三項(xiàng)采用 路由跳轉(zhuǎn)、后三項(xiàng)是鏈接跳轉(zhuǎn)

搜索欄使用了 antd 的樣式,通過(guò) import { Input } from 'antd'引入

搜索圖標(biāo)使用了antd 的圖標(biāo)庫(kù),通過(guò)import { SearchOutlined } from '@ant-design/icons'引入

  • 推薦頁(yè)輪播圖采用 antd 的 Carousel走馬燈組件完成

背景的模糊效果使用高斯模糊,通過(guò)改變請(qǐng)求的url ?imageView&blur=40x20 實(shí)現(xiàn),css可以用filter: blur(20px);實(shí)現(xiàn)

  • 自定義公共組件,實(shí)現(xiàn)組件的復(fù)用

以下內(nèi)容都被抽取到 components目錄中。

  • 對(duì)于圖片及播放次數(shù)也做了格式化處理

圖片的處理:在 utils 目錄的 format-utils 下編寫(xiě) getSizeImage 函數(shù),根據(jù)輸入的參數(shù)來(lái)決定圖片的大小

對(duì)數(shù)字的處理:在 utils 目錄的 format-utils 下編寫(xiě) getCount 函數(shù),格式化歌曲播放數(shù)量,讓用戶可以更直觀的知道播放次數(shù)

  • 播放音樂(lè)板塊

播放/暫停音樂(lè):采用了 html5 的 audio 標(biāo)簽實(shí)現(xiàn),通過(guò)點(diǎn)擊播放/暫停按鈕實(shí)現(xiàn)歌曲的播放或暫停,通過(guò)isPlaying來(lái)獲取當(dāng)前播放狀態(tài),從而實(shí)現(xiàn)狀態(tài)切換。

  // 播放/暫停音樂(lè)
const playMusic = useCallback(() => {
    isPlaying ? audioRef.current.pause() : audioRef.current.play()
    setIsPlaying(!isPlaying)
  }, [isPlaying])

通過(guò) antd 的 Slider滑動(dòng)條來(lái)改變播放進(jìn)度:通過(guò)Slider自帶 value={progress} 屬性獲取當(dāng)前播放進(jìn)度,從而設(shè)置audio的播放進(jìn)度。

//進(jìn)度改變觸發(fā)onchange時(shí)間,調(diào)用該函數(shù)
  const sliderChange = useCallback((value) => {
    setIsChanging(true)
    const currentTime = value / 100 * duration / 1000
    setCurrentTime(currentTime * 1000)
    setProgress(value)
  }, [duration])

獲取當(dāng)前狀態(tài),切換播歌類(lèi)型:

// 獲取狀態(tài)中的播放類(lèi)型
    sequence: state.getIn(['player', 'sequence']),
// 點(diǎn)擊切換播放類(lèi)型
<button className="sprite_playbar btn loop" onClick={changeSequence}></button>
// 改變播放類(lèi)型
  const changeSequence = () => {
    let currentSequence = sequence + 1
    if (currentSequence > 2) { currentSequence = 0 }
    dispatch(changeSequenceAction(currentSequence))
  }

使用 isChanging, setIsChanging = useState(false),來(lái)判斷當(dāng)前進(jìn)度條是否正在改變,以便于當(dāng)用戶正在播放音樂(lè)并滑動(dòng)滾動(dòng)條時(shí),滾動(dòng)條可以滑動(dòng)

利用 antd 的 Slider組件 自帶的onChange和onAfterChange的屬性可以得到進(jìn)度條滑動(dòng)的位置和滑動(dòng)后結(jié)束的位置

使用useCallback減少渲染次數(shù):

原理:把函數(shù)以及依賴項(xiàng)作為參數(shù)傳入 useCallback,它將返回該回調(diào)函數(shù)的 memoized 版本,這個(gè) memoizedCallback 只有在依賴項(xiàng)有變化的時(shí)候才會(huì)更新。

例如:

// 播放歌曲進(jìn)度條部分
// 滑動(dòng)中的位置
  const sliderChange = useCallback((value) => {
    setIsChanging(true)
    // 滑動(dòng)滾動(dòng)條時(shí),實(shí)時(shí)更新時(shí)間的改變
    const currentTime = value / 100 * duration / 1000
    setCurrentTime(currentTime * 1000)
    setProgress(value)
  }, [duration])
// 滑動(dòng)后的位置
  const sliderAfterChange = useCallback((value) => {
	//滑動(dòng)進(jìn)度條后的進(jìn)度條時(shí)間
    const currentTime = value / 100 * duration / 1000
    audioRef.current.currentTime = currentTime
     // 重新更新進(jìn)度條時(shí)間
    setCurrentTime(currentTime * 1000)
    setIsChanging(false)
	//如果沒(méi)有播放音樂(lè),當(dāng)滑動(dòng)滾動(dòng)條后開(kāi)始播放音樂(lè)
    if (!isPlaying) {
      playMusic()
    }
  }, [duration, isPlaying, playMusic])
  • 歌詞的處理

實(shí)現(xiàn):展示歌詞部分使用的是 antd的 Message全局提示

原理:先獲取到這首歌的全部歌曲,在 utils/parse-lyric下格式化歌詞,原理就是將字符串轉(zhuǎn)為數(shù)組,數(shù)組的每一項(xiàng)為 一個(gè)對(duì)象 { time, content }包含了時(shí)間及該時(shí)間的歌詞。

六、遇到的問(wèn)題

背景圖片不能正常顯示:

源代碼:

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

解決方法:為圖片添加.default

background-image: url(${<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E-->require("@/assets/img/recommend-top-bg.png").default});

編寫(xiě)代碼過(guò)程中無(wú)法將數(shù)據(jù)存儲(chǔ)到redux的state中,但是看了react devtools 發(fā)現(xiàn)代碼能夠正常執(zhí)行到action部分,在我編寫(xiě)了兩遍 actionCreators.js 和 reducer.js 后發(fā)現(xiàn)是因?yàn)槲覜](méi)有在總的 store 中合并 reducer,留下悲傷的淚水。

滑動(dòng)播放音樂(lè)的進(jìn)度條時(shí),進(jìn)度條會(huì)短暫的回彈到滑動(dòng)前位置。錯(cuò)誤原因:在獲取當(dāng)前音樂(lè)播放時(shí)間時(shí),利用setCurrentTime(e.target.currentTime * 1000),但是e.target.currentTime無(wú)法更加實(shí)時(shí)的獲得當(dāng)前滑動(dòng)的數(shù)據(jù),所以出現(xiàn)回彈。 解決方法:在滑動(dòng)結(jié)束后的回調(diào)函數(shù)沖重新更新進(jìn)度條時(shí)間。

  const sliderAfterChange = useCallback((value) => {
  	// 獲取滑動(dòng)進(jìn)度條后的進(jìn)度條時(shí)間
    const currentTime = value / 100 * duration / 1000
    // 設(shè)置當(dāng)前時(shí)間
    audioRef.current.currentTime = currentTime
    setCurrentTime(currentTime * 1000)
  }, [duration])

七、github鏈接

react仿寫(xiě)網(wǎng)易云音樂(lè)項(xiàng)目

到此這篇關(guān)于React模仿網(wǎng)易云實(shí)現(xiàn)一個(gè)音樂(lè)項(xiàng)目詳解流程的文章就介紹到這了,更多相關(guān)React網(wǎng)易云音樂(lè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 代碼解析React中setState同步和異步問(wèn)題

    代碼解析React中setState同步和異步問(wèn)題

    前端框架從MVC過(guò)渡到MVVM。從DOM操作到數(shù)據(jù)驅(qū)動(dòng),一直在不斷的進(jìn)步著,本文給大家介紹React中setState同步和異步問(wèn)題,感興趣的朋友一起看看吧
    2021-06-06
  • ForwardRef?useImperativeHandle方法demo

    ForwardRef?useImperativeHandle方法demo

    這篇文章主要為大家介紹了ForwardRef?useImperativeHandle方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Ant Design組件庫(kù)的使用教程

    Ant Design組件庫(kù)的使用教程

    AntDesign ,簡(jiǎn)稱antd是基于 Ant Design 設(shè)計(jì)體系的 React UI 組件庫(kù),主要用于研發(fā)企業(yè)級(jí)中后臺(tái)產(chǎn)品,這篇文章主要介紹了Ant Design組件庫(kù)的使用教程,需要的朋友可以參考下
    2023-12-12
  • Electron+React應(yīng)用打包全流程

    Electron+React應(yīng)用打包全流程

    本文主要介紹了Electron+React應(yīng)用打包全流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • React父組件數(shù)據(jù)實(shí)時(shí)更新了,子組件沒(méi)有更新的問(wèn)題

    React父組件數(shù)據(jù)實(shí)時(shí)更新了,子組件沒(méi)有更新的問(wèn)題

    這篇文章主要介紹了React父組件數(shù)據(jù)實(shí)時(shí)更新了,子組件沒(méi)有更新的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • react antd表格中渲染一張或多張圖片的實(shí)例

    react antd表格中渲染一張或多張圖片的實(shí)例

    這篇文章主要介紹了react antd表格中渲染一張或多張圖片的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • React實(shí)現(xiàn)菜單欄滾動(dòng)功能

    React實(shí)現(xiàn)菜單欄滾動(dòng)功能

    本文將會(huì)基于react實(shí)現(xiàn)滾動(dòng)菜單欄功能,點(diǎn)擊菜單,內(nèi)容區(qū)域會(huì)自動(dòng)滾動(dòng)到對(duì)應(yīng)卡片,內(nèi)容區(qū)域滑動(dòng),指定菜單欄會(huì)被選中,代碼簡(jiǎn)單易懂,感興趣的朋友一起看看吧
    2024-03-03
  • 簡(jiǎn)單談?wù)凴eact中的路由系統(tǒng)

    簡(jiǎn)單談?wù)凴eact中的路由系統(tǒng)

    下面小編就為大家?guī)?lái)一篇簡(jiǎn)單談?wù)凴eact中的路由系統(tǒng)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • React中的函數(shù)式插槽詳解

    React中的函數(shù)式插槽詳解

    這篇文章主要為大家詳細(xì)介紹了React?開(kāi)發(fā)中遇到的具名插槽的函數(shù)用法,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,有興趣的小伙伴可以了解一下
    2023-11-11
  • 從零開(kāi)始搭建webpack+react開(kāi)發(fā)環(huán)境的詳細(xì)步驟

    從零開(kāi)始搭建webpack+react開(kāi)發(fā)環(huán)境的詳細(xì)步驟

    這篇文章主要介紹了從零開(kāi)始搭建webpack+react開(kāi)發(fā)環(huán)境的詳細(xì)步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05

最新評(píng)論

丹凤县| 中山市| 吕梁市| 贺兰县| 华阴市| 襄垣县| 同江市| 闵行区| 萨嘎县| 龙井市| 平湖市| 株洲县| 漯河市| 成武县| 房山区| 读书| 马公市| 兴海县| 石阡县| 宣威市| 汶川县| 大新县| 永仁县| 宜州市| 桓台县| 乌拉特后旗| 金山区| 盐山县| 华宁县| 克东县| 互助| 永丰县| 民丰县| 夏津县| 隆德县| 安庆市| 墨竹工卡县| 合水县| 涟水县| 神农架林区| 报价|