秦子實(shí)
摘要:在企業(yè)中臺(tái)等復(fù)雜交互場(chǎng)景的網(wǎng)頁(yè)應(yīng)用中,基于JSP、ASP等模板技術(shù)的頁(yè)應(yīng)用一直存在著拓展性差、修改維護(hù)困難、調(diào)試效率低下等問(wèn)題。因此,對(duì)于企業(yè)中臺(tái)等復(fù)雜交互場(chǎng)景,需要一種能夠完全獨(dú)立于后端復(fù)雜網(wǎng)頁(yè)應(yīng)用開(kāi)發(fā)方法,方法應(yīng)完全基于REST APl,且具備良好的拓展性,各功間能耦合性低,便于后期的迭代及維護(hù)。該文將以React框架為例,通過(guò)Redux控制數(shù)據(jù)狀態(tài)以代替?zhèn)鹘y(tǒng)基于模板的網(wǎng)頁(yè)開(kāi)發(fā),給出一種新的獨(dú)立復(fù)雜交互式前端的開(kāi)發(fā)方法。
關(guān)鍵詞:前端;JavaScript;React;Redux
中圖分類(lèi)號(hào):TP393 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2020)08-0254-02
1 概述
隨著企業(yè)業(yè)務(wù)的不斷擴(kuò)展,企業(yè)中臺(tái)網(wǎng)頁(yè)應(yīng)用需要展示的報(bào)表數(shù)量越來(lái)越多,在網(wǎng)頁(yè)上進(jìn)行的數(shù)據(jù)操作越來(lái)越復(fù)雜。傳統(tǒng)基于模板的網(wǎng)頁(yè)開(kāi)發(fā)(如JSP、ASP等)越來(lái)越難以應(yīng)付這些復(fù)雜功能,基于模板的網(wǎng)頁(yè)應(yīng)用由于HTML結(jié)構(gòu)以及表單提交機(jī)制等原因,不可避免地會(huì)出現(xiàn)頁(yè)面代碼臃腫,數(shù)據(jù)交換冗余較大。這不僅會(huì)占用客戶(hù)端瀏覽器資源導(dǎo)致加載緩慢.也會(huì)在請(qǐng)求/提交數(shù)據(jù)時(shí)大量消耗服務(wù)器資源處理無(wú)用數(shù)據(jù)。
前端框架日趨成熟,更多的企業(yè)中臺(tái)網(wǎng)頁(yè)應(yīng)用從原來(lái)的模板開(kāi)發(fā),轉(zhuǎn)移到基于如React或Vue等框架的JavaScript前端網(wǎng)頁(yè)應(yīng)用。相較于模板技術(shù),前端應(yīng)用框架的核心在于狀態(tài)管理。本文以React框架為例,介紹使用Redux庫(kù)進(jìn)行前端應(yīng)用狀態(tài)管理,以實(shí)現(xiàn)具有良好擴(kuò)展性、方便修改迭代、易于調(diào)試維護(hù)的獨(dú)立前端應(yīng)用的實(shí)現(xiàn)。
2 Redux技術(shù)簡(jiǎn)介
Redux產(chǎn)生的原因,是為了應(yīng)對(duì)功能復(fù)雜的JavaScript單頁(yè)應(yīng)用,比如在企業(yè)中臺(tái)應(yīng)用里,我們希望在同一個(gè)頁(yè)面上展示大量數(shù)據(jù),生成統(tǒng)計(jì)圖形和報(bào)表,同時(shí)也希望操作、處理這些數(shù)據(jù),使得數(shù)據(jù)實(shí)時(shí)的更新至服務(wù)器,并直接將更新結(jié)果顯示在網(wǎng)頁(yè)上。傳統(tǒng)的模板式網(wǎng)頁(yè)開(kāi)發(fā)可能就需要大量的表單提交,或是采用大量各不相同的Ajax請(qǐng)求,這不論對(duì)于前端的網(wǎng)頁(yè)渲染,還是后端的API管理,都是非常繁雜的工作,且調(diào)試環(huán)境復(fù)雜,不易定位問(wèn)題。
對(duì)于這種復(fù)雜的網(wǎng)頁(yè)應(yīng)用,Redux充分利用React等框架基于狀態(tài)(state)的頁(yè)面渲染機(jī)制,對(duì)應(yīng)用數(shù)據(jù)狀態(tài)進(jìn)行集中的、簡(jiǎn)潔的管理。同時(shí),Redux基于函數(shù)式編程的思想,使用冪等操作,加強(qiáng)了React等框架的狀態(tài)控制,使得網(wǎng)頁(yè)應(yīng)用的行為變得更容易追蹤、調(diào)試及后期功能拓展。
使用Redux管理應(yīng)用數(shù)據(jù)狀態(tài),無(wú)須引入額外工具或庫(kù),僅使用JavaScript自身的JSON數(shù)據(jù)結(jié)構(gòu)以及普通的函數(shù)實(shí)現(xiàn),Redux庫(kù)本身僅有2k,利于應(yīng)用打包和發(fā)布。Redux在使用中需要注意三個(gè)原則:
1)應(yīng)用數(shù)據(jù)狀態(tài)的唯一陛,即一個(gè)網(wǎng)頁(yè)應(yīng)用有且僅有一個(gè)狀態(tài)對(duì)象。該原則不僅使得前后端數(shù)據(jù)交換更為簡(jiǎn)潔,也能夠大幅降低應(yīng)用調(diào)試難度,有利于持續(xù)跟蹤應(yīng)用狀態(tài),加速開(kāi)發(fā)流程。
2)應(yīng)用數(shù)據(jù)狀態(tài)是只讀對(duì)象,即只能夠通過(guò)發(fā)送動(dòng)作(dis-patch actions)來(lái)改變?cè)搶?duì)象。該原則意味著無(wú)論應(yīng)用界面的改變或是后端返回的請(qǐng)求都無(wú)法直接改變?cè)摖顟B(tài)對(duì)象,任何對(duì)狀態(tài)改變的期望都必須通過(guò)發(fā)送一個(gè)用于改變狀態(tài)的動(dòng)作來(lái)實(shí)現(xiàn)。如此一來(lái),Redux通過(guò)嚴(yán)格的依次執(zhí)行各個(gè)動(dòng)作,實(shí)現(xiàn)了狀態(tài)變更的集中化管理,也同時(shí)實(shí)現(xiàn)了狀態(tài)的跟蹤、序列化、存儲(chǔ),方便了之后的調(diào)試和測(cè)試。
3)使用冪等函數(shù)改變狀態(tài),即使用純r(jià)educer函數(shù)改變狀態(tài)。所謂冪等操作,指于狀態(tài)無(wú)關(guān)的數(shù)據(jù)操作,即無(wú)論應(yīng)用當(dāng)前處于什么狀態(tài),對(duì)同樣的輸入,一定會(huì)得到同樣的輸出。re-ducer函數(shù)的輸入為原狀態(tài)和動(dòng)作,輸出為新?tīng)顟B(tài)。這種設(shè)計(jì)極大地增加了應(yīng)用的拓展性,隨著應(yīng)用功能的復(fù)雜,reducer函數(shù)可以由原來(lái)的一個(gè)操作整個(gè)狀態(tài),逐漸細(xì)分為多個(gè)分別操作狀態(tài)樹(shù)的各個(gè)部分。此外,因?yàn)閞educer是純粹的冪等函數(shù),我們可以輕松地控制各reducer的執(zhí)行順序、傳遞額外數(shù)據(jù)或是進(jìn)行函數(shù)復(fù)用(如最常見(jiàn)的分頁(yè)操作)。
3 Redux數(shù)據(jù)狀態(tài)控制
本文以React框架為例,使用Redux對(duì)React應(yīng)用的數(shù)據(jù)狀態(tài)進(jìn)行管理。Redux的數(shù)據(jù)狀態(tài)流程如圖1所示。
3.1 存儲(chǔ)及狀態(tài)對(duì)象
網(wǎng)頁(yè)應(yīng)用的所有數(shù)據(jù)均維護(hù)在一個(gè)存儲(chǔ)(store)中,這個(gè)存儲(chǔ)就是數(shù)據(jù)的容器:
想要獲取當(dāng)前的數(shù)據(jù),就要對(duì)存儲(chǔ)進(jìn)行快照,返回的快照就是應(yīng)用當(dāng)前的狀態(tài)(state):
狀態(tài)是一個(gè)普通的JavaScript對(duì)象,用戶(hù)能夠接觸到的視圖完全取決于狀態(tài),在Redux中,狀態(tài)對(duì)象到視圖呈現(xiàn)是冪等操作,即一個(gè)確定的狀態(tài)呈現(xiàn)一個(gè)確定的視圖,而一個(gè)確定的視圖能夠推出一個(gè)確定的狀態(tài),如圖l中的S1過(guò)程。
3.2 動(dòng)作對(duì)象
狀態(tài)的變化能夠引起視圖的變化,在Redux中,為了保證狀態(tài)的一致性,狀態(tài)不能被直接修改,僅能夠通過(guò)發(fā)送動(dòng)作(ac-tion)對(duì)象來(lái)變更。動(dòng)作是一個(gè)普通JavaScript對(duì)象,其中僅'type'屬性是必須的,表示動(dòng)作的名稱(chēng),其他屬性均可自定義。例如,向視圖中的一個(gè)表格添加一行數(shù)據(jù):
動(dòng)作對(duì)象通常由視圖發(fā)出,也就是用戶(hù)交在視圖上的操作期望引起狀態(tài)改變,比如在視圖的表格中點(diǎn)擊“增行”插入新的數(shù)據(jù),即圖l中的E-AI-A2過(guò)程:由視圖產(chǎn)生交互事件E(Event),進(jìn)而發(fā)送一個(gè)動(dòng)作對(duì)象A1。此外,服務(wù)端返回的數(shù)據(jù)也可以通過(guò)發(fā)送動(dòng)作對(duì)象引起狀態(tài)變化,比如視圖定期請(qǐng)求服務(wù)器獲取最新的表格數(shù)據(jù),服務(wù)器返回并渲染在視圖中,即圖1中的req-res-A2過(guò)程。
視圖和服務(wù)端要進(jìn)行多少操作,就需要產(chǎn)生有多少動(dòng)作對(duì)象,我們通常會(huì)編寫(xiě)一個(gè)函數(shù)用于快捷的生成這些動(dòng)作,這個(gè)函數(shù)也稱(chēng)作動(dòng)作生成器(action creator):