頁面搭建工具總結及架構思考

在初步完成了在線流程圖編輯工具以後,又接到了在線搭建頁面工具的需求,剛開始其實並不想接項目,由於從歷史以及現實緣由來看,個性化及動態渲染都是很難解決的痛點,各類H5頁面搭建工具的不溫不火早已說明了這條路並無這麼好走,但從另外一個方面來講,既然有了這樣的需求,那也就說明了現實的工做流程確實存在問題,本着解決問題的心態,說不定能夠從工具及產生的新式組件部分從新梳理底層開發規範,從而側面加強我司前端部門的重要程度.人總要有夢想是吧...css

簡介

項目第一版部分UI 組件使用了ant design加快進度.到目前爲止基本解決內部建立頁面模板,併發布到用戶服務器的流程.html

目標

經過托拉拽方式快速生成頁面模板,進行預覽及發佈.前端

使用人羣分析

普通用戶須要所見即碎得的編輯方式,經過簡單,學習成本低的操做,好比拖拽頁面元素的方式來達到快速生成頁面的效果.固然,當頁面元素過多時,實際上拖拽的方式,就不如樹形結構容易定位和編輯(可參考ps等軟件).node

而對於運營人員甚至是原模板製做人員來講,除了但願經過操做已有組件進行頁面排版以外,還但願能夠經過屬性配置及方法修改來完成獨立業務場景的活動頁面.react

對於中後臺系統開發人員來講,大量的表單頁面以及更加複雜的業務流程流轉,不只須要頁面搭建工具,甚至作在線的IDE都不爲過,固然現階段版本暫時不須要這種複雜場景.但在考慮總體架構時,仍然須要針對這一狀況進行分析.git

爲何使用可視化搭建工具,而不是自研UI框架?

一方面工具可以提升內部開發效率,更快完成修改及簡單製做需求,而自研UI框架的難點在於如何持續投入,對於中小企業而言,盈利纔是最終目標,就是對於模板開發人員來講,一個擁有衆多樣例及解決方案的開源庫,在實際工做中也能節省大量的時間.以前內部失敗的幾個前端UI組件庫已經說明了這一點,開發成本,實際用例,問題解決,相關文檔都會帶來各類各樣的問題.github

另外一方面,業務的大量擴張,各個業務線所要求的人力成本愈來愈高,逐漸走向惡性循環.從用戶角度來講,愈來愈長的交付時間帶來的是體驗與質量的大幅降低,阻礙了進一步的發展.redux

結合實際狀況

此次的重點其實在於如何提升初級前端開發者的開發效率以及解決運營人員的上線後可維護的問題.那麼,從產品形態來講,能夠參考Dreamweaver的部分界面,好比設計視圖與預覽視圖.這樣可減小我司大部分模板開發人員的學習成本. 另外,經過提供部分開放的代碼編輯能力,來解決特殊的個性化需求. 這麼看來,我一開始想的使用現有前端框架進行改造升級以及推進新的組件開發規範根本不現實. 所以,決定工具自己使用react進行實現,組件部分結合已有的後臺模板字符串方式,劃分好樣式及腳本命名空間,按需加載便可.前端工程化

功能實現

按照上述梳理,得出工具核心功能在於編輯狀態下的拖拽佈局與組件屬性編輯以及預覽模式下的解析展現部分.再按照實際狀況定義新的組件開發規範,並準備好組件管理系統,就能完成第一版目標. 這裏的組件仍然採用原始的HTML+js+css的開發方式,所不一樣則是組件包會通過後臺轉義以及前臺解析按照規則書寫的模板字符串,並輸出到頁面中進行展現.前端框架

數據結構

在以前的項目中,到後期才發現由於自實現的狀態管理工具過於簡單且缺少文檔,致使後期接手維護人員的難以修改.正好藉着項目的機會,使用與react搭配較好的 redux進行開發. 上個項目採用的扁平化狀態樹結構在一開始只是爲了查找方便,在學習了redux以後,發現範式化的state更加符合複雜的場景,特別是在排序以及關聯查詢方面.

項目中須要實現組件節點樹

及與節點相關聯的對應窗口標題的數據

設計視圖

雖然已好久不用Dreamweaver,但確實不得不認可其所見即所得製做頁面效果在之前仍是很讓人驚豔的.

而本項目中就功能程度而言確定是遠遠不及的,以H5製做工具,或者各類原型工具來講(最近在用 xiaopiu.com,表單項設計很出彩),都是採用類ps的畫布方式.

而在本項目中,由於須要考慮運營人員的使用場景,採用全畫布形式最麻煩的地方在於以製做設計圖的思惟在製做網頁,這樣會帶來製做步驟複雜,且層級較多,頁面節點一多各類互相遮蓋難以維護.這只是操做上帶來的問題,更麻煩的地方在於難以造成規範,這裏的規範是製做頁面的規範,若是隻注重定位而不注重文檔流天然佈局,則會在區塊劃分上定義模糊不清,對於現今大多數動態獲取數據模板來講,也根本沒辦法定死位置. 那麼,只要搞定設計視圖中最麻煩的節點拖拽排序功能,就能完成最基礎的設計視圖功能.

拖拽功能

這裏使用了react-dnd,API定義及數據處理與DOM分離的方式確實讓我大開眼界,內部已使用redux的架構進行設計,核心部分都是純函數,將DOM操做分離出去,也所以更容易進行擴展,後續會專門整理源碼閱讀筆記,以供參考.

須要支持平級排序與嵌套排序,包括浮動定位.

在使用Dnd的過程當中,須要給視圖中可排序以及可嵌套放置的節點都設置類型,相似於惟一標識符,當綁定的DOM節點觸發事件以後,會經過以前已包裹完成的高級組件進行傳遞狀態,從而觸發自定義的事件.

通過幾回的修改,最終肯定了定義可嵌套的佈局容器以及沒法再次嵌套只能排序的展現模塊

比較麻煩的處理在於限制拖拽即時排序方法,當有嵌套層級時,過於靈活的直接插入在用於深層級嵌套時反而讓使用者無所適從,好比想要作一個第二層級排序操做,但因爲使用了即時排序,若是還有內嵌層級,當移動進入時會進行插入操做.固然這一點自己也是由於思慮不周,認爲只要鼠標通過容器之上,既然沒法判斷用戶是否須要插入嵌套層級,那麼直接作插入處理,但真實對接業務場景卻發現有些容器內部由於自身內容過長,致使容易誤操做,以後約束了hover事件,採用drop事件用於判斷真實嵌套意圖或排序.

對於嵌套容器而言,排序時須要根據當前拖動節點與鼠標通過節點的實際通過位置以及以前的排序方式做判斷,好比當通過可排序節點50%高度則自動作排序,對於可嵌套放置節點,須要記錄移出時方位,當通過該節點以後,再作相應排序規則.

同時,須要定義一個畫布級容器用於知足浮動定位需求,當展現型模塊進行拖拽操做時,可放置在該容器中用於解決浮動定位排版需求.

部分交互操做

還有一個麻煩之處在於設計視圖中須要可以支持外部樣式表以及外部腳本,那麼爲了避免與工具自己產生衝突,甚至影響到工具操做,這裏的設計視圖中採用iframe做爲展現層.參考react-frame-component,新建一個空白的iframe,在建立完成時手動重寫document,前期直接使用ReactDOM.unstable_renderSubtreeIntoContainer進行跨節點組件更新,在以後由於屢次重複渲染的問題改爲爲ReactDOM.createPortal.

設計視圖採用iframe來實現的問題,還在於須要根據上下文進行重構組件,其中畫布類容器中的拖拽放大縮小及框選對齊及同時編輯都須要根據iframe 的document從新計算.這裏採用以前項目的邏輯,用react的方式進行組件重構便可.

屬性編輯

依託於強大的狀態管理工具,咱們將表單項與節點數據進行雙向綁定便可達到屬性編輯的效果,那麼這裏只剩下對於展現型模塊的屬性聲明.

不是IDE

其實工具自己起到的做用只是將代碼以更加通用的方式進行組合,在大部分實施及運營人員沒有辦法很快速的掌握組件化開發的狀況下,也須要經過工程化的手段進行推進.至少經過工具及推出的新式組件開發規範,可以將之間那種低效的人工方式進行優化升級,包括也可以有必定的積累.更別說分離的模式更有利於自動化測試.

從新定義XML文件,用於支持展現型模塊的配置需求,這也算是一種聲明,效果以下:

同一類型模塊能夠有多個展現(HTMl結構及獨立功能),通用性配置項寫在模塊主XML中,展現包具體內容結構以下:

css部分會在上傳至應用中心以後進行編譯,類css module方案增長標識符,局部實例採用模板引擎組合的方式,生成不重複的root className 進行包裝.

主體結構部分採用html模板字符串方式,定義key-value形式的數據源,在設計視圖中根據用戶操做表單項進行數據修改,達到實時編輯效果.在內部使用時還需開放局部的源碼編輯效果以知足快速修改上線.

而工具內部對應進行節點數據存儲,最終拼裝完成一個模板頁面所需的組件節點樹.這裏實際上將工具自身實現進行了隱藏,普通模板開發人員或許並不瞭解其內部組件的實現,但能夠按照以前的經驗進行模板片斷的編寫,惟一區別則是須要增長模板字符串的認知及編寫.做爲過渡方案來講,至少解決了現實成本問題.

表單項擴展

表單項描述中增長級聯標識符asFor與asForValue,由工具進行判斷是否顯示當前表單項,同時增長分類標識符classify,用於將過多的表單項進行組合分類展現.對與展現模塊開發者來講,只須要聲明type便可調用.後續經過擴展提供更多類型

解析翻譯

在經過拖拽及配置的方式完成設計視圖以後,只要再解析翻譯爲預覽展現所需的各終端真實內容便可.這裏只需翻譯爲HTML字符串便可.

終點or起點

初始的需求到這裏基本已完結,除了業務需求以外,我其實仍想探索出如何結合現實狀況推進團隊的前端工程化發展,若是按照前端工程——基礎篇的階段總結,那麼咱們甚至還在第一階段掙扎前行.

而在基本完成上述工具以後,我不禁的思考,若是以工具做爲起點,潛移默化的將高級能力植入到線上項目中去,應當比硬推框架效果更好,同時也可以進行積累.好比此次的頁面模板,在之前甚至連最基礎的資源壓縮都沒有作到,而經過新的工具統一進行壓縮,既沒有增長開發人員的工做量,又達到了效果.經過快捷工具的方式既減輕了使用者的開發壓力,又加強了線上項目的實際質量,何樂而不爲?更別說工具自己以及所產生的衍生物的價值.

架構思考

作組合

每一個可以延伸下去的業務場景其實都很複雜,若是真按照以前的模式給每個場景單獨開發工具,那麼項目週期就太長了.特別是一旦工具內部作交互性功能,好比建站工具中嵌入問卷,或者數據大屏中加入流程流轉,不統籌兼顧根本玩不轉.

爲何須要作組合?一部分緣由固然是爲了節省開發人力,另一部分則是這些場景都有必定的共性:建站中的展現型模塊,自定義表單中的表單項,甚至是數據圖表以及流程節點,都能變成數據節點進行組裝.

每一種工具最終的產物其實都只是代碼的組合,所不一樣的是以前靠人編輯,如今用工具生成.只考慮通用的業務場景,再將其進行概括,實際上已經解決了大部分的線上開發效率問題.

經過分析能夠看到:這些場景都須要一個可以進行托拉拽操做的畫布,一個畫布構成的最小單元(如下稱爲節點)來進行排版,一套直觀的邏輯輔助編輯工具(這裏採用流程圖)控制事件,一個可真實渲染的設計視圖(編輯狀態,生成運行時所需的store),以及對應終端平臺的翻譯器(預覽狀態,解析以前生成的store並按規則進行渲染)就能作到組合.

nodeTree

控制整個應用渲染的頁面結構的數據.定義規範基礎結構:

對節點樹操做的行爲由框架直接提供,對拖拽行爲進行封裝,並提供回調便可.

對於各個場景下所需的展現型模塊來講,只須要遵循統一規範,由框架進行抽象便可

節點註冊

目前看來仍然採用以前的XMl文件定義便可,對於額外的數據信息,好比問卷系統中須要的事件或流程圖須要的連線等都經過關聯表的形式,進行數據擴展.

事件

一部分由全局定義公共事件,好比頁面初始化以及節點銷燬,關聯狀態重置.另外一部分由模塊單獨聲明,好比問卷中表單項條件跳轉,在模塊中聲明onChange事件,由用戶經過流程圖工具綁定對應節點.這裏的觸發效果應當由公共事件與模塊修改自身屬性事件共同擴展.固然,這裏不須要作到自定義的程度,只要根據預先設置的規則進行處理便可.

能力擴展

這裏的能力擴展是爲了分離核心功能,當工具須要好比組件樹展現,格式刷等額外功能時,經過相似中間件形式增長工具能力,插件可以使用內部數據流進行功能擴展

同時在框架中提供預留UI渲染節點:

<div id="toolbar" /> <!-- 工具欄節點注入 -->
<div id="artboard" /> <!-- 畫布頁面注入,注意不能遮擋組件節點,按照規範定義層級 -->
<div id="sidebar" /> <!-- 側邊欄節點注入 -->

節點能力定義

全部節點皆採用鼠標移動至上方,顯示可拖動區域及快捷菜單的方式

總結

在這一過程當中,既有產物,又能從新梳理組件開發規範,作到由上到下統一整合,避免以前的那種割裂式開發流程,這樣即便前端框架或引用的庫發生了變換,只要根據規範進行聲明便可,在作到這一步的基礎上,再談其它,我想應該就會容易不少.

工具自己也是爲了解放前端工程師,畢竟日復一日的業務代碼的堆積很容易消耗工做的積極性,沒有人天生想一直成爲資源池的一部分.經過創建新的基礎研發體系,讓工程師站在不一樣的角度看待問題,即便是無聊的業務代碼,通過包裝,從新聲明,附加配置項等步驟以後,也會發現哪裏能夠複用,哪裏寫的有問題等以前忽略的信息.我以爲這才最有價值的地方

原文出處:https://www.cnblogs.com/leomYili/p/10176228.html

相關文章
相關標籤/搜索