點擊進入GitHub倉庫 (歡迎來star、提pr哦!)css
點擊進入項目上線地址 項目支持PWA,點擊chrome或者safari瀏覽器的添加至主屏幕,便可在桌面跟App同樣以圖標形式訪問,體驗如絲滑般流暢:)html
首先說一說爲何要作這樣一個React開源項目:前端
一、後端接口和文檔完整,你們都知道開發一個產品毫不僅僅是前端一我的的活,須要花大量的時間和後端溝通,商討數據接口的形式,最終作成文檔並以此爲依據開發。而如今github已經有很是成熟的抓取網易雲音樂服務端的接口,不只在與時俱進地不斷更新接口,並且文檔寫的也很是完善,用這樣的真實數據接口能夠大大方便咱們進行前端的開發,大大下降了咱們開發前端的成本。vue
二、React Hooks現在可謂前端界"當紅小生", 因其API簡潔性、邏輯複用性等特性逐漸被開發者所應用,將來的vue3.0也是採用相似的Function Based的模式,所以學習React Hooks也是將來的大趨勢,經過一個具體的項目來實踐、應用hooks特性,我以爲比干啃文檔要強太多,而且在實踐的過程當中會遇到一些坑,經過坑驅動來學習,能夠加深咱們對於hooks原理的理解。react
三、把Redux和不可變數據結合也是react性能優化的一個重要的手段,我很早就想用Redux結合Facebook開源的一款不可變數據結構庫immutable.js來開發,因此經過這個項目來具體地實踐一把。ios
一、 首先在這個項目發出時,我就已經作了一個Promise, 拆解文章必定會出來,這是直接緣由。git
二、 我相信這個系列出來可以幫助很多的前端開發者,可以經過本身的才華和努力影響一批人,我以爲這原本就是一件很是有成就感的事情。es6
三、 輸出倒逼輸入。這個項目不是我一切準備就緒纔開始開發的,而是一步步嘗試、不斷學新的東西,才得以呈現如今的效果。我想寫拆解文章覆盤,也是這樣一個過程,讓本身可以不斷產生新的想法,而後去嘗試,對本身自己也是一種成長。github
這是咱們即將開發的版本,你們能夠看到,這個項目仍是稍微有一些複雜的,相信你們跟着作完會有很是大的收穫。web
react v16.8
: 用於構建用戶界面的 MVVM 框架redux
: 著名JavaScript狀態管理容器redux-thunk
: 處理異步邏輯的redux中間件immutable
: Facebook歷時三年開發出的進行持久性數據結構處理的庫 (它和memo、Redux搭配就是神器,memo包裹函數組件跟PureComponent是同樣的效果,在組件更新前進行數據的淺層比較,具體請參考這篇文章當 PureComponent 趕上 ImmutableJS)react-lazyload
: react懶加載庫better-scroll
: 提高移動端滑動體驗的知名庫styled-components
: 處理樣式,體現css in js的前端工程化神器(詳情請移步我以前的文章styled-components:前端組件拆分新思路)axios
: 用來請求後端api的數據在開始這個項目以前,我有必要強調一個這個項目工程的開發規範和我我的的編碼風格,提早告知一下,我這麼作也是有本身充分的理由的,讓項目可讀性和可維護性儘量高,但願後面看到一些奇葩的操做不要感到奇怪。
一、class組件再也不用,全面擁抱hooks,統一用函數組件。
二、組件內部狀態用hooks處理,凡是業務數據所有放在redux中管理。
三、ajax請求以及後續數據處理的具體代碼所有放在actionCreator中,由redux-thunk進行處理,儘量精簡組件代碼。
四、每個容器組件都有本身獨立的reducer,而後再全局的store下經過redux的combineReducer方法合併。
五、JS變量名(包括函數名)採用小駝峯的方式,組件名或者styled-components導出的樣式容器名都採用大駝峯,常量名全部字母大寫。
六、普通CSS類名所有用英語小寫,單詞間用下劃線鏈接,CSS動畫鉤子類名中單詞用-鏈接。
七、凡是props中有數據的,所有在組件最前面提早解構賦值,而且,得到的屬性名和方法名要分開聲明,從父組件得到的props和經過react-redux中映射得到的props也要分開聲明。
八、useEffect統一寫在最前面,而且緊跟着props解構賦值代碼後面。
九、凡是負責返回JSX的函數,統一彙集在函數最後面,中間不要穿插事件處理函數和其餘邏輯。
十、mapDispatchToProps返回的函數中,函數名格式爲xxxDispatch,以避免和現有action名衝突。
看到這裏你是否是有一點心動?哈哈,別高興的太早。其實要掌握這些內容着實不容易,要經歷的還有不少不少,我我的能力也有限,沒法保證你100%可以消化掉這些東西,但我惟一能夠保證的是:
這個系列拆解文章我會百分之百地投入,將我在開發中所經歷的坑和解決問題的過程毫無保留地分享給各位,對於一些你們可能會感到陌生的概念和語法都會一五一十地攤開來講,作到真正的"手摸手"。對於裏面涉及的代碼,我首先會再markdown中本身寫一遍,而後把本身看成小白,對照vuepress博客的開發界面再本身從頭至尾實現一遍,給你們足夠的技術安全感。
可是本系列拆解文章也不是針對前端純小白的,因爲基礎部分過於科普太多基礎內容不少小夥伴會厭倦,因此須要你有必定的前端知識的儲備,具體來講是指CSS經常使用的佈局方式和屬性,原生JavaScript的基礎,ES6的經常使用語法,React和Redux的基本使用。
若是有些你還不會,我推薦你先去學習一下這些資料:
本小節代碼你們能夠去參考GitHub倉庫chapter1分支。傳送門
首先經過create-react-app這個腳手架工具生成項目的初始化化結構,在命令行中輸入如下命令:
create-react-app cloud-music
複製代碼
完成後,根據提示:
cd cloud-music
複製代碼
啓動項目:
npm start
複製代碼
開始這個項目以前,咱們須要對目錄進行一下改造。以下(主要針對src目錄):
├─api // 網路請求代碼、工具類函數和相關配置
├─application // 項目核心功能
├─assets // 字體配置及全局樣式
├─baseUI // 基礎UI輪子
├─components // 可複用的UI組件
├─routes // 路由配置文件
└─store // redux相關文件
App.js // 根組件
index.js // 入口文件
serviceWorker.js // PWA離線應用配置
style.js // 默認樣式
複製代碼
腳手架生成的無用文件已經刪除,你們注意也把相關的引入語句也刪除。目前應該是整個應用的最終工程目錄,之後的開發都會基於這個目錄結構進行。
本項目的樣式採用styled-components來進行開發,也就是利用css in js的方式,我爲何要這麼作,有興趣的同窗能夠閱讀一下我以前在掘金寫的文章styled-components:前端組件拆分新思路。固然後面有人看了個人項目後給我提了這個庫的一些缺點,但我依然堅持用它進行開發,由於它在工程化方面的優點依然很是明顯,並且大部分缺點咱們也能夠有意識的去避開,這個具體在後面的章節裏面再說吧。
其實styled-components的使用是至關簡單的,不須要額外專門的學習,因此你們跟着我寫一遍,熟悉一下就好了。
不知道你有沒有發現一個問題,上面目錄中默認樣式文件是style.js,而不是.css,沒錯,這就是使用了styled-components後的結果。
咱們先安裝這個庫:
npm install styled-components --save
複製代碼
在剛剛的style.js中,
import { createGlobalStyle } from 'styled-components';
export const GlobalStyle = createGlobalStyle` html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } html, body{ background: #f2f3f4;; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; } a{ text-decoration: none; color: #fff; } `
複製代碼
這就是styled-components建立全局樣式並導出的代碼。
這段代碼導出到哪裏去呢?導入到App.js中。
//App.js中添加這一句
import { GlobalStyle } from './style';
複製代碼
咱們繼續來引入字體圖標文件,這裏的字體圖標是採用的阿里圖標庫地址
選擇好圖標以後下載至本地(本項目下載unicode模式)。這個操做不屬於本項目的重點,也過於簡單,就不在這浪費篇幅了。
在assets目錄下新建一個名爲iconfont的文件夾, 將.css, .eot, .svg, .ttf, .woff爲後綴的文件放到這個文件夾中。 而後將這個css文件作一些手腳,須要改爲js代碼。
因此如今的iconfont.css須要改爲iconfont.js,這裏作了一些省略,具體代碼你們直接看GitHub倉庫chapter1分支吧。
import {createGlobalStyle} from 'styled-components';
export const IconStyle = createGlobalStyle` @font-face {font-family: "iconfont"; src: url('iconfont.eot?t=1565320061289'); /* IE9 */ src: url('iconfont.eot?t=1565320061289#iefix' ...省略base64巨長字符) format('embedded-opentype'), /* IE6-IE8 */ url('data:application/x-font-woff2;charset=utf-8) format('woff2'), url('iconfont.woff?t=1565320061289') format('woff'), url('iconfont.ttf?t=1565320061289') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ url('iconfont.svg?t=1565320061289#iconfont') format('svg'); /* iOS 4.1- */ } .iconfont { font-family: "iconfont" !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } ... `
複製代碼
接下來,我們把字體引入App.js中。
//App.js
import React from 'react';
import { IconStyle } from './assets/iconfont/iconfont';
import { GlobalStyle } from './style';
function App() {
return (
<div className="App"> <GlobalStyle></GlobalStyle> <IconStyle></IconStyle> <i className="iconfont"></i> </div>
);
}
export default App;
複製代碼
接下來你們打開頁面能夠看到一個小小的放大鏡,背景變爲淺灰色,字體圖標和默認樣式起到了效果。
到此爲止,默認樣式和字體圖標就算一同引入到了項目中。你們可能會字體圖標的用法有了瞭解,可是中間的unicode編碼怎麼來的呢?別擔憂,我專門在iconfont文件夾中放了demo_index.html文件,打開便能索引不一樣圖標的unicode值啦。