Ant Design Pro 學(xué)習(xí)筆記

學(xué)習(xí)筆記

原文地址:antDesignPro使用心得,快速開發(fā)必備。
https://www.52pojie.cn/thread-696928-1-1.html
(出處: 吾愛破解論壇)

摘要介紹

Ant Design Pro 是一個(gè)基于Ant Design搭建起來的模板項(xiàng)目。它提供了兩個(gè)主要布局:BasicLayoutUserLayout,在布局基礎(chǔ)上制作了20多個(gè)基礎(chǔ)頁(yè)面,詳情見模板介紹段落。

Ant Design Pro 主體代碼使用ES2015+語(yǔ)法規(guī)則,因此在閱讀源碼時(shí)遇到不理解的語(yǔ)法,可前往相關(guān)主頁(yè)進(jìn)行查詢。在學(xué)習(xí)筆記中,除非遇到關(guān)鍵的語(yǔ)法點(diǎn),否則不對(duì)語(yǔ)法進(jìn)行額外說明。

在接下來,將按照以下幾個(gè)方面介紹項(xiàng)目的相關(guān)代碼。
......

目錄結(jié)構(gòu)

├── mock                     # 本地模擬數(shù)據(jù)
├── node_modules             # 依賴庫(kù)
├── public
│   ├── favicon.ico          # Favicon
│   └── index.html           # HTML 入口模板
├── src
│   ├── common               # 應(yīng)用公用配置,如導(dǎo)航信息
│   ├── components           # 業(yè)務(wù)通用組件
│   ├── e2e                  # 集成測(cè)試用例
│   ├── layouts              # 通用布局
│   ├── models               # dva model
│   ├── routes               # 業(yè)務(wù)頁(yè)面入口和常用模板
│   ├── services             # 后臺(tái)接口服務(wù)
│   ├── utils                # 工具庫(kù)
│   ├── g2.js                # 可視化圖形配置
│   ├── polyfill.js          # 兼容性墊片
│   ├── theme.js             # 主題配置
│   ├── index.js             # 應(yīng)用入口
│   ├── index.less           # 全局樣式
│   └── router.js            # 路由入口
├── tests                    # 測(cè)試工具
├── .editorconfig            # 編輯器配置
├── .eslintrc                # js代碼檢測(cè)工具
├── .ga                      # 未知
├── .gitignore               # git版本配置
├── .roadhogrc               # roadhog配置
├── .roadhogrc.mock.js       # roadhog的模擬配置
├── .stylelintrc             # css代碼審查配置
├── .travis.yml              # travis持續(xù)構(gòu)建工具配置
├── package.json             # web前端項(xiàng)目配置文件
├── README.md
└──

項(xiàng)目中的幾項(xiàng)配置文件

Q:為什么要用編輯器配置

A:當(dāng)多人共同開發(fā)一個(gè)項(xiàng)目的時(shí)候,往往會(huì)出現(xiàn)大家用不同編輯器的情況。就前端開發(fā)者來說,有人喜歡 Sublime,有人喜歡 Webstorm , 也有人喜歡 Atom,還有人喜歡 Vim,HBuilder 等等。各種不同編程語(yǔ)言的開發(fā)者喜歡各種不同的編輯器。問題來了,如何讓使用不同編輯器的開發(fā)者在共同開發(fā)一個(gè)項(xiàng)目時(shí)“無痛”地遵循編碼規(guī)范(編碼風(fēng)格)?


Q:怎么用編輯器配置

A:在項(xiàng)目根創(chuàng)建一個(gè)名為 .editorconfig 的文件。安裝與編輯器對(duì)應(yīng)的 EditorConfig 插件。詳情參考編輯器配置


Q代碼檢查工具是什么?

A:js的代碼檢查工具是ESLint,css的代碼檢查工具是StyleLint,相應(yīng)的配置項(xiàng)保存在.eslintrc.stylelintrc文件中。一般來說,都不需要進(jìn)行修訂,深入學(xué)習(xí)可參考js代碼檢測(cè)工具css代碼審查配置


Qgit是什么?

Agit是版本控制工具,類似的工具還有svn。有關(guān).gitignore的配置參考git版本配置


Q:什么是持續(xù)集成系統(tǒng)

A:對(duì)個(gè)人而言,就是讓你的代碼在提交到遠(yuǎn)程——這里是GitHub——后,立即自動(dòng)編譯,并且在失敗后可以自動(dòng)給你發(fā)郵件的東西。當(dāng)然,除了編譯,還能做自動(dòng)化測(cè)試、自動(dòng)部署等。對(duì)團(tuán)隊(duì)或企業(yè)而言,這意味著更多的東西,是敏捷開發(fā)的一種踐行。travis是一種持續(xù)集成工具,企業(yè)中還有用jenkins的。有關(guān)travis的更多介紹見travis持續(xù)構(gòu)建工具配置


Q:什么是roadhog

A:這是一個(gè) cli 工具,提供 serverbuildtest 三個(gè)命令,分別用于本地調(diào)試和構(gòu)建。更多介紹見roadhog配置


Q:web前端項(xiàng)目的配置是package?

A:每個(gè)web前端項(xiàng)目的根目錄下面,一般都有一個(gè) package.json 文件,定義了這個(gè)項(xiàng)目所需要的各種模塊,以及項(xiàng)目的配置信息(比如名稱、版本、許可證等元數(shù)據(jù))。更多介紹見web前端項(xiàng)目配置文件


Q:最關(guān)鍵,初學(xué)者應(yīng)著重關(guān)心哪些

A:初學(xué)者應(yīng)將精力放在package.jsonroadhog這兩者上,其他的都可以忽略掉。

package.json摘要介紹

npm install命令根據(jù)這個(gè)package.json配置文件,自動(dòng)下載所需的模塊,也就是配置項(xiàng)目所需的運(yùn)行和開發(fā)環(huán)境。package.json文件就是一個(gè)JSON對(duì)象,該對(duì)象的每一個(gè)成員就是當(dāng)前項(xiàng)目的一項(xiàng)設(shè)置。

scripts指定了運(yùn)行腳本命令的npm命令行縮寫,比如start指定了運(yùn)行npm run start時(shí),所要執(zhí)行的命令。

進(jìn)行前端開發(fā)時(shí)可能經(jīng)常用到的幾個(gè)命令是:npm run start(進(jìn)行開發(fā)調(diào)試,縮寫成npm start)、npm run build(進(jìn)行構(gòu)建打包)。當(dāng)然也可以嘗試package.json中給出的其他命令,如:npm run analyzenpm run test等,甚至也可以自己在package.json中添加需要的命令。

dependencies字段指定了項(xiàng)目運(yùn)行所依賴的模塊,devDependencies指定項(xiàng)目開發(fā)所需要的模塊。它們都指向一個(gè)對(duì)象。該對(duì)象的各個(gè)成員,分別由模塊名和對(duì)應(yīng)的版本要求組成,表示依賴的模塊及其版本范圍。更多信息參見web前端項(xiàng)目配置文件

babel配置項(xiàng),其實(shí)是有關(guān)babel的配置內(nèi)容,寫在package.json中實(shí)際上是一種省略,也可以寫在.babelrc文件中。

lint-staged是與代碼檢查有關(guān)的配置項(xiàng),jest是與單元測(cè)試有關(guān)的配置項(xiàng)。這兩項(xiàng)的配置可以參考jestlint。這兩項(xiàng)與寫業(yè)務(wù)邏輯代碼沒有直接關(guān)聯(lián)。

roadhog摘要介紹

roadhog 是一個(gè) cli 工具,提供 serverbuildtest 三個(gè)命令,分別用于本地調(diào)試和構(gòu)建,并且提供了特別易用的 mock 功能。命令行體驗(yàn)和 create-react-app 一致,配置略有不同,比如默認(rèn)開啟 css modules,然后還提供了 JSON 格式的配置方式。

重點(diǎn)介紹roadhog有關(guān)的幾個(gè)配置項(xiàng),主要是在ant design pro的代碼中用到了這些配置項(xiàng)。

entry

指定 webpack 入口文件,支持 glob 格式。

如果你的項(xiàng)目是多頁(yè)類型,會(huì)希望把 src/pages 的文件作為入口。可以這樣配:

"entry": "src/pages/\*.js"
env

針對(duì)特定的環(huán)境進(jìn)行配置。server 的環(huán)境變量是 developmentbuild 的環(huán)境變量是 production

比如:

"extraBabelPlugins": ["transform-runtime"],
"env": {
  "development": {
    "extraBabelPlugins": ["dva-hmr"]
  }
}

這樣,開發(fā)環(huán)境下的 extraBabelPlugins["transform-runtime", "dva-hmr"],而生產(chǎn)環(huán)境下是 ["transform-runtime"]

"env": {
  "development": {
    "extraBabelPlugins": [
      "dva-hmr",
      "transform-runtime",
      "transform-decorators-legacy",
      "transform-class-properties",
      ["import", { "libraryName": "antd", "style": true }]
    ]
  },
  "production": {
    "extraBabelPlugins": [
      "transform-runtime",
      "transform-decorators-legacy",
      "transform-class-properties",
      ["import", { "libraryName": "antd", "style": true }]
    ]
  }
}

在這段代碼中,開發(fā)環(huán)境和生產(chǎn)環(huán)境分別配置,其中開發(fā)環(huán)境使用了dva-hmr插件,

externals

配置 webpackexternals 屬性。

theme

配置主題,實(shí)際上是配 lessmodifyVars。支持 Object 和文件路徑兩種方式的配置。

比如:

"theme": {
  "@primary-color": "#1DA57A"
}

或者,

"theme": "./node_modules/abc/theme-config.js"

這里有 如何配置 antd theme 的例子

babel

上述多處提到了babel,因此有必要針對(duì)babel進(jìn)行了解。用官方的用語(yǔ):Babel 是一個(gè) JavaScript 編譯器。今天就來用下一代 JavaScript 語(yǔ)法寫代碼吧!。換句話說:Babel是一個(gè)廣泛使用的轉(zhuǎn)碼器,可以將ES6代碼轉(zhuǎn)為ES5代碼,從而在現(xiàn)有環(huán)境執(zhí)行。

既然如此,接下來重點(diǎn)說說package.json.roadhogrc中有關(guān)babel的配置內(nèi)容:

presets字段用來設(shè)定轉(zhuǎn)碼規(guī)則,如package.json

"babel": {
  "presets": [
    "env",
    "react"
  ],
  ...
}

就是設(shè)定了envreact兩個(gè)轉(zhuǎn)碼規(guī)則。其中env指的是babel-preset-env,這是一個(gè)新的 preset,可以根據(jù)配置的目標(biāo)運(yùn)行環(huán)境(environment)自動(dòng)啟用需要的 babel 插件。react指的是babel-preset-react,主要是針對(duì)所有react插件的轉(zhuǎn)碼規(guī)則。

plugins配置項(xiàng)不用多說,從名稱就能看出來,就是babel的一系列插件,與ant design propackage.json相關(guān)的兩個(gè)插件在這里:transform-decorators-legacytransform-class-properties。而在.roadhogrc配置文件中也額外配置了babel的插件:transform-runtimedva-hmrbabel-plugin-import。其中唯一需要多說一點(diǎn)的是按需加載插件babel-plugin-import,它可以針對(duì)antd插件中的部分元素樣式進(jìn)行按需加載。

其實(shí)不用更多了解相關(guān)內(nèi)容,只需知道如此配置之后,1.開發(fā)者可以使用最新的ES6書寫代碼;2.放心使用react相關(guān)插件;3.在進(jìn)行run startrun build時(shí),代碼能夠自動(dòng)轉(zhuǎn)換成ES5代碼,從而在瀏覽器中執(zhí)行。

項(xiàng)目中的幾個(gè)目錄

其中mock是本地模擬數(shù)據(jù)目錄、node_modules是依賴庫(kù)目錄、public是入口目錄、src是源碼目錄、tests是測(cè)試工具目錄。在進(jìn)行npm run build之后還會(huì)生成(默認(rèn)情況下)dist目錄,這是生成的生產(chǎn)環(huán)境下的運(yùn)行代碼目錄。其他目錄不必多說,只需要核心了解src的目錄組成即可。

├── src
│   ├── common               # 應(yīng)用公用配置,如導(dǎo)航信息
│   ├── components           # 業(yè)務(wù)通用組件
│   ├── e2e                  # 集成測(cè)試用例
│   ├── layouts              # 通用布局
│   ├── models               # dva model
│   ├── routes               # 業(yè)務(wù)頁(yè)面入口和常用模板
│   ├── services             # 后臺(tái)接口服務(wù)
│   ├── utils                # 工具庫(kù)
│   ├── g2.js                # 可視化圖形配置
│   ├── polyfill.js          # 兼容性墊片
│   ├── theme.js             # 主題配置
│   ├── index.js             # 應(yīng)用入口
│   ├── index.less           # 全局樣式
│   └── router.js            # 路由入口

index.js 應(yīng)用入口

這個(gè)頁(yè)面核心就是importconst這兩個(gè)命令,至于其是否是ES6的暫且不管。

import

語(yǔ)法介紹見這里。在index.js這個(gè)文件中核心就是加載并執(zhí)行了一系列module,并引入了dvamodels兩個(gè)變量。

有關(guān)ES6的語(yǔ)法推薦查詢?nèi)钜环宸g的ECMAScript 6 入門,后續(xù)不再贅述。

const

語(yǔ)法介紹見這里。這里就是聲明了一個(gè)變量app

其他

至于index頁(yè)面中的const app = dva({})models.forEach((m)=>{app.model(m);});app.router(require('./router'));app.start('#root');這幾句代碼暫時(shí)不理會(huì),待梳理調(diào)用流程時(shí)再進(jìn)行解析。

簡(jiǎn)單說一下,由于這里是入口,所有這些內(nèi)容都是用來進(jìn)行全局設(shè)置的,至于其如何實(shí)現(xiàn)?如何調(diào)用?這些是細(xì)節(jié)內(nèi)容,在概略瀏覽代碼時(shí),可以不關(guān)注這些點(diǎn)。

router.js 路由入口

這個(gè)頁(yè)面核心就是定義路由策略。并引出了export命令。

export

語(yǔ)法介紹見這里。這里是將定義好的函數(shù)RouterConfig默認(rèn)輸出出去。

定義路由策略

通過function關(guān)鍵字定義了RouterConfig函數(shù),其輸入?yún)?shù)是{history}對(duì)象,返回值是一個(gè)頁(yè)面,其由LocaleProviderRouterSwitchRouteRedirect標(biāo)簽(component)組成的。其中每個(gè)component從哪里來,怎么操作暫時(shí)先不去關(guān)注這些細(xì)節(jié),在模仿實(shí)現(xiàn)的時(shí)候可以有樣學(xué)樣。

核心認(rèn)識(shí)到通過/user路徑可以訪問到UserLayout,通過/可以訪問到BasicLayout,默認(rèn)情況下(Redirect),會(huì)跳轉(zhuǎn)到/。具體代碼就是如下這段:

<Switch>
  <Route path="/user" component={UserLayout} />
  <Route path="/" component={BasicLayout} />
  <Redirect to="/" />
</Switch>

其他文件

theme.js主要是主題配置、index.less主要是進(jìn)行了全局樣式設(shè)置、polyfill.js是兼容性墊片、g2.js是可視化圖形的配置。一般情況下,如果不需要修改全局樣式、主題修改、對(duì)g2進(jìn)行配置,不進(jìn)行額外的瀏覽器兼容性考慮,這些文件可以不進(jìn)行深入了解。

其實(shí)對(duì)這些文件的加載過程是其使用的腳手架完成的,暫且不深入了解腳手架及webpack相關(guān)的實(shí)現(xiàn)機(jī)制。

dva

先來看看dva的介紹:dva 是基于現(xiàn)有應(yīng)用架構(gòu) (redux + react-router + redux-saga 等)的一層輕量封裝,沒有引入任何新概念,全部代碼不到 100 行。dva 是 framework,不是 library,類似 emberjs,會(huì)很明確地告訴你每個(gè)部件應(yīng)該怎么寫,這對(duì)于團(tuán)隊(duì)而言,會(huì)更可控。另外,除了 reactreact-dompeerDependencies 以外,dva 封裝了所有其他依賴。dva 實(shí)現(xiàn)上盡量不創(chuàng)建新語(yǔ)法,而是用依賴庫(kù)本身的語(yǔ)法,比如 router 的定義還是用 react-routerJSX 語(yǔ)法的方式(dynamic config 是性能的考慮層面,之后會(huì)支持)。 引用自這里,github的中文介紹在這里

這又引出了一系列新的概念:reduxreactreact-routerreact-dom等。暫且先不管這些新的概念是什么,只需要知道dva是一套框架(framework),盡量不引入新的語(yǔ)法,只是明確了每個(gè)部件該怎么寫。

redux

由于dva是一層皮,其內(nèi)涵是reduxreact等。那就了解下redux是什么?redux的中文文檔從這里找到。用幾句話概括就是:ReduxJavaScript 狀態(tài)容器,提供可預(yù)測(cè)化的狀態(tài)管理。可以讓你構(gòu)建一致化的應(yīng)用,運(yùn)行于不同的環(huán)境(客戶端、服務(wù)器、原生應(yīng)用),并且易于測(cè)試。不僅于此,它還提供 超爽的開發(fā)體驗(yàn),比如有一個(gè)時(shí)間旅行調(diào)試器可以編輯后實(shí)時(shí)預(yù)覽。

從閱讀其介紹就可以獲知:Redux 試圖讓 state 的變化變得可預(yù)測(cè),它就是管理state的解決方案。至于如何使用redux、它具有哪些核心概念、如何操作redux中的函數(shù)、使用它有哪些注意事項(xiàng)。可以通過學(xué)習(xí)redux獲知。這應(yīng)該是2天工作量的就可以完成的學(xué)習(xí)任務(wù)。

由于后續(xù)進(jìn)行開發(fā)時(shí)會(huì)反復(fù)使用到redux相關(guān)的概念,這一章節(jié)必須進(jìn)行擴(kuò)展學(xué)習(xí),可以安排后續(xù)的學(xué)習(xí)任務(wù)。但為不影響主線,暫且放下,進(jìn)行整體思路梳理。

react及其他

React 是一個(gè)采用聲明式,高效而且靈活的用來構(gòu)建用戶界面的框架。因此,有必要對(duì)react的基礎(chǔ)邏輯進(jìn)行理解,此處需要安排2天的學(xué)習(xí)任務(wù),了解react的基礎(chǔ)知識(shí)。中文的教程在這里

React Router 是完整的 React 路由解決方案。React Router 保持 UI 與 URL 同步。它擁有簡(jiǎn)單的 API 與強(qiáng)大的功能例如代碼緩沖加載、動(dòng)態(tài)路由匹配、以及建立正確的位置過渡處理。中文教程在這里

React Dom提供了針對(duì)dom的方法,具體參考這里

各目錄及相互關(guān)系

common是應(yīng)用公共配置,如導(dǎo)航信息;components是業(yè)務(wù)通用組件;layouts是通用布局;modelsdva modelroutes是業(yè)務(wù)頁(yè)面入口和常用模板;services是后臺(tái)接口服務(wù);utils是工具庫(kù);e2e是集成測(cè)試用例。

從入口開始看起,一步步抽絲剝繭看看各個(gè)組件之間是怎樣進(jìn)行調(diào)用的。

首先在index.js中加載了models中的所有model并進(jìn)行了注冊(cè)。其中app.model()函數(shù)來自于dva的用法,而且model的概念也是dva中的概念,詳見這里,而所有的model均來自于./models目錄。之后又通過app.router()語(yǔ)句注冊(cè)了路由表,詳細(xì)介紹見這里index.js文件的最后調(diào)用了 app.start('#root');,這句話的含義是啟動(dòng)應(yīng)用,詳細(xì)介紹見這里

在啟動(dòng)應(yīng)用之后,開發(fā)者可以通過瀏覽器向服務(wù)器發(fā)起請(qǐng)求訪問,以獲取頁(yè)面和數(shù)據(jù)。不詳細(xì)展開路由過程,依照路由字面含義。在訪問/時(shí),會(huì)被路由到BasicLayout布局頁(yè)面(此處參見router.js)。

布局頁(yè)面

布局頁(yè)面在開始的位置import了一系列的組件(component),定義了一些const(常量),先不去管它。接下來出現(xiàn)了詭異的class關(guān)鍵字,這有中java代碼亂入的感覺,沒關(guān)系。這是ES6的新特性,參見這里,簡(jiǎn)單理解起來可以將之看作對(duì)象。這個(gè)class繼承自React.PureComponent,在class中定義了靜態(tài)變量、構(gòu)造方法,以及一系列的內(nèi)部方法,值得注意的是方法只有被調(diào)用時(shí)才會(huì)執(zhí)行,因此class中的一系列方法都可以視為聲明,而不會(huì)順序執(zhí)行。直到最后出現(xiàn)了一個(gè)render方法,這個(gè)方法會(huì)在渲染組件時(shí)被調(diào)用(此處請(qǐng)參考react組件相關(guān)),因此我們關(guān)心頁(yè)面顯示相關(guān)邏輯就主要是關(guān)注render這個(gè)方法。

在對(duì)render方法展開說之前,先把BasicLayout最后的export說完。export defaultES6相關(guān)語(yǔ)法,前面已有介紹,指默認(rèn)輸出。connectreact-redux中的一個(gè)api,是用來連接 React 組件與 Redux store的,其用法詳情見這里,只需知道其返回的仍是原React組件(當(dāng)前事例中是BasicLayout),并與已有的狀態(tài)信息state相關(guān)聯(lián)。

再展開說render。1.在render中,用到了一系列來自antd的組件如:LayoutMenu等,其相關(guān)的介紹不展開,可以到antd網(wǎng)站參考其相關(guān)教程。2.當(dāng)然也需要用到dva封裝好的有關(guān)路由的一系列組件,如:LinkRouteRedirectSwitch。3.同樣也用到了ant design pro中創(chuàng)建的組件,如:HeaderSearchNoticeIconGlobalFooter。如果深入進(jìn)去了解每個(gè)組件的實(shí)現(xiàn)原理,會(huì)不可避免陷入泥潭,對(duì)此只需閱讀antddva的相關(guān)api,明確該組件是什么、怎么做就好,接下來就是實(shí)踐中掌握。

BasicLayout布局的render中,核心布局就是左邊欄(Sider,參考antdLayout.Sider)、頂部(Header,參考Layout.Header、內(nèi)容區(qū)(Content,參考Layout.Content。在內(nèi)容區(qū)除了整體的可更換的頁(yè)面以外還有自創(chuàng)建的腳部區(qū)域(GlobalFooter),其中左邊欄、頂部使用了ant design pro樣例中自創(chuàng)建的組件,包括:搜索框(HeaderSearch)、通知提醒框(NoticeIcon),以及antd中已經(jīng)封裝好的通用模板:菜單欄(Menu)、下拉菜單(Dropdown)、頭像(Avatar)、加載中(Spin)、圖標(biāo)(Icon)、標(biāo)簽(Tag)、全局提示(message)。如上所述,有關(guān)antddva中已經(jīng)封裝好的通用模板,應(yīng)當(dāng)閱讀相關(guān)的api,而不應(yīng)該重新造一遍輪子。

整個(gè)布局頁(yè)面大體就是這個(gè)樣子,在ant design pro中還提供了另一個(gè)頁(yè)面布局就是UserLayout。如果實(shí)際開發(fā)中還需要其他的頁(yè)面布局,就需要自己撰寫,大體來說就要研究清楚BasicLayout頁(yè)面中的各方面細(xì)節(jié),并能夠再依照需求完成創(chuàng)建。

Redirect 路由

BasicLayout頁(yè)面布局中,Content區(qū)是通過

{
  getRouteData('BasicLayout').map(item =>
    (
      <Route
        exact={item.exact}
        key={item.path}
        path={item.path}
        component={item.component}
      />
    )
  )
}
<Redirect to="/dashboard/analysis" />

完成頁(yè)面加載。有關(guān)RedirectRoute的詳細(xì)介紹在這里這里。先來看看getRouteData函數(shù)干了什么。

getRouteData函數(shù)來自于../utils/utils文件,通過對(duì)utils.js查看,可以看出該函數(shù)引用了../common/nav文件,也就是nav.js,結(jié)合nav.js文件進(jìn)行梳理。綜合三個(gè)位置可以分析得到如下過程:

  1. nav.js中通過import...from...引入了layoutsroutes中的布局頁(yè)面和業(yè)務(wù)頁(yè)面(常用模板)。由此可知 如需添加新的頁(yè)面可以參照這個(gè)格式引入
  2. nav.js中定義了data,以json的格式定義了菜單目錄結(jié)構(gòu),并將引入的頁(yè)面(1.)以變量的形式引入進(jìn)來。這個(gè)目錄內(nèi)在含義可以后續(xù)深入了解,需要注意的是:在添加新頁(yè)面時(shí)應(yīng)參照這個(gè)json格式添加
  3. 通過export default關(guān)鍵字把data輸出出來。
  4. utils.js中,import navData from '../common/nav';引入了剛剛定義的data并重命名為navData。
  5. utils.js中的函數(shù)getRouteData中,用到了數(shù)組對(duì)象中的函數(shù)some官方中譯文檔解讀參考)、filter官方中譯文檔解讀參考)以及lodashcloneDeep
  6. 依照字面意思來理解,getRouteData做了兩件事:1.對(duì)輸入?yún)?shù)path,進(jìn)行檢查,如果檢查不通過返回null(檢查含義主要是確保path是一個(gè)有效layout,同時(shí)layoutchildren不為空);2.對(duì)檢查通過的path,獲取該布局下的所有數(shù)據(jù),并將數(shù)據(jù)轉(zhuǎn)換成數(shù)組,數(shù)組的每個(gè)元素是被稱為item,該item具有path屬性、exact屬性、component屬性、children屬性。
  7. 解釋下item的四個(gè)屬性:path屬性會(huì)賦值給外層調(diào)用中Routepath屬性;component屬性會(huì)賦值給外層調(diào)用中component屬性;children屬性是用來控制如何進(jìn)行遞歸的;exact屬性會(huì)賦值給外層調(diào)用中exact屬性。
  8. getRouteData就獲得了具有pathcomponent等屬性的元素?cái)?shù)組。
  9. BasicLayout中調(diào)用了getRouteData函數(shù)并對(duì)返回?cái)?shù)組逐項(xiàng)拆解,組成Route
  10. 通過以上過程就將nav中的json格式配置轉(zhuǎn)換成了頁(yè)面中的跳轉(zhuǎn)路由。當(dāng)頁(yè)面中的地址欄中出現(xiàn)/一級(jí)目錄/二級(jí)目錄時(shí),就可以通過Route找到對(duì)應(yīng)的component并進(jìn)行加載。

這樣一來,layoutsroutesnav.jsutils.js之間進(jìn)行路由的鏈路就清晰了。由于我們是在實(shí)踐中學(xué)習(xí),對(duì)一些實(shí)現(xiàn)細(xì)節(jié)還不必過度深究,只需要知道頁(yè)面是怎樣串起來的,以及為什么改變nav.js中的目錄樣式就能夠操作路由,同時(shí)能夠結(jié)合實(shí)際的路由需要對(duì)路由進(jìn)行必要整改就可以動(dòng)手執(zhí)行了。

Menu 導(dǎo)航菜單

導(dǎo)航菜單顧名思義就是左側(cè)欄中的內(nèi)容,在BasicLayout中就是這段代碼

<Menu
  theme="dark"
  mode="inline"
  {...menuProps}
  onOpenChange={this.handleOpenChange}
  selectedKeys={this.getCurrentMenuSelectedKeys()}
  style={{ margin: '16px 0', width: '100%' }}
>
  {this.getNavMenuItems(this.menus)}
</Menu>

核心函數(shù)封裝成了getNavMenuItems,其操作的對(duì)象是menus屬性,而在構(gòu)造方法中對(duì)menus的值進(jìn)行了初始化。綜合來看梳理成如下過程:

  1. BasicLayout的構(gòu)造方法中,通過getNavData方法獲取到nav.js中定義好的data
  2. data本身是數(shù)組,通過reduce官方中譯文檔解讀參考)方法和concat(官方中譯文檔)方法將數(shù)組規(guī)約成一個(gè)新的數(shù)組。新的數(shù)組是原數(shù)組中每個(gè)元素的children數(shù)組再拼裝在一起組成的。換句話說,nav中定義的data,第一層級(jí)是布局(layout),布局的children是頁(yè)面集合(第二層級(jí)),頁(yè)面集合的children是業(yè)務(wù)頁(yè)面(第三層級(jí))。此處的轉(zhuǎn)換就是將layout去掉,拼裝成頁(yè)面集合(第二層級(jí))的數(shù)組。
  3. getNavMenuItems函數(shù)中,對(duì)menus進(jìn)行操作。對(duì)每一項(xiàng)(也就是頁(yè)面集合)轉(zhuǎn)換成一個(gè)Menu.Item。這是可以理解的。
  4. getNavMenuItems函數(shù)從上到下核心做了5件事:1.判斷有沒有可顯示的name,如果沒有將返回null;2.給item制定path,也就是跳轉(zhuǎn)路徑,采用父子路徑拼裝的思路完成;3.如果存在children且存在name不為空,構(gòu)造子菜單SubMenu;4.明確可顯示的圖標(biāo);5.拼裝成Menu.Item
  5. 在拼裝Item過程中,涉及到了跳轉(zhuǎn)路徑path的構(gòu)造、可顯示的nameicon

結(jié)合路由和導(dǎo)航就可以理解整個(gè)頁(yè)面左側(cè)導(dǎo)航欄的動(dòng)態(tài)顯示、通過導(dǎo)航欄的點(diǎn)擊實(shí)現(xiàn)頁(yè)面的路由過程。

布局頁(yè)面的其他關(guān)注點(diǎn)

BasicLayout中還引入了styles,這是一個(gè)less文件。

Less 是一門 CSS 預(yù)處理語(yǔ)言,它擴(kuò)展了 CSS 語(yǔ)言,增加了變量、Mixin、函數(shù)等特性,使 CSS 更易維護(hù)和擴(kuò)展。

因此只需要把less當(dāng)成是基本的樣式對(duì)待就好。雖然它有不少新的特性,但大多數(shù)情況下,styles都是出現(xiàn)在某個(gè)組件的className位置,以引用的方式加入進(jìn)來(css的外聯(lián))。

有關(guān)LinkIcon等框架提供的組件,需要自行查閱相關(guān)API,HeaderSearchNoticeIconGlobalFooter的用法在后續(xù)提到components的用法時(shí)再行展開。

動(dòng)態(tài)獲取數(shù)據(jù)

BasicLayout頁(yè)面中進(jìn)行動(dòng)態(tài)加載數(shù)據(jù)就涉及到React組件生命周期,相關(guān)資料也可參考這里,總之在BasicLayout頁(yè)面中用到的就是componentDidMount函數(shù)進(jìn)行數(shù)據(jù)動(dòng)態(tài)加載的。這個(gè)函數(shù)核心只是調(diào)用了dispatch

componentDidMount() {
  this.props.dispatch({
    type: 'user/fetchCurrent',
  });
}

此時(shí)就要引出前面提到的dvaredux相關(guān)的概念了。上文中提到了app.model()這個(gè)函數(shù)及其參考。接下來把整體邏輯串起來:

  1. 通過app.model()方法,對(duì)model進(jìn)行注冊(cè),這個(gè)model概念來自于dva
  2. model中的effects部分,包裝自redux-saga
  3. this.props.dispatch方法源自redux,見這里
  4. model注冊(cè)時(shí),其實(shí)就是注冊(cè)了一系列的監(jiān)聽器,等待著被觸發(fā)。
  5. dispatch時(shí),會(huì)接受一個(gè) Action 對(duì)象作為參數(shù),將它發(fā)送出去。關(guān)于redux的數(shù)據(jù)流程參見這里
  6. 'user/fetchCurrent'為例,依照dva的邏輯會(huì)找到model中的user命名空間,并在其下找到fetchCurrent方法。因此,dispatch之后會(huì)觸發(fā)models/user.js中的fetchCurrent方法。
  7. 又通過import加載了services/user.js中的queryCurrent異步調(diào)用方法。
  8. services/user.js中,importutils/request.js,并調(diào)用了其中的request請(qǐng)求。并傳遞請(qǐng)求路徑為'/api/currentUser'
  9. 最終在utils/request.js中找到了request函數(shù),其核心調(diào)用了dvafetch函數(shù)進(jìn)行url請(qǐng)求。
  10. dva中的fetch包裝自isomorphic-fetch,說明見這里
  11. 至此將發(fā)起fetch請(qǐng)求,向服務(wù)端請(qǐng)求相應(yīng)的數(shù)據(jù)。以queryCurrent為例,將利用url:'/api/currentUser'
  12. .roadhogrc.mock.js中配置了代理,同時(shí)可以找到/api/currentUser請(qǐng)求返回的數(shù)據(jù)。后續(xù)不再贅述。

通過上述分析,可見關(guān)鍵點(diǎn)在1.model的撰寫和注冊(cè);2.dispatch的正確調(diào)用;3.后臺(tái)業(yè)務(wù)請(qǐng)求的封裝。這涉及到了modelsservices目錄內(nèi)容及utils/request.js(由于這個(gè)文件主要完成的是底層封裝,基本可以不去關(guān)注。以添加新的后臺(tái)請(qǐng)求為例,需要完成:1.在services目錄下定義好請(qǐng)求的url以及函數(shù)名稱;2.將該后臺(tái)請(qǐng)求添加到對(duì)應(yīng)的model中。以添加新的數(shù)據(jù)加載為例,需要完成:1.在models目錄下中定義新的model,注意namespacestateeffectsreducerssubscriptions的合理使用;2.如果涉及到后臺(tái)請(qǐng)求數(shù)據(jù)需要引入services;3.在合理的事件處發(fā)起dispatch。需要注意的是dispatch的目錄要與modelnamespace相一致。

components目錄

這個(gè)目錄其實(shí)是抽象出來的一系列的業(yè)務(wù)通用組件。詳細(xì)內(nèi)容不再展開。包括BasicLayout中已經(jīng)提到的HeaderSearchNoticeIconGlobalFooter組件,實(shí)際上都是自行封裝的結(jié)果。

e2e目錄

這個(gè)目錄是端到端測(cè)試的相關(guān)目錄,相關(guān)信息可以從這里了解一些。
由于不在主線學(xué)習(xí)范圍之內(nèi)暫不理會(huì)。

關(guān)于redux-auth-wrapper

這個(gè)項(xiàng)目的github地址在這里

通過對(duì)這個(gè)項(xiàng)目demo的初步體驗(yàn),感覺到它是基于redux的state進(jìn)行設(shè)計(jì)的。先來說說state,這是駐留在瀏覽器內(nèi)存中的一個(gè)數(shù)據(jù)結(jié)構(gòu),可以講起理解為記錄在瀏覽器(客戶端)中的用戶最新狀態(tài)信息。redux-auth-wrapper的作用位置是route時(shí),就是利用state中的信息驗(yàn)證用戶是否可以進(jìn)行跳轉(zhuǎn)。這是對(duì)用戶體驗(yàn)的一重優(yōu)化。

有關(guān)圖標(biāo)

擴(kuò)展當(dāng)前的圖標(biāo)

核心參考這篇擴(kuò)展教程

  • Q:為什么需要用到擴(kuò)展圖標(biāo)?

  • A:阿里框架所使用的圖標(biāo)庫(kù),不足以滿足實(shí)際開發(fā)需要。

  • Q:阿里框架庫(kù)中有哪些圖標(biāo)?

  • A:阿里框架中的所有圖標(biāo)可以在ant design的資源列表中下載到,點(diǎn)擊這里

  • Q:為什么在下載的圖標(biāo)庫(kù)中有些圖標(biāo)找不到?如:dashboard,它出現(xiàn)在ant design pro的項(xiàng)目中,但是在圖標(biāo)庫(kù)中卻沒有。

  • A:因?yàn)閍nt design pro依賴的是ant-design-3.0.0-beta.5,阿里發(fā)布的圖標(biāo)庫(kù)的版本號(hào)是2.10.x

  • Q:如何找到最新的圖標(biāo)庫(kù)?

  • A:可以在ant-design代碼庫(kù)的tag中找到3.0.0-beta.5的代碼中找到。其路徑是components\style\core\iconfont.less中能夠找到映射關(guān)系。當(dāng)然阿里使用了一整套的圖標(biāo)(svg、ttf、woff、eot等多種格式,掃盲貼見這里),并用css和js完成適配映射,將圖標(biāo)映射成16進(jìn)制的unicode,并指定相應(yīng)的class代碼。只要確保工程項(xiàng)目中使用到的圖標(biāo)庫(kù)中存在某個(gè)圖標(biāo),就可以直接在項(xiàng)目中使用相應(yīng)的unicode代碼或class代碼。如果工程項(xiàng)目中使用到了第三方圖標(biāo),可以對(duì)其擴(kuò)展。

  • Q:如何依照阿里的icon框架進(jìn)行圖標(biāo)擴(kuò)展?

  • A:參考擴(kuò)展教程

  • Q:還有哪些值得參考的與ant design圖標(biāo)有關(guān)的資料?

  • A:1.圖標(biāo)設(shè)計(jì)規(guī)范;2.本地部署 Iconfont 示例;3.antd圖標(biāo)庫(kù)2.10.x;4.內(nèi)網(wǎng)環(huán)境使用離線Icon圖標(biāo)資源

  • Q:在adp項(xiàng)目中應(yīng)該怎么操作?

  • A:由于我們的工程打包環(huán)境是可以聯(lián)網(wǎng)的,因此不需要進(jìn)行離線Icon設(shè)置,也不需要完成Iconfont的本地部署。只需要按照擴(kuò)展教程進(jìn)行新組建的擴(kuò)充即可。在擴(kuò)充時(shí)用iconfont添加新的icon,然后構(gòu)造成相應(yīng)的圖標(biāo)庫(kù),在下載到對(duì)應(yīng)位置即可。鑒于已完成基礎(chǔ)性操作,后續(xù)添加新圖標(biāo)的流程:1.在iconfont的圖標(biāo)庫(kù)中添加新的圖標(biāo);2.將圖標(biāo)庫(kù)下載下來覆蓋項(xiàng)目圖標(biāo)目錄/public/fonts/iconfont;3.在項(xiàng)目中使用圖標(biāo)代碼。

React Developer Tools

  • Q:react的源代碼通過編譯組成了普通html、css代碼。那怎樣在瀏覽器中查看對(duì)應(yīng)的源代碼?

  • A:使用React Developer Tools可以輔助在chrome中查看源代碼,參見這里

  • Q:相關(guān)鏈接

  • A:chrome插件下載地址

有關(guān)樣式的幾個(gè)注意事項(xiàng)

  • Q:如何在ant design的樣式代碼中使用css常用的'-'?如:“font-size”

  • A:此處核心遇到的是js中的'.'取值與'[]'取值的區(qū)別,參考這里的解答

  • Q:ant design中推薦哪種方式編寫樣式?

  • A:ant design中推薦使用駝峰式的樣式書寫,如:'fontSize'。同時(shí)這個(gè)框架中大量使用了'.'操作符進(jìn)行對(duì)象操作,使用import語(yǔ)法進(jìn)行整個(gè)的代碼組織。

  • Q:在引用樣式時(shí)傳統(tǒng)的寫法可以使用多個(gè)classname,如class="csdn-toolbar csdn-toolbar-skin-black ",在ant design中怎樣使用多個(gè)樣式?

  • A:使用composes,參考這里Class 的組合章節(jié)。

  • Q:還有哪些注意事項(xiàng)?

  • A:1.在ant design的框架下推薦XXX.js文件與XXX.css(或XXX.less)文件放在一起,而不是使用分開的css、html、js目錄分別管理不同類型的文件。這是源自react的模塊化管理的思想。2.CSS Modules是ant design中默認(rèn)使用。簡(jiǎn)要介紹見這里

  • Q:為什么樣式會(huì)變成類似于class="globalFooter___1cM92"

  • A:因?yàn)镃SS Modules定義了局部作用域的概念,為達(dá)到局部作用效果,構(gòu)建工具會(huì)對(duì)class的name進(jìn)行哈希操作,使類名變成獨(dú)一無二。常用工具就是webpack,而使用的插件是css-loader

關(guān)于數(shù)據(jù)查詢的方法

  • Q:如何制定模擬的數(shù)據(jù)請(qǐng)求?

  • A:ant design pro中使用了mock。可以在.roadhogrc.mock.js中進(jìn)行數(shù)據(jù)請(qǐng)求配置。比如'GET /api/testapi'是新添加的模擬數(shù)據(jù)請(qǐng)求。可以嘗試在瀏覽器中訪問這個(gè)url:http://localhost:8000/api/testapi,確認(rèn)該接口可以訪問數(shù)據(jù)。

  • Q:在ant design pro中如何發(fā)起數(shù)據(jù)請(qǐng)求?

  • A:在services目錄中的文件添加一個(gè)request請(qǐng)求。如:export async function queryTestData(){ return request('/api/testapi'); }就在js中定義了一個(gè)request,發(fā)起相應(yīng)的request請(qǐng)求。因此,就可以在需要請(qǐng)求數(shù)據(jù)的位置直接調(diào)用queryTestData方法。

  • Q:可不可以在頁(yè)面點(diǎn)擊事件中直接調(diào)用queryTestData方法?ant design pro中為什么沒用這種方法?

  • A:首先,這種調(diào)用方法是基礎(chǔ)的調(diào)用,是可以在頁(yè)面布局中引入相應(yīng)的文件直接調(diào)用這個(gè)函數(shù)的。ant design pro中遵從了react和redux的設(shè)計(jì)理念,承認(rèn)component的模塊化設(shè)計(jì)理念,并加強(qiáng)瀏覽器緩存的管理。

  • Q:ant design pro設(shè)計(jì)框架中在哪里調(diào)用queryTestData方法?

  • A:在models中進(jìn)行調(diào)用。

  • Q:那models有什么含義?

  • A:在瀏覽器的緩存中,每個(gè)component都有其自身的state(這是redux里的基礎(chǔ)概念),也就是緩存。而models就是緩存進(jìn)行對(duì)象化管理的抽象。因此可以把models中的model看作是不同的業(yè)務(wù)對(duì)象。而每個(gè)業(yè)務(wù)對(duì)象都可以按對(duì)象邏輯調(diào)用service方法。如在models/user.js中進(jìn)行如下調(diào)用:

*fetchTestData(_, { call, put }){
  const response = yield call(queryTestData);
  yield put({
    type: 'returnTestData',
    payload:response,
  });
}
  • Q:fetchTestData函數(shù)書寫有什么值得注意的地方?

  • A:1.這個(gè)函數(shù)寫在model中,model的概念來自于dva,見這里,同時(shí)其概念解釋見這里。2.要充分理解model的概念,才能更合理書寫和調(diào)用相關(guān)函數(shù)。3.model的概念還整合了redux-saga的設(shè)計(jì)理念。4.model中的effects設(shè)計(jì)來源于redux-saga的設(shè)計(jì),參考這里。5.effects部分中使用了星號(hào)和yield關(guān)鍵字,是源自于ES6中的Generator語(yǔ)法,以及異步調(diào)用,因此只需要認(rèn)識(shí)到星號(hào)標(biāo)識(shí)了這不是普通函數(shù),是可以暫停執(zhí)行的,加星號(hào)以示區(qū)別;yield標(biāo)識(shí)此處可以暫停,并在獲得執(zhí)行權(quán)時(shí)從此處開始執(zhí)行,調(diào)用方式參考文檔里的next調(diào)用。6.call和put來自于redux-saga(是Redux異步操作的中間件),更全的redux接口見這里。7.call實(shí)際上就是創(chuàng)建了一條描述結(jié)果的信息(上例中的含義就是異步(yield)調(diào)用queryTestData,調(diào)用完成后(call)將結(jié)果賦值給response)。8.put實(shí)際上是用來創(chuàng)建dispatch Effect的(上例中的含義就是異步(yield)調(diào)用returnTestData,并傳遞參數(shù)response),可從這里這里以及這里了解更多的信息。

  • Q:model中如何改變相關(guān)狀態(tài)?

  • A:model的狀態(tài)存儲(chǔ)在state對(duì)象中,在示例中我們添加了testdata:{},對(duì)象。依照redux的設(shè)計(jì)理念,所有對(duì)狀態(tài)的修改都應(yīng)該在reducer中完成。因此model中的reducers部分就是定義一系列修改state的函數(shù),如:queryTestData函數(shù)。

  • Q:model中的state和action是什么?

  • A:其中state是函數(shù)調(diào)用前的狀態(tài),而action就是dispatch發(fā)出的action。

  • Q:model中的狀態(tài)信息(state)怎么在頁(yè)面中使用?

  • A:通過connect函數(shù)(來自于react-redux),其實(shí)connect設(shè)計(jì)的初衷就是把容器組件與redux相連接。其更多使用方法見這里。在示例中,就是通過

@connect(state => ({
  chart: state.chart,
  testdata: state.user.testdata,
}))

方法將redux中的state連接到了這個(gè)頁(yè)面(容器組件)中。通過這句話testdata: state.user.testdata,就將全局state中命名空間(namespace)為user下的狀態(tài)(state)屬性testdata對(duì)象與容器組件中的testdata屬性(存在于props中)相關(guān)聯(lián)。

  • Q:怎樣把容器組件中的屬性與頁(yè)面顯示相關(guān)聯(lián)?
  • A:通過const { chart,testdata } = this.props;這句話能夠把屬性(props)中的對(duì)象testdata解析出來。在頁(yè)面上通過{testdata.name}將相應(yīng)的值取出來。

例:Analysis頁(yè)面折線圖切換

<Card
  loading={loading}
  className={styles.offlineCard}
  bordered={false}
  bodyStyle={{ padding: '0 0 32px 0' }}
  style={{ marginTop: 32 }}
>
  <Tabs
    activeKey={activeKey}
    onChange={this.handleTabChange}
  >
    {
      offlineData.map(shop => (
        <TabPane
          tab={<CustomTab data={shop} currentTabKey={activeKey} />}
          key={shop.name}
        >
          <div style={{ padding: '0 24px' }}>
            <TimelineChart
              data={offlineChartData}
              titleMap={{ y1: '客流量', y2: '支付筆數(shù)' }}
            />
          </div>
        </TabPane>)
      )
    }
  </Tabs>
</Card>
  • Q:怎樣從接口中獲取數(shù)據(jù)?
  • A:涉及到數(shù)據(jù)獲取的部分有兩個(gè)對(duì)象:offlineData、offlineChartData。這兩個(gè)對(duì)象都是通過如下方法實(shí)現(xiàn)的數(shù)據(jù)調(diào)用,詳細(xì)過程見'關(guān)于數(shù)據(jù)查詢的方法'部分
  componentDidMount() {
    this.props.dispatch({
      type: 'chart/fetch',
    }).then(() => this.setState({ loading: false }));
  }
  • Q:currentTabKey怎樣在頁(yè)面實(shí)現(xiàn)數(shù)值傳遞?

  • A:先明確頁(yè)面加載時(shí)會(huì)調(diào)用的幾個(gè)函數(shù):componentDidMountcomponentWillUnmountrender。這涉及到react組件的生命周期概念,參考這里的簡(jiǎn)介。現(xiàn)在只需要知道:
    componentDidMount()方法會(huì)在組件(所謂組件就是Component)掛在之后調(diào)用一次;
    componentWillUnmount()方法會(huì)在組件被卸載時(shí)調(diào)用。;
    render()有四種觸發(fā)場(chǎng)景,詳情不贅述,只需知道頁(yè)面中調(diào)用this.setState方法是會(huì)觸發(fā)當(dāng)前組件的更新。
    可以看出如下過程:
    1.組件初始化時(shí)定義了currentTabKey變量,并賦值為'';
    2.在初始化時(shí)最后調(diào)用了render方法,依據(jù)currentTabKeyactiveKey進(jìn)行賦值;
    3.在真正渲染時(shí)通過activeKey設(shè)置TabsactiveKey屬性并傳值給CustomTab組件;
    4.在Tabs組件被點(diǎn)擊時(shí)通過onChange方法回調(diào)handleTabChange函數(shù);
    5.在回調(diào)函數(shù)中通過this.setStatestate中的currentTabKey值修改;
    6.this.setState 觸發(fā)了render函數(shù)被再次調(diào)用。

  • Q:還有哪些是值得關(guān)注的點(diǎn)?

  • A:TabPane的變量通過const { TabPane } = Tabs;Tabs中析取出來,也就是說TabPane是定義在Tabs中的一個(gè)子組件;
    CustomTab是一個(gè)自定義組件,由于其在Tab的頁(yè)簽位置,同時(shí)使用了ReactNode來做頁(yè)簽,因此需要自行控制選中狀態(tài),由此theme={(currentKey !== data.name) && 'light'}color={(currentKey !== data.name) && '#BDE4FF'}就是在控制相應(yīng)的樣式。

相關(guān)鏈接整理

很有用的單獨(dú)說一遍

dva:github項(xiàng)目

React中文文檔

React 入門實(shí)例教程(阮一峰)

Redux 入門教程(一):基本用法(阮一峰)

Redux 中文文檔

Redux-saga 中文文檔

Redux 三重境

ECMAScript 6 入門

React Router 中文文檔

React Router 使用教程(阮一峰)

Ant Design 指引

dva:github項(xiàng)目

dva:React+Redux最佳實(shí)踐

dva:中文Readme

dva:中文API

一起學(xué)react (1) 10分鐘 讓你dva從入門到精通

初識(shí) Dva

dva源碼解析(一)

dva 入門:手把手教你寫應(yīng)用



React中文文檔

React:State&生命周期

React:組件 & Props

React 入門實(shí)例教程(阮一峰)

React PureComponent源碼解析

ReactJS分析之入口函數(shù)render

談一談創(chuàng)建React Component的幾種方式

React Dom



Redux 入門教程(一):基本用法(阮一峰)

Redux 關(guān)于react-redux中的connect用法介紹及原理解析

Redux 中文文檔

Redux 數(shù)據(jù)流

Redux-saga 中文文檔

Redux-saga 實(shí)踐總結(jié)

Redux 三重境

實(shí)例講解基于 React+Redux 的前端開發(fā)流程



ECMAScript 6 入門

ES5中新增的Array方法詳細(xì)說明

Ecma標(biāo)準(zhǔn)

Lodash 中文文檔

exports 和 module.exports 的區(qū)別

ES6:export default 和 export 區(qū)別

fetch的用法

React 語(yǔ)法之let和const命令

ES6展開運(yùn)算符



React Router

React Router 中文文檔

React Router 使用教程(阮一峰)

React Router Redirect

path-to-regexp

Path-to-RegExp 使用



Ant Design 指引

Ant Design of React

Ant Design Pro教程

自定義主題開發(fā)中,修改theme.js需要重啟

如何評(píng)價(jià) Ant Design 這個(gè)項(xiàng)目(一個(gè)設(shè)計(jì)語(yǔ)言)?

Ant Design源碼分析(一):Icon組件



roadhog

less 快速入門

Less簡(jiǎn)介及簡(jiǎn)單用法

Babel 入門教程(阮一峰,<s>不知何故他已經(jīng)在自己的博客中刪除了,只能從archive找到</s>)

stylelint初體驗(yàn)

JS/React 開發(fā)者的 Atom 終極配置

自動(dòng)化e2e測(cè)試 -- WebDriverJS,Jasmine和Protractor

Webpack單元測(cè)試,e2e測(cè)試

怎么為大中型的vue.js項(xiàng)目編寫e2e測(cè)試?

Atom編輯器折騰記_(23)加快React開發(fā)的插件匯總

Fetch API

react&webpack使用css、less && 安裝原則 --- 從根本上解決問題。

less-loader

webpack-中文文檔

React中的DOM操作

編輯器配置

js代碼檢測(cè)工具

css代碼審查配置

git版本配置

travis持續(xù)構(gòu)建工具配置

roadhog配置

web前端項(xiàng)目配置文件

jest

lint

如何配置 antd theme 的例子

dva-hmr

babel-plugin-import

babel-preset-env

babel-preset-react

transform-decorators-legacy

transform-class-properties

transform-runtime

antd

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,466評(píng)論 25 708
  • ant Design給人的感覺就是:很強(qiáng)大、很龐大(雜亂)。 它號(hào)稱已經(jīng)應(yīng)用于多個(gè)生產(chǎn)項(xiàng)目了。或者看這里。或者看看...
    松鼠楊閱讀 16,321評(píng)論 4 21
  • 前段時(shí)間和朋友聊天,聊到女孩子不應(yīng)該讓自己的男朋友陪自己去逛地?cái)偅词鼓阌邪训財(cái)傌洿┏龃笈谱拥哪芰Γ阌心芰I牌...
    怕曬仍向陽(yáng)閱讀 4,455評(píng)論 0 2
  • 最近在看軍師聯(lián)盟。里面兩個(gè)人的斗法讓我印象深刻。那就是楊修和司馬懿的較量。楊修當(dāng)時(shí)無論是才華還是地位都在司馬懿之上...
    mylkevin閱讀 288評(píng)論 0 0
  • 分享198 時(shí)間每到此時(shí)此刻就需要用度秒如年計(jì)算,面對(duì)著一個(gè)個(gè)蠢蠢欲動(dòng)的學(xué)生,這又是斗智斗勇的過程,怎樣讓他...
    梓桐潔兒閱讀 439評(píng)論 0 2