(開源) 低代碼H5可視化搭建系統(tǒng) – 易動v3.0(動易cms還能用么)
前言
作者在2020年的時候開源了易動第一個版本(開源)從0打造h5可視化搭建系統(tǒng) – 易動(vue ts egg),這兩年在公司針對裝修技術(shù)方案做了大量的實踐,使用過draggable方案 iframe裝修方案 絕對定位方案,對其在技術(shù),產(chǎn)品層面都存在更深入的理解,今天給大家?guī)硇乱淮髽I(yè)級H5裝修方案易動v3.0
開源地址
拖拽生成h5頁面,支持頁面全局設(shè)置,組件,自定義URL,插件市場,公共npm組件庫
基于最新vue技術(shù)棧, 易動v3.0 已上線,歡迎體驗~~
YD 管理端
YD_Client 客戶端
開源不易,給個Star吧~
技術(shù)棧
管理端:vue3 vite pinia vueuse TypeScript
客戶端:vue3 vite TypeScript
集成組件庫(ydh5-UI):基于Vue3 TypeScript進行開發(fā)
服務(wù)端:serverLess
項目架構(gòu)
在正文開始之前先為大家介紹一下項目架構(gòu),我們從底層到上層依次介紹
易動3使用騰訊云serverless作為后端服務(wù),serverless在易動系統(tǒng)中提供組件schema的數(shù)據(jù)存儲服務(wù),為什么使用serverless下文在說明。
易動3將客戶端、管理端的公共裝修組件進行了統(tǒng)一封裝發(fā)布成為npm包,解決了以往存在的一個組件需要寫、改兩遍代碼的核心問題。
易動管理端是項目的最核心系統(tǒng),除了核心的保存,修改之外,以及一系列提供裝修效率的功能,例如組件市場、輔助線、復(fù)制、粘貼、撤銷、放撤銷,這個低代碼裝修系統(tǒng)的上限于下限皆由此項目決定。
易動客戶端功能比較單純,主要是根據(jù)約定好的js schema結(jié)合集成組件庫進行數(shù)據(jù)渲染于邏輯觸發(fā)。
使用方向
這幾年關(guān)于低代碼領(lǐng)域開始不斷有大廠入場,這也變相的說明了該領(lǐng)域巨大的提效需求,愿望是美好的,但是現(xiàn)實是骨感的,低代碼無法做到全盤通吃,只能聚焦某個領(lǐng)域,易動v3.0也是這樣的,他無法處理存在大量邏輯的頁面,所以易動v3.0選擇專注于營銷單頁,在營銷單頁領(lǐng)域他可以發(fā)揮自己的優(yōu)勢。
除了基礎(chǔ)的按鈕、圖片組件外,業(yè)務(wù)組件可以做很多場景化組件,例如banner,商品專區(qū),甚至從接口獲取數(shù)據(jù)的組件都可以通過js Schema的約定進行實現(xiàn)
而營銷單頁的需求絡(luò)繹不絕,這樣的工作就像在工廠“打螺絲”,大部分前端開發(fā)者并不愿意做這件事情,并且工作流程比較繁瑣,可能因為業(yè)務(wù)原因頻繁改動,大致工作流程如下
一個再簡單的單頁都需要走一樣的固定流程,并且一旦某個環(huán)節(jié)出現(xiàn)了問題就需要回滾好幾步,在這兒個過程中開發(fā)者也需要跟著回滾,遍出現(xiàn)了頻繁改樣式,重復(fù)機械行為。
如果有了低代碼平臺 流程可以變成這樣
這樣的架構(gòu)中權(quán)責變的更加清晰,開發(fā)者從“螺絲釘”變成了技術(shù)解決方案開發(fā)者
而業(yè)務(wù)的決定權(quán)也掌握在專人手中;大家各司其職,技術(shù)根據(jù)實際需求不斷優(yōu)化技術(shù)解決方案,運營使用低代碼平臺的搭建能力 物料能力也能提高運營的效率。
H5裝修常見方案
據(jù)作者了解,目前市面上所有的低代碼平臺幾乎都是基于Schema進行實現(xiàn)的,這種方案的核心原理比較簡單
基于這樣的Schema結(jié)構(gòu),便衍生出來了多種實現(xiàn)方案,在這里簡單描述一下我在實際工作中都使用過方案以及他們的優(yōu)缺點;
絕對定位方案
簡介:所有的裝修組件都是再后臺直接拖拽放置,沒有組件群組的概念,可以任意放置你的組件到任何地方。
優(yōu)點:靈活
缺點:無法流式布局,需要維護公共組件庫,操作門檻較高,需要通過技術(shù)能力填補,例如吸附輔助線。
流式布局方案
簡介:裝修組件遵循流式布局,從上到下從左到右進行排序,就像搭積木一件,這種方案僅限移動端
優(yōu)點:操作簡單
缺點:組件不夠靈活,因為只能上下移動,想做到非常規(guī)布局比較麻煩,需要維護公共組件庫
iframe方案
簡介:將客戶端通過iframe內(nèi)嵌到裝修管理端中,再通過postMessage進行項目間通信,客戶端識別環(huán)境開啟裝修模式與后臺進行實時通信
優(yōu)點:不需要維護公共組件庫 ,只需要維護客戶端代碼
缺點:客戶端與管理端代碼耦合嚴重 裝修操作部分代碼需要寫在客戶端中
流式布局 絕對定位方案
簡介:為絕對定位組件增加一個流式布局的父級容器,讓裝修數(shù)據(jù)具備二級結(jié)構(gòu),
優(yōu)點:靈活 具備可生成代碼的規(guī)范結(jié)構(gòu)
缺點:操作麻煩,存在一定學(xué)習(xí)成本 ,需要維護公共組件庫,相對其他方案多了一層結(jié)構(gòu),難度相對更加大
易動3選擇的方案
在公司生產(chǎn)環(huán)境項目中,憑借易動v1.0的經(jīng)驗,我使用了流式布局方案,最初效果還是非常不錯的,那時候沒想到將公共組件發(fā)布到npm,兩端項目公用組件的方案,后期組件改動頻繁,出現(xiàn)了極大的維護問題,這迫使我尋找其他出路。
為了解決流式布局中一套組件,兩套代碼問題,在生產(chǎn)環(huán)境項目中實驗性的使用管理端 客戶端耦合的iframe方案,滿足了公司的需求只需要維護一套代碼,并且可以將Schema抽象出來應(yīng)用到單頁中,實現(xiàn)活動頁裝修,iframe裝修方案在公司也是沿用至今,幫助公司搭建了200 的頁面。
再后來,我準備重啟易動項目,開發(fā)易動v2.0,我們在易動v2.0中實驗性的嘗試了流式布局 絕對定位方案,在開發(fā)之前普遍覺得這是一個天才的主意,同時具備流式布局與絕對定位方案的優(yōu)點,而且易動v2.0開發(fā)技術(shù)中還存在類似易企秀的多頁的需求,大概經(jīng)過2個月的代碼編寫,最終發(fā)現(xiàn)還是我們的想法過于理想化,首先操作上就存在比較高的門檻,技術(shù)難度也很大,而且因為Schema結(jié)構(gòu)復(fù)雜,后期代碼難度也是幾何級別的提升,最終我們PASS了這個方案。
在后面一段時間我一直在思考一個問題,也就是低代碼的邊界性,他應(yīng)該做什么,他可以做什么,我們?nèi)绾瓮ㄟ^低代碼來創(chuàng)造產(chǎn)品價值,在不斷的思考中我也逐漸明確了開發(fā)方向,不再去想他還能做什么,而是在開發(fā)之前就確定一個目標,易動3.0將會在營銷領(lǐng)域發(fā)揮它的作用,所有的功能都圍繞這個核心目標
基于這樣的目標,易動v3.0再出發(fā),依舊采用絕對定位方案,因為絕對定位方案符合需求,難度最小,具備拓展性,后期維護性更強。
方案確定好了,接下來將會介紹一些核心的實現(xiàn)思路。
核心實現(xiàn)思路
Schema的編寫
schema的結(jié)構(gòu)將會決定你的裝修系統(tǒng)的上限,一個良好的設(shè)計結(jié)構(gòu)將會為后面的開發(fā)降低很大的難度,我們需要定義好頁面的結(jié)構(gòu)與組件的結(jié)構(gòu)。
而在代碼中增加組件,或者增加組件類的數(shù)據(jù),例如在輪播圖組件中增加一項輪播圖,都需要通過函數(shù)return的方式進行對象創(chuàng)建,以免出現(xiàn)多個組件使用的數(shù)據(jù)為一個數(shù)據(jù)源。
在項目中增加一個組件,只需要將組件Schema push到模板變量中即可
代碼位置:https://github.com/vkcyan/YD/blob/main/src/modules/component/index.ts
/** * 組件信息列表 * @param name 組件名稱 * @param tempLen 本次層級 * @returns */function baseComList(name: string, tempLen) { const list: baseComponent[] = [ { id: guid(), name: 'y-img', showTitle: `圖片${tempLen}`, // 顯示組件名稱 show: true, cssModule: { ...absolute(tempLen), ...borderData(), ...compSize(100, 60), 'background-color': '#ffffff00', }, // 樣式 staticData: { imglUrl:'xxxx.png', ...linkData(), }, // 行為 function: {}, // 方法 animation: [], // 動畫 }, // ..... ] return list.find((e) => e.name == name)}
例如增加一個圖片組件,我們只需要將參數(shù)'y-img',傳入函數(shù),即可得到一個圖片組件的Schema,這樣我們便具備搭建頁面Schema樹的能力。
實現(xiàn)拖拽
實現(xiàn)良好的拖拽是一件非常有難度的事情,它不僅僅是簡單元素的移動,而是通過技術(shù)的手段降低裝修的操作門檻。
元素位移
在易動v3.0中,棄用了以往采用的監(jiān)聽鼠標單次移動距離實現(xiàn)方案,因為這會導(dǎo)致快速移動后出現(xiàn)坐標不準確的情況,改成獲取相對父級絕對坐標。
全局鼠標監(jiān)聽使用vueuse的useMouseInElementAPI,幫助我們獲取每次的相對位置,鼠標按下同時保存元素下標,再通過watchEffect全局監(jiān)聽useMouseInElement的變化,拿著鼠標按下階段保存的下標去尋找需要位移的元素,不斷更新其Schema中的cssModule字段中的top與left值,進而實現(xiàn)元素移動。
元素縮放
我們?yōu)樵卦黾?上 下 左 右 左上 左下 右上 右下,八個操作點,是元素支持任意縮放功能,再點擊任意縮放點的時候,我們都會保存一個標識,來確定當前點擊的點是什么,然后在 全局監(jiān)聽鼠標移動的watchEffect中執(zhí)行對應(yīng)縮放邏輯,來不斷更新選中的元素的 top left width height的組合值,進而實現(xiàn)元素縮放功能。
元素多選
支持元素位移與縮放其實已經(jīng)完成了裝修的最核心功能,已經(jīng)可以完成簡單的頁面搭建了,但是僅憑位移與縮放操作起來不方便,這時候就需要開發(fā)多選功能,我們把之前保存的單個選中下標改成一個選中數(shù)組。
這里說明一下為什么保存數(shù)組下標,而不是組件的唯一id,這是一個時間復(fù)雜度的問題,如果保存組件唯一id,更新組件數(shù)據(jù)就需要通過循環(huán)再找到下標,進而通過下標更新數(shù)據(jù),這時候時間復(fù)雜度為On,而直接保存數(shù)組下標,在通過下標直接更新數(shù)據(jù),時間復(fù)雜度為O1。
回到正題,我們開發(fā)一個選中框組件,在拖動選中框的時候判斷是否包含了組件,不斷更新當前選中框多選的元素,進而實現(xiàn)多選刪除,多選拖動,等等多選功能。
目前多選框計算邏輯還比較單一,僅支持從左上向右下拖動,后續(xù)有時間會繼續(xù)完善。
輔助線
輔助線是低代碼系統(tǒng)必備功能,這將會極大的降低使用門檻,實現(xiàn)輔助線相對來說也是非常復(fù)雜的,假如頁面有4個組件,我們點擊了任意一個的時候,就需要去保存其他3個組件的 top top height/2 top height left left width/2 left width,并且將其數(shù)組保存成為字典結(jié)構(gòu),也就是ES6的Set,相對數(shù)組實現(xiàn)可以將時間復(fù)雜度從On2降低到On,有效避免了卡頓的情況,在被選中元素不斷拖動的時候,我們會不斷對比當前變化坐標與之前保存的3個組件的坐標,一旦對比到了一致,就會將其值push到存儲變量,并在頁面上顯示,表明已經(jīng)對齊。
輔助線吸附
先聲明一下,輔助線吸附作者的實現(xiàn)還存在瑕疵,目前還在尋找更好的方案,也希望有大佬可以指點一二,目前吸附還存在一點操作上的不流暢情況,所以這部分我便不多贅述。找到最佳解決方案再更新。
時間旅行
pinia的subscribes存在差異,并且events在生產(chǎn)環(huán)境無法獲取,導(dǎo)致現(xiàn)在線上無法相關(guān)使用
所謂時間旅行就是可以進行撤銷 反撤銷操作操作,,具體原理感興趣可以看看vuex版本的實現(xiàn),本質(zhì)原理都是一樣的,基于vuex實現(xiàn) 撤銷 與 反撤銷 的plugins,采用數(shù)組 單指針進行實現(xiàn)。
more
移動端如何讀取schema,使其還原裝修效果;如何實現(xiàn)二次編輯組件的保存到創(chuàng)建市場;還有很多拖拽細節(jié)的實現(xiàn);章節(jié)有限,這里不再一一贅述,有興趣可以加入微信群在一起聊聊。
基礎(chǔ)組件or業(yè)務(wù)組件
基礎(chǔ)組件:按鈕 圖片 輸入框 文字 模塊(html自帶的標簽元素)
業(yè)務(wù)組件:富文本 輪播圖 若干營銷組件(由開發(fā)人員定制化產(chǎn)出的標簽元素)
在早期開發(fā)低代碼,無代碼產(chǎn)品的時候,我將絕對定位方案與基礎(chǔ)組件綁定,業(yè)務(wù)組件與流式布局綁定,隨著對低代碼的深入理解,我在這里必須糾正之前的偏見,正確的觀點應(yīng)該是:基礎(chǔ)組件 絕對定位方案更加和諧、業(yè)務(wù)組件 流式布局方案更加和諧。
隨著將裝修組件發(fā)布成為npm包,他們的隔閡已經(jīng)幾乎不存在,全部視為公共組件,公共npm組件包中將會抹平平臺差異,任何可以描繪的組件可以看作為靜態(tài)結(jié)構(gòu)組件都可以被低/無代碼平臺使用。
關(guān)于低代碼
這幾年關(guān)于低代碼討論也非常多,最近一直看到大廠開源的低代碼工具,例如騰訊的tmagic-editor,阿里的LowCodeEngine,還有5月28號掘金直播低代碼的探索與實踐,其背后是前沿開發(fā)者們對效率的思考,是從局部效率轉(zhuǎn)變到全局效率思想的轉(zhuǎn)變。
在技術(shù)條件有限的情況下,低代碼產(chǎn)品的廣度與深度只能選擇其一,我們自然希望低代碼可以做的事情越多越好,生成頁面,生成代碼,直接編寫事件,支持單頁,支持多頁,支持無限嵌套dom,達到降低門檻,提效降成本的作用,甚至解放勞動力,創(chuàng)造更大的社會價值,但是如果沒有足夠的技術(shù)基礎(chǔ),做的功能越多,就死的越慘。所以如果你也發(fā)現(xiàn)存在類似需求,切勿在產(chǎn)品設(shè)計期間不斷加功能,要專注細分領(lǐng)域,只有這樣,低代碼項目才有發(fā)光發(fā)熱的機會,有了經(jīng)驗之后再決定做什么也不遲。
從發(fā)現(xiàn)需求到明確定位有很長的路要走,低代碼產(chǎn)品從可用到好用還有很長的路要走。
其他問題
為什么易動v3.0選擇絕對定位方案
易動v3.0考慮到營銷頁面的多樣化,他并不是理想化的流式布局,而是多樣化的,甚至你意想不到的UI實現(xiàn)方式,這也是易動v3.0使用絕對定位方案實現(xiàn)的一個重要原因,后續(xù)作者也會不斷加強可用性,進一步降低搭建門檻。貫徹技術(shù)為業(yè)務(wù)服務(wù),而不是業(yè)務(wù)為技術(shù)服務(wù)的理念。
為什么使用serverless
做出這個決定處于兩點考慮
- 大部分公司不會使用node作為服務(wù)端框架,接入會重寫服務(wù)端。
- 本人是前端工程師,node 以及服務(wù)端周邊服務(wù)不算精通,低代碼的項目核心也不在服務(wù)端,serverless滿足了作者的需求,后續(xù)我會提供表結(jié)構(gòu),以及關(guān)聯(lián)關(guān)系。
- 因為騰訊云serverless已經(jīng)開始收費了,后續(xù)可能會換成fastify進行服務(wù)端編寫,主要看作者是否有時間,也非常歡迎有志之士為開源做出貢獻。
關(guān)于PC端
易動3的實現(xiàn)方案是絕對定位方案,這讓實現(xiàn)pc端裝修的可能性,但是個人感覺這部分需求比較小,B端的客戶都是ToC,所以并沒有做相關(guān)功能開發(fā),但是理論上可以實現(xiàn)的。
后續(xù)還會做什么
目前易動v3.0 并不是完整狀態(tài),因為作者比較忙碌,很多功能依舊在開發(fā)中,大家也可以提出需求,如果存在價值,作者會加入后面的工作計劃。
- 數(shù)據(jù)分析能力:頁面的曝光情況是客戶非常關(guān)心的指標,這也是易動v3.0非常關(guān)注的功能
- 模板市場功能:物料市場也是低代碼平臺非常重要的功能,配合組件市場,實現(xiàn)團隊資源最大化利用,降低搭建門檻
- 豐富業(yè)務(wù)組件:根據(jù)客戶需求開發(fā)其滿足業(yè)務(wù)場景的組件,達到一次開發(fā),多次使用的效果
- 增強裝修能力:組件旋轉(zhuǎn),多選組件輔助對齊,搭建頁面快捷操作,進一步降低大家門檻
最后
這個開源項目將會一直做下去,未來可能也會嘗試做收費版本,畢竟為愛發(fā)電還是過于理想化了,如果你也是同道中人或者有這樣的需求,歡迎一起起交流學(xué)習(xí),共同進步~