論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針對項目需求進行了封裝,使其適應各種請求,使其在報錯的時候在瀏覽器的控制檯打出錯誤日誌,這對開發很有幫助;

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

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

發佈了32 篇原創文章 · 獲贊 11 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章