天天看點

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

文章目錄

  • 一、項目功能說明
  • 二、最終效果
  • 三、檔案目錄結構說明
  • 四、項目技術棧
  • 五、核心技術
    • 1. 配置項目别名: @craco/craco
    • 2. 使用reset.css進行 css 重置
    • 3. 使用CSS Sprites 精靈圖
    • 4. 使用 memo 包裹函數式元件,減少渲染次數
    • 5. AppHeader以及AppFooter的布局實作:
    • 6. 推薦頁輪播圖采用 antd 的 Carousel走馬燈元件完成
    • 7. 自定義公共元件,實作元件的複用
    • 8. 對于圖檔及播放次數也做了格式化處理
    • 9. 播放音樂闆塊
    • 10. 歌詞的處理
  • 六、遇到的問題
  • 七、github連結

一、項目功能說明

  1. 暫停、播放歌曲
  2. 切換上一首、下一首歌曲
  3. 拖動進度條改變播放進度
  4. 随機播放、循環播放、單曲循環
  5. 實時展示歌詞
  6. 切換不同分類的歌單、歌手、電台
  7. 實作推薦、排行榜、歌單、主播電台、歌手、新碟上架闆塊的展示

二、最終效果

首頁:

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

排行榜:

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

歌單:

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

主播電台:

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

歌手:

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

新碟上架:

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

三、檔案目錄結構說明

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結
  • 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

實作

7. 自定義公共元件,實作元件的複用

以下内容都被抽取到

components目錄

中。

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結
react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結
react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

8. 對于圖檔及播放次數也做了格式化處理

圖檔的處理:在 utils 目錄的 format-utils 下編寫

getSizeImage

函數,根據輸入的參數來決定圖檔的大小

對數字的處理:在 utils 目錄的 format-utils 下編寫

getCount

函數,格式化歌曲播放數量,讓使用者可以更直覺的知道播放次數

react仿寫網易雲音樂項目一、項目功能說明二、最終效果三、檔案目錄結構說明四、項目技術棧五、核心技術六、遇到的問題七、github連結

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元件 自帶的onChange和onAfterChange的屬性可以得到進度條滑動的位置和滑動後結束的位置
  • 使用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. 背景圖檔不能正常顯示:

源代碼:

解決方法:為圖檔添加.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仿寫網易雲音樂項目