春暖花開,寫一個React小Demo,典型SPA項目

前言

本示例依照Ant Design 實戰教程(beta 版)進行編寫,非常感謝各位大佬的傾情付出!謝謝

正是江南好風景,落花時節學代碼

春暖花開,寫一個React小Demo,典型SPA項目

有了前兩節的鋪墊,這個Ant Design 實戰教程(beta 版)也覺得挺順手的,彙總下編寫的流程以及接下來要進一步學習的內容。

第一部分 整體概述

該demo是個典型的SPA項目,實現功能如佈局、側邊欄、列表、表格、彈窗等,其中包含:

  • 應用框架:Umi
  • 數據流:DvaJs
  • UI: Antd

Umi,中文可發音為烏米, 是可擴展的企業級前端應用框架。Umi 以路由為基礎的,同時支持配置式路由和約定式路由,保證路由的功能完備,並以此進行功能擴展。然後配以生命週期完善的插件體系,覆蓋從源碼到構建產物的每個生命週期,支持各種功能擴展和業務需求。


DvaJs首先是一個基於 redux 和 redux-saga 的數據流方案,然後為了簡化開發體驗,dva 還額外內置了 react-router 和 fetch,所以也可以理解為一個輕量級的應用框架。


Antd 是基於 Ant Design 設計體系的 React UI 組件庫,主要用於研發企業級中後臺產品。


<code>hhw-4:antd-course hhw$ tree -L 4 -I node_modules
.
├── config #配置文件
│ └── config.js
├── dist
│ ├── index.html
│ └── umi.js
├── mock
│ └── articleMock.js
├── package.json
└── src
├── layout
│ └── index.js
├── models
│ ├── articleModel.js
│ ├── chartModel.js
│ └── complexArticleModel.js
├── pages
│ ├── Chart
│ │ └── ChartClass.js
│ ├── Complex
│ │ ├── Article.js
│ │ └── ComplexArticle.js
│ ├── Dashboard
│ │ ├── Analysis.js
│ │ ├── Monitor.js
│ │ └── Workplace.js
│ └── HelloWorld.js
├── service
│ └── chart.js
└── util
└── request.js/<code>

第二部分

一、DvaJs--Effect

Reducer如果做了異步操作,將破壞redux中reducer是純函數的機制,effect 就是專門處理這些具有 "副作用" 的操作的執行單元。

<code>export default {
namespace: 'some_namespace',
state: {},
effects: { // 定義 effects 成員
'someEffect': function*() {},
'someOtherEffect': function*() {},
// ...
},
reducers: {
// ...
},
}/<code>
  • 宏觀上看,effect 是一層中間件。
  • 局部上看 effect 就是一個一個的 generator function。

1. 中間層

什麼是中間層?

" Middleware is some code you can put between the framework receiving a request, and the framework generating a response. "

當 action 被 dispatch 之後,會先到達 effect 處理副作用,然後該 effect 最終會促使新的 action 發送出去,這個新的 action 可能被其他的 effect 再捕獲繼續處理,也可能被 reducer 捕獲並結束,無論怎樣,最終處理邏輯的終點都將是 reducer。

2. generator function。

春暖花開,寫一個React小Demo,典型SPA項目

異步的實質是事件發生促使程序的執行點來回跳轉。我們使用 callback 本質上是描述跳轉的一種手段。generator function 並沒有改變異步的本質,只是改變了描述的方式,使得程序看起來像是同步一樣。

一個 generator function 在執行時有 兩方。一方是 generator function 本身,另一方是 generator function 的句柄持有者,而這一般都是框架所持有。我們姑且稱這個句柄為 genStub。當框架調用 genStub.next() 時,generator function 會執行到下一個 yield 然後暫停,並把 yield 後面表達式的計算值返還給框架,同時把程序執行權交給框架。框架拿到值後做處理,比如就是異步處理,處理結束拿到結果,再次調用 genStub.next(),返還值給 generator function 同時驅動它恢復執行。當恢復執行時,你可以認為 返回的處理結果會整體替換 yield <expression>,然後程序繼續執行到下一個 yield。


yield 這個單詞用在這裡特別形象:yield 本身有「讓步」的意思,也有「產出」的意思。

「generator function yield 到外部的值」和「外部返還給 generator function 的值」不是一回事!!!

3. 使用

入參有兩個對象,第一個對象就是匹配這個 effect 的 action 對象,因此可以取到約定的 payload 這個字段,第二個對象是 effect 原語集,其中 call, put 最為常用,

<code>call: 阻塞 用於調用異步邏輯,支持 promise
put: 不阻塞 用於觸發 action,一般來觸發reducer改變state
select: 不阻塞 用於從 state 裡獲取數據
take: 阻塞 dva封裝了take,可以監聽action的開始和結束階段,take會阻塞到監聽的事件觸發,才執行下一步/<code>

示例

春暖花開,寫一個React小Demo,典型SPA項目

二、代理

在前端開發中,一種常見的規避跨域的方法就是:把 ajax 請求發送到你的本地開發服務器,然後本地開發服務器再把 ajax 請求轉發到遠端去,從網絡拓撲上看本地開發服務器起著「反向代理」的作用。本地服務器和遠端服務器是「服務器和服務器間的通信」,就不存在跨域問題了。

配置代理也很簡單,只需要您在配置文件 config/config.js 中與 routes 同級處增加 proxy 字段,代碼如下,

<code>+  proxy: {
+ '/dev': {
+ target: 'https://08ad1pao69.execute-api.us-east-1.amazonaws.com',
+ changeOrigin: true,
+ },
+ },/<code>

配置的含義是:去往本地服務器 localhost:8000 的 ajax 調用中,如果是以 /dev 開頭的,那麼就轉發到遠端的 https://08ad1pao69.execute-api.us-east-1.amazonaws.com 服務器當中,/dev 也會保留在轉發地址中。

春暖花開,寫一個React小Demo,典型SPA項目

三、二次封裝

Antd真的很贊!對於開發者而言,公共的代碼其實可以二次封裝一下,比如from表單等,可以減少不少的代碼。

四、CSS Modules

春暖花開,寫一個React小Demo,典型SPA項目


CSS Modules 詳解及 React 中實踐

CSS MODULES用法教程

CSS modules 將生成全局唯一的hash值【標籤實際的class】。通過全局唯一的class name 變相的就可以獲取到局部作用域【scoped css】,如果一個 CSS 文件僅僅是作用在某個局部的話,我們稱這樣一個 CSS 文件為 CSS module。

注意:很多 CSS 選擇器是不會被 CSS Modules 處理的,比如 body、div 、a 這樣的 HTML 標籤名就不會。我們推薦如果要定義局部 css 樣式/動畫, 只使用 class 或 @keyframe。

Less 官方文檔

Less 是一個 CSS 的超集,Less 允許我們定義變量,使用嵌套式聲明,定義函數等。嚴格說 Less 包含兩部分:1. Less 的語法。2. Less 預處理器(Less preprocessor)。瀏覽器終究只認識 CSS,所以 Less 文件需要經過 Less 預處理器編譯成為 CSS。


在工具的支持下,一個 Less 文件首先會經過 CSS modules 的編譯,把類名全局唯一化,然後才被 Less preprocessor 編譯成為 CSS 文件。正因此,Less 文件可以和 CSS modules 無縫聯合使用。


<code>// less 文件
// 常量
@grey-color: rgba(0, 0, 0, 0.25);
// 類嵌套
.hello {
font-size: 32px;
font-weight: bold;
color: #30b767;
.deleted {
text-decoration: line-through;
background-color: @grey-color;
}
}

// 重寫Antd樣式
.override-ant-btn {
// CSS Modules 允許使用:global(.className)的語法,聲明一個全局規則。凡是這樣聲明的class,都不會被編譯成哈希字符串。
:global(.ant-btn) {
border-radius: 16px;
}
}
/<code>
<code>          

css module


Less class 嵌套




<button>圓角樣式按妞/<button>



<button>antd 原始按鈕/<button>



/<code>
春暖花開,寫一個React小Demo,典型SPA項目

最後強調,global 不應該被濫用,特別地我們建議:若想在某個文件中覆蓋 antd 樣式,請加上一個類似 .override-ant-btn 的類包裹住 global 修飾的名稱,以避免全局樣式聲明分散在項目各處。

還有很多待補充的內容,邊做邊學


分享到:


相關文章: