基於 React 的可視化編輯平臺實踐

前言

前段時間發在朋友圈的一句話:各種自主搭建的平臺,想起好多年各種DIY博客,行業門戶網站,本質不變,變的是實現的手段了。

正文從這開始~~

本文主要介紹了基於 React 構建可視化編輯平臺的實踐,包括對可視化拖拽佈局、在線編輯、同構直出的實現。

背景

目前,HRG 的英才校園在線招聘業務有大量的企業定製化需求,企業在英才校園做招聘,同時也希望有自己的招聘主頁,每年都會招聘一部分兼職同學來開發這類的招聘主頁,這類招聘主頁通常不復雜,但是如果全部需要前端同學實現的話,還是很耗時費力的,我們希望能通過技術手段不斷的提升這類業務的交付效率。

提效規劃

定製頁相關的項目,早期是通過靜態頁來做的,純靜態頁對開發者來說上手容易,但是很難做組件化,上線流程完全靠手工,成本太高,所以我們計劃逐步推進通過可視化編輯提升效率。

項目整體分了兩期:

一期,實現了可視化的在線編輯、發佈,支持流式佈局、絕對定位佈局、同構直出、動畫,提供了通用的組件庫。

二期,支持組件可擴展,提供組件開發工具,組件市場,三期仍在完善階段,暫未發佈。

系統演示

首先看下我們的系統演示,然後再逐步分析深入,主要是可視化編輯系統開發思路,以及關鍵模塊的實現。

系統維度分析

針對可視化編輯平臺,我們做了一些調研,有一些思想我們覺得挺有意義,這裡分享一下,參考文章見參考文獻。

我們的系統,對標上面的維度應該下面三項:

系統功能

Component Tree 編輯,核心功能為頁面可視化佈局設計

頁面由組件組成,組件可以支持嵌套,目前組件是通用的組件,後期會支持擴展,組件可以承載業務邏輯。

提供了拖拽佈局支持,支持流式佈局,絕對定位佈局。

面向客群

前端小白,核心訴求是交互性高,所見即所得的編輯方式

目前是組內兼職的同學在用,有一定的前端佈局基礎,理解每個組件的使用方式。

如果想降低對用戶的要求,比如對普通用戶,那麼就要提供模板支持,對普通用戶而言,改改背景圖,換個圖片,編輯下文字就夠用了,越是要降低對用戶的要求,越是要固化一些設計和數據模型。

前端框架組件,依賴工具提供組件,編輯效率高,業務邏輯封裝度高

目前系統的自由度是組件級別,內置了通用的組件,包括:

  • 基礎組件:圖片、文本、表格、模板組件
  • 複雜組件:數據列表、跑馬燈、輪播圖、表格
  • 佈局:錨點佈局、標準佈局、選項卡布局
  • 容器:上下流(塊),左右流(內聯塊),自由容器(絕對定位佈局)

這些組件是內置到系統的,二期的組件市場,目標是組件可擴展,組件可以承載業務,業務邏輯封裝度更高些,方便使用。

技術實現

系統採用技術棧如下:

  • 前端:React + Redux + ImmutableJs + ReactDND + Antd
  • 後端:Node Express + MongoDB + Redis

可視化佈局

首先,需要定義渲染UI的數據結構,通常這種UI的數據都是樹形的結構,可以用一個大的 JSON 來表示,然後遞歸渲染。

類似如下的結構:

基於 React 的可視化編輯平臺實踐

節點使用類似 React 的虛擬 DOM 結構:

  • Type :組件類型
  • Props :組件屬性
  • Children:組件的子節點列表
  • Sort:排序號

由於直接使用樹形的的結構,對節點的增刪改查不友好,所有進行了扁平化處理,將樹拆成了兩個結構:

結構一:

基於 React 的可視化編輯平臺實踐

存儲節點的關係,類似一個數據庫的二維表,描述節點的父子關係,方便修改父子結構,同級排序。

結構二:

基於 React 的可視化編輯平臺實踐

存儲節點的數據,通過 ID 可以獲取節點數據,方便節點數據更新。

其次,定義好數據結構以後,就是渲染頁面了,將上面的兩個數據合併組成樹形結構,然後遞歸遍歷創建組件對象。

創建組件的時候,需要獲取對應的組件類型,比如導航組件,輪播圖組件,所以需要一個組件的類型映射表,根據組件的 Type 獲取對應的類型,創建實例。

還有組件的佈局能力,佈局功能抽到容器裡,所以組件在創建的時候會包裹對應的容器,組件的定位由容器負責,不同的容器提供不同的功能,容器由高階組件提供。

如下圖所示:

基於 React 的可視化編輯平臺實踐

圖中 typeFactory 負責組件的創建,創建組件的同時包裹對應的高階組件,

這裡是組件在編輯狀態的渲染過程,發佈以後,考慮的渲染的性能,預先創建了組件的樹形結構。

最後,實現拖拽佈局,佈局完全是容器來負責,拖拽過程的位置檢測由容器來實現,通過鼠標位置確定組件的安放位置,修改描述組件關係的數據,觸發重新渲染。

流式佈局演示:

基於 React 的可視化編輯平臺實踐

自由佈局演示:

基於 React 的可視化編輯平臺實踐

前面說了組件的佈局,除了佈局,還要對組件的屬性進行編輯,編輯也是通過容器來實現的,通過高階組件來複用。

組件也需要遵守一個規範,方便獲取組件的屬性列表,為組件增加額外的靜態屬性來說明組件的屬性說明。

系統提供了組件屬性編輯器,同時可以支持擴展出其他自定義編輯器。

同構直出

因為定製頁是需要 SEO 的,所以要做服務器端渲染,也就是要做同構直出。

做同構直出需要考慮以下內容:

  • 全局的 Store(Redux)
  • 組件內 CSS 抽取(Glamor)
  • 針對 Node 端單獨構建一個組件庫,忽略組件內 less 的引用
  • 設置 externals 避免包過大
  • 組件內異步獲取的數據,通過為組件加靜態屬性 getInitProps(參考Next框架)

Store 中存儲了組件樹和組件屬性數據,直出的不僅僅是 HTML,還包括對應的 CSS,這裡使用 css in js 方案 Glamor,渲染 HTML 的同時,也可以提取對應的 CSS。

下面是同構直出的大致流程:

基於 React 的可視化編輯平臺實踐

同構直出的渲染結果:

基於 React 的可視化編輯平臺實踐

為了減小首次渲染頁面的體積,並沒有把狀態數據內嵌到頁面裡,而是提供了一個狀態的的請求鏈接,異步加載狀態數據。

一階段完成以後,開始上線運行支持業務,目前已經支持 100+ 的定製頁項目,通過在線編輯、修改、發佈,節約了大部分編碼、構建、發佈的時間,開發效率大幅提升。

組件可擴展

由於一階段是內置的組件庫,包括通用組件以及定製頁業務相關的組件,二階段希望能實現組件可擴展,提升平臺的應用範圍,實現頁面級的組件,增強易用性。

組件市場

組件市場是一個組件的集合,提供可選的組件,組件的粒度可以開發者控制,可以是組件級,也可以是頁面級,可以內嵌業務,或者是通用的組件。

組件開發CLI工具

提供組件開發腳手架,本地開發、調試環境,可以發佈組件到組件市場。

組件動態加載

為了動態加載組件,我們開發了模塊加載器 BondJs,可以動態加載頁面依賴的所有組件,將組件註冊到系統裡。

目前組件市場還處於完善階段,計劃年底上線,磨合一段時間,後期希望可以積累更多的模板,接入其他業務,能提升運營類項目的效率。

關於第二階段的後續有機會可以再詳細說明,這裡不展開了。

易用性分析

目前平臺是給內部開發者使用,因為編輯自由度高,需要有一定的前端基礎,系統也提供了模板功能,直接從模板編輯相對易用一些,不過,仍是對頁面內元素的編輯,對運營/產品/企業用戶來說還是有一定的難度。

對普通用戶來說,最容易懂的模型不是頁面的元素,而是業務模型,比如用戶信息、企業信息、職位信息這一類更貼近用戶的模型,所以後期組內同學和後端同學一起開發基於後端模板的解決方案,這個方案的優點是可以利用企業招聘方的數據模型,比如企業介紹、職位列表等數據,再提供多個後端預置模板,企業只需要維護自己的信息,然後選擇一個模板即可,可以滿足對定製頁要求不那麼高的用戶。

靈活性和易用性是需要平衡的,越靈活往往易用性比較差,一般是通過預定義來說提升易用性,細粒度的組件很靈活,但是易用性差,後續可以開發內嵌業務的頁面級組件,來提升易用性。

總結

目前,整個編輯平臺已經支持了 100+ 的項目,針對複雜度不高的項目可以很大提升開發效率,整個項目因為是 Side Project ,一邊支持業務一邊開發,所以花了不少時間,回過頭來看,做這類項目,首先要有明確的目標和受眾,是為開發者賦能,還是服務普通用戶,可視化佈局也不是銀彈,所以要想好真正影響效率的地方。比如有些項目開發快,但是面對用戶的頻繁修改需求,效率也很難提升,反過來要控制用戶的需求變更,如果客戶要求不高,直接給個默認模板就可以,或者提供多樣的選擇,讓用戶選擇相對滿意的模板即可。

後期組件市場上線,希望可以接入不同的業務線,提供更多面向業務的組件或者頁面模板,提升系統的應用廣度,提升運營類項目的開發效率。

原文:https://zhuanlan.zhihu.com/p/94016600


分享到:


相關文章: