1. 程式人生 > >論React後臺管理系統開發模式

論React後臺管理系統開發模式

lz在公司用react開發後臺管理系統,大家都知道,後臺管理系統,最主要的是資料的處理與後臺的互動,實現支援App各種各樣的功能。
既然說到資料處理,那麼react的資料驅動和雙向繫結就發揮了很大的作用;另外react的事件監聽機制也是核心,通過觸發事件觸發函式中的方法,函式方法的羅列成為寫後臺管理系統的重點。
————————————————————————————————————————————————————
閒話不多說,直接說我的開發模式:

這是我專案目錄
首先,來剖析一下專案的模式:
1、我所理解的react,它就是一個View,負責顯示;
2、但是通過react我們可以再View層做很多事情,例如對資料的操作和事件的觸發;


3、用react將controler層和View層結合,那麼對於一個專案來說,缺少的只是Server了;
4、這裡的Server我選擇了node服務,node服務中有很多框架可供選擇:koa、koa2、express等,對於我的專案,由於啟動較早,我選用了express,如果現在讓我重新做的話,我會毫不猶豫選擇koa2;
5、因為所有的操作和請求都是在View層做的,所以服務並不是主要的組成部分,完全可以替換成nginx,httpserver等簡單的服務;
6、專案目錄中src是根本react本地開發目錄,本地開發啟動webpack服務,開發完成後最後打包生成靜態檔案js,css和img圖片到dist資料夾中,這時候,只需要在express框架中配置一下靜態檔案目錄指向dist資料夾;

整體架構的示意圖

通過整體架構的示意圖,看出整個專案框架分為兩部分,一內層react的View層,一是外層的node服務層,下面由內到外分別詳細說一下內層外層和內外層之間的橋接;
1、內層react的View層可以理解為一個單頁應用,在一個入口頁面index.html中存在一個根元素<div id="root"></div>所有的react元件都將渲染在這個根元素內部(下面稱其為root元素),再由react引擎渲染成dom元素,瞭解react的童鞋都知道,react是虛擬的dom,是由js動態生成的dom元素,所以dom元素在root元素中是通過js指令碼控制並且不斷變化的;
a、這裡有個疑問,怎麼去控制dom的切換和區域性重新整理?
這個問題react已經幫我們做好;react的核心是資料驅動,資料驅動的概念是當資料發生變化,View隨之發生改變,es5中提出的資料驅動原理,監聽資料的讀取觸發事件,這個原理跟Vue.js中的資料雙向繫結是大同小異;在後臺管理系統中,從介面拿到資料,首先對資料進行處理(其實這一步我更願意讓後端的童鞋去做,直接拿到我想要的資料結構~),大多處理成一維陣列、二維陣列、物件、甚至字串等,將這些資料在定義的變數中儲存——setState()

方法,這樣資料就會被監聽,每次對資料進行處理後呼叫這個方法,那麼根據雙向繫結原理,頁面的顯示將會重新整理,這裡重新整理的是與修改的資料有關的元素,也就是區域性重新整理;
b、還有對於新接觸react的童鞋來說,肯定會存在這樣一個疑問,整個專案只有一個html檔案,怎麼去跳轉頁面,進行頁面間的切換?
確實,在整個react專案中,只有一個html檔案,也就是上面所說的入口頁面,也是存放root元素的頁面。在上面已經提到,react所有dom都是虛擬的,由js動態生成的,這裡說一下怎麼去控制dom元素的生成與刪除——react的前端路由;通過前端路由渲染不同的react元件來實現頁面的切換;在我的專案裡,每個頁面是一個大的元件,當然這個大的元件可能包含很多小的元件,形成元件巢狀、複用,最後將這個大元件(頁面)export出來,讓前端路由獲取,那麼當URL的hash值發生該變的時候,觸發事件去尋找與URL相匹配的路由,進而渲染與路由匹配的頁面;

2、外層node服務,這個node框架僅僅是個server,當然還需要有個後端路由來render整個專案的入口頁面–index.html,通過node服務的啟動,這個入口頁面就在伺服器上跑起來了,剩下的事情交給react來做;

剩下要說的就是請求:對於後臺管理系統來說,一個功能頁面相對有大量的請求,各種方式的請求並存,獲取資料get請求,提交資料post請求,表單,上傳圖片、檔案,匯出資料表格等等······

既然這麼多的請求,則對於請求的封裝是必不可少的,在我的專案中,選用了fetch作為請求工具,fetch請求是對ajax進行的封裝, 下面貼出fetch原生支援率;
fetch
可以看出fetch的原生支援率並不高,好在我們專案只需要支援chrome 45以上,那麼我就不用操心再引入一些庫來對fetch進行封裝了。這裡也貼出對fetch進行封裝的一些主流的方法;

引入下面這些 polyfill 後可以完美支援 IE8+1.由於 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
2.引入 Promise 的 polyfill: es6-promise
3.引入 fetch 探測庫:fetch-detector
4.引入 fetch 的 polyfill: fetch-ie8
5.可選:如果你還使用了 jsonp,引入 fetch-jsonp
6.可選:開啟 Babel 的 runtime 模式,現在就使用 async/await
Fetch polyfill 的基本原理是探測是否存在 window.fetch 方法,如果沒有則用 XHR 實現。這也是 github/fetch 的做法,但是有些瀏覽器(Chrome 45)原生支援 Fetch,但響應中有中文時會亂碼,老外又不太關心這種問題,所以我自己才封裝了 fetch-detector 和 fetch-ie8 只在瀏覽器穩定支援 Fetch 情況下才使用原生 Fetch。這些庫現在每天有幾千萬個請求都在使用,絕對靠譜!

fetch請求是由頁面(browser)發出去的,雖然chrome 45支援fetch,但是我也利用es6的Promise將fetch針對專案需求進行了封裝,使其適應各種請求,使其在報錯的時候在瀏覽器的控制檯打出錯誤日誌,這對開發很有幫助;

好了,以上所說框架的外圍思路,也就是整體的大方向。基本就是這樣,以後想到詳細的再新增~

本人菜鳥,不喜輕噴,當然,歡迎大家多多說出自己的意見和建議,在這裡我們共同進步~