react實戰-線上音樂播放器

始悔不悟發表於2018-02-02

music-react

專案簡介

基於 react 搭建的線上音樂播放器

點選線上預覽

該專案由 Create React App 搭建.

Github 地址

  1. 工程構建:Create React App

  2. 專案搭建:

    1. views: views 目錄用於存放專案功能模組的頁面,需要根據路由配置情況以及頁面複雜程度大小分割子級目錄
    2. config: config 目錄存放一些配置目錄,比如 API 資訊以及 axios 攔截器設定
    3. router: 路由資訊資料夾
    4. layout: 頁面基本佈局
    5. store: store 目錄用於整合 views 中的 store
    6. components: components 目錄用於存放非業務元件,或者在多個業務間都需要用到的功能元件
    7. common: common 目錄用於存放一些公共 css 以及 js 工具方法
  3. 部分第三方庫:

    1. 基礎框架: react
    2. 前端路由: react-router[-dom] v4
    3. 資料管理: redux / react-redux / redux-thunk
    4. 路由同步 store:connected-react-router
    5. 網路請求: axios
    6. css 前處理器: stylus
    7. 字型圖示: icomoon
  4. 程式碼規範:

    1. eslint: airbnb (可參見根目錄下的.eslintrc 檔案)
    2. 縮排空行等設定可參見專案根目錄.editorconfig 檔案
    3. 使用 commitizen 規範 commit 提交
  5. API:

    1. AD`s API
    2. 部分 API 由我室友爬蟲完成畢業伺服器到期,首頁資料 mock
    3. 推薦NeteaseCloudMusicApi
  6. 非同步請求錯誤處理: 使用 axios 攔截器,配合connected-react-router進行相應處理

// 新增響應攔截器
axios.interceptors.response.use(
  response => response,
  error => {
    // 請求錯誤時做些事
    const { status } = error.response
    if (status === 400) {
      // 原諒我沒有modal元件
      console.log('抱歉,系統開小差了')
    }
    if (status === 403) {
      // 跳轉到403
      store.dispatch(push('/exception/403'))
    }
    if (status >= 404 && status < 422) {
      // 跳轉到404
      store.dispatch(push('/exception/404'))
    }
    if (status <= 504 && status >= 500) {
      console.log('伺服器內部錯誤')
    }
    return Promise.reject(error)
  }
)
複製程式碼
  1. 非同步請求 loading 處理

    原本是每次 dispatch 非同步請求 action 時,先 dispatch 一個請求開始的 action,根據這個 action 改變的資料去 showLoading,請求結束完 dispatch 一個請求結束的 action,根據資料 hideLoading,但是全是重複勞動,每一個請求都要做一次。

    有想過在 axios 攔截中進行 showLoading 以及 hideLoading,但存在明顯缺陷:粒度太大,不能定位到某一個具體元件。

    公司的專案使用的是 dva,其外掛 dva-loading 可以自動處理 loading 狀態,不用一遍遍地寫 showLoading 和 hideLoading,並且每一個 model 均有獨立的 loading,元件內部可以獲取到,目前還在思考不使用 dva 如何實現同樣效果。

  2. layout-主頁結構

    1. menu 選單導航
    2. header 頭部
    3. footer 底部
    4. main 內容區域

    頭部和底部固定,中間高度自適應的幾種實現方式

    1. header/footer 通過 fixed 定位,container 高度為 100vh,上下 padding 為 header 與 footer 的高度,main 高度為 100%
    header {
      height: 30px;
      position: fixed;
      top: 0;
      left: 0;
    }
    
    footer {
      height: 60px;
      position: fixed;
      bottom: 0;
      left: 0;
    }
    
    .container {
      height: 100vh;
      padding: 30px 0 60px 0;
    }
    
    .main {
      height: 100%;
    }
    複製程式碼
    1. header 以及 footer 使用 fixed 定位 main 使用 absolute 定位
    header {
      height: 30px;
      position: fixed;
      top: 0;
      left: 0;
    }
    
    footer {
      height: 60px;
      position: fixed;
      bottom: 0;
      left: 0;
    }
    
    .container {
      height: 100vh;
    }
    
    .main {
      position: absolute;
      top: 30px;
      bottom: 60px;
    }
    複製程式碼

    3.普通流式佈局,container 高度為 100vh,中間高度通過calc計算得到

    header {
      height: 30px;
    }
    footer {
      height: 60px;
    }
    
    .container {
      height: 100vh;
    }
    
    .main {
      height: calc(100vh - 30px - 60px);
    }
    複製程式碼

實現功能

  1. 歌手詳情
  2. 排行榜
  3. 收藏歌單
  4. 歌詞滾動
  5. 歌曲播放
  6. 切歌模式

TODO

  1. 封裝輪播圖元件react-tiny-swiepr
  2. 抽象 layout 元件
  3. 抽象 router 資訊
  4. 非同步請求全域性錯誤處理
  5. loading 控制
  6. 合理劃分 redux 結構
  7. 封裝 message 元件
  8. 效能優化
    • 路由按需載入
    • 動畫優化
    • 服務端渲染

本地執行

git clone https://github.com/worldzhao/music-react.git

cd music-react

npm install

npm start
複製程式碼

專案截圖

推薦歌單.png

歌單詳情.png

播放詳情.png

每學到一點新知識,新思想,我都會來改進這個專案,歡迎 fork 和 star,如果你正在學習 react,通過一個比較綜合的專案來實戰也還是非常不錯的。

Github 地址

我的部落格

相關文章