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

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

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

一、項目功能說明

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

二、最終效果

首頁:

排行榜:

歌單:

主播電臺:

歌手:

新碟上架:

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

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

四、項目技術(shù)棧

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

五、核心技術(shù)

  • 配置項目別名:@craco/craco

craco還可以進(jìn)行wepback 進(jìn)行自定義配置、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"
  },

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

重啟項目

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

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

  • 使用CSS Sprites 精靈圖

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

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

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

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

使用 styled-components 編寫css樣式,通過 import styled from 'styled-components'引入css 文件

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

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

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

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

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

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

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

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

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

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

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

  • 播放音樂板塊

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

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

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

//進(jìn)度改變觸發(fā)onchange時間,調(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),切換播歌類型:

// 獲取狀態(tài)中的播放類型
    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),來判斷當(dāng)前進(jìn)度條是否正在改變,以便于當(dāng)用戶正在播放音樂并滑動滾動條時,滾動條可以滑動

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

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

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

例如:

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

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

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

六、遇到的問題

背景圖片不能正常顯示:

源代碼:

 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});

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

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

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

七、github鏈接

react仿寫網(wǎng)易云音樂項目

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

相關(guān)文章

  • 代碼解析React中setState同步和異步問題

    代碼解析React中setState同步和異步問題

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

    ForwardRef?useImperativeHandle方法demo

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

    Ant Design組件庫的使用教程

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

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

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

    React父組件數(shù)據(jù)實時更新了,子組件沒有更新的問題

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

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

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

    React實現(xiàn)菜單欄滾動功能

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

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

    下面小編就為大家?guī)硪黄唵握務(wù)凴eact中的路由系統(tǒng)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • React中的函數(shù)式插槽詳解

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

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

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

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

最新評論

长治市| 竹北市| 余姚市| 车险| 永平县| 保山市| 镇赉县| 衡阳市| 东源县| 什邡市| 泾源县| 澄江县| 新丰县| 瑞安市| 科尔| 渭南市| 蛟河市| 吴忠市| 临沭县| 张家川| 洪湖市| 双江| 紫金县| 山西省| 和政县| 宣城市| 乐陵市| 理塘县| 教育| 无锡市| 宁津县| 安宁市| 保山市| 洛川县| 怀集县| 广州市| 且末县| 灌阳县| 邛崃市| 惠安县| 芷江|