背景
目前低代碼引擎在設計上是需要在單獨的頁面上使用的,他的擴展功能也都是適用于頁面設計的。
但是大多數的場景中,我們都不是只設計一個頁面,我們還有導航配置、依賴配置、低代碼組件和邏輯編排等等應用級別需要的功能。
甚至我們希望在低代碼搭建的過程中能有 VsCode 般絲滑的體驗。快速切換頁面,快速配置應用能力等等。而不是現在開發一個頁面和一個低代碼組件就需要打開至少三個新的標簽頁。如果開發的頁面和組件更多,需要打開的標簽頁也就越多。
因此,在使用低代碼平臺時,我的瀏覽器常常就成為了這樣的。
而當我們需要在同一個設計器中,使用兩種不同類型的設計方式時,只能通過 彈窗 iframe 的方式,這樣的方式體驗上也很不友好。
因此我們需要提供應用級別的低代碼引擎,用于低代碼平臺者開發出應用級別的低代碼設計器。
應用級能力介紹
我們這里提供的應用級能力是指,在一個設計器中即可完成低代碼頁面、低代碼組件、應用級邏輯、應用級國際化配置等的編輯。甚至對于應用相關的配置也可以通過 Webview 的方式進行編輯,而不需要來回切換瀏覽器頁面才能達到這樣的效果。
為了實現這樣的效果,我們在低代碼引擎原有的基礎上新增了以下能力:
- 新增 workspace 模式,新增資源、視圖的概念
- 新增應用級擴展區域
- 多層作用域開發模式
新增 workspace 模式
由于應用級別的設計器和頁面級別的設計器在開發時略有不同,所以需要在設計器初始化時進行配置,是否開啟應用級別設計器的模式。
開啟這個模式之后,就需要注冊“資源”和“資源視圖”。
資源
其中,資源是指在應用級別的設計器中,需要一個獨立的設計器環境來進行編輯、修改、查看等操作的一份文件,這份文件可能是某一個頁面的 Schema、可能是某一個低代碼組件的 Schema,也可能是一段 JS 邏輯的代碼。
如圖,我們可以在應用級別的設計器中編輯所有注冊的資源,而不用新開多個瀏覽器窗口。
資源類型
其中每個資源所需的設計器插件、物料、擴展的面板可能都是不一樣的,也就是設計區域是不一樣的。我們根據資源所需的設計器資源將資源分為幾種類型,這里我們稱為資源類型。
如圖,在設計頁面的時候,使用的資源都是一樣的,這里所有頁面的編輯都會使用頁面的資源類型,而邏輯設計區域,可以看到左側和右邊是沒有注冊擴展區域的,這里就需要一個和頁面不一樣的資源類型,也就是邏輯資源類型。
這樣,根據資源和資源類型,我們就可以在一個設計器中編輯和設計不同類型的低代碼相關的資源。
資源視圖
在同一個資源中,可以根據要編輯方式的不同,可能需要使用不同的設計視圖,因此我們還定義了一個資源視圖的概念,可以給同一個資源注冊不同的視圖,通過切換視圖編輯同一個資源的不同的模塊,來提升整體的編輯體驗。
新增應用級擴展區域
為了提供應用級別的設計器,我們新增了一些擴展區域來幫助大家在合適的未來提供應用級別的能力。
如圖,在應用級別模式下,我們分為應用擴展、資源擴展和視圖擴展,其中每種級別擴展又提供了不同的擴展區域:
- 應用擴展:應用級別的擴展只會在最開始的時候初始化一次,不會因為資源/視圖的切換而重新初始化。
- leftArea:這里用于展示應用級別能力的面板,例如:資源管理器,應用配置,分支管理等等。
- topArea:這里主要是用于展示應用級別的信息,例如:應用的名字和圖標、應用的保存和預覽、應用的國際化配置等等。
- subTopArea:這是和 topArea 類似的區域,這里主要是用于展示應用編輯時的輔助信息,也就是我們的資源切換的標簽欄等等。
- 資源擴展:資源級別的擴展,會在新開資源的時候隨著資源的初始化一起初始化,相當于每一個資源都會對應一個資源級別的擴展區域,但是在資源視圖切換的時候不會產生變化。
- topArea:這里是資源級別的頂部擴展區域,可以展示一些資源相關的信息。
- 視圖擴展:視圖擴展在每個視圖初始化的時候,都會初始化自己的擴展區域。
- leftArea:視圖的左側擴展區域,一般會展示大綱樹、組件列表等等視圖所需的面板,默認會注冊大綱樹的面板。
- topArea:視圖的頂部擴展區域,可以用戶展示對應視圖特有的能力。
- mainArea:視圖的編輯區域
- rightArea:視圖的右側擴展區域,主要是提供設計過程中的組件配置能力。
大家可能會擔心了,有那么多擴展區域,設計器的畫布豈不會很小。為了解決這個問題,其中大部分擴展區域在沒有注冊的情況下,是不會展示的,也就是低代碼平臺的開發者可以自行選擇適合自己平臺的擴展區域,而不是使用所有的擴展區域。
多層作用域開發模式
上面提到的應用級別的擴展區域,分為了應用層、資源層、視圖層。我們在 API 的設計和使用上不能再延續之前的開發模式了。
在之前的開發模式下,我們常常會使用如下的代碼來注冊面板,但是這樣的代碼沒有辦法區分我們的面板是注冊在哪一層的。因此我們需要在原來插件的開發模式下,根據插件注冊的位置不同,將作用域分為幾層。
import { skeleton } from "@alilc/lowcode-engine";// 注冊 logo 面板skeleton.add({ area: "topArea", type: "Widget", name: "logo", content: Logo, // Widget 組件實例 contentProps: { // Widget 插件 props logo: "https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png", href: "/", }, props: { align: "left", width: 100, },});
因此我們需要在插件的作用域中獲取 skeleton 來進行面板的注冊,而不是從全局,也就是從 @alilc/lowcode-engine 中獲取 skeleton API。
import { IPublicModelPluginContext } from '@alilc/lowcode-types';function pluginDemo(ctx: IPublicModelPluginContext) { const { skeleton, } = ctx; return { init() { skeleton.add({ area: 'topArea', type: 'Widget', name: 'pluginDemo', props: { align: 'left', width: 800, }, index: -1, content: Content, contentProps: { ctx, }, }); } }}pluginDemo.pluginName = 'pluginDemo';
這樣,我們在不同的層級進行插件注冊,就可以使用不同層級的 skeleton 來注冊對應的擴展區域了。
應用層
import { init, workspace } from '@alilc/lowcode-engine';(async function main() { workspace.registerResourceType(pageResourceType); await workspace.plugins.register(pluginDemo) init(undefined, { enableWorkspaceMode: true, })})()
如圖,在 workspace.plugins 下注冊的插件,插件下獲取的 skeleton 就是應用級別的 skeleton。
資源層
import { IPublicModelPluginContext } from '@alilc/lowcode-types';function pageResourceType(ctx: IPublicModelPluginContext) { return { category: '頁面', defaultViewType: 'page', defaultTitle: window.pageConfig.title, editorViews: [pageView], icon: PageIcon, async init() { await ctx.plugins.register(pluginDemo) }, }}pageResourceType.resourceName = 'page';pageResourceType.resourceType = 'editor';export default pageResourceType;
這樣我們 plugin 里面的 ctx.skeleton 獲取到的就是資源層的 skeleton,可以向資源層注冊擴展了。
視圖層
import { IPublicModelPluginContext } from '@alilc/lowcode-types';export const pageView = (ctx: IPublicModelPluginContext, options: any) => { return { async init() { // 注冊插件 await ctx.plugins.register(pluginDemo) }, };};pageView.viewName = 'page';
這樣我們 plugin 里面的 ctx.skeleton 獲取到的就是視圖層的 skeleton,可以向視圖層注冊擴展了。
此外,視圖層內的 ctx 還可以獲取到其他的 API,來進行視圖層設計器區域的擴展,包括:material、project、simulatorHost、hotkey、setters、canvas 等等。
如何升級應用級設計器
開啟低代碼引擎的應用模式
import { init, workspace } from '@alilc/lowcode-engine';(async function main() { // ... init(undefined, { enableWorkspaceMode: true, })})()
注冊應用的資源類型和視圖
開發頁面視圖
import { IPublicModelPluginContext } from '@alilc/lowcode-types';export const pageView = (ctx: IPublicModelPluginContext, options: any) => { return { async init() { // 注冊插件 }, };};pageView.viewName = 'page';
開發頁面資源類型
import { IPublicModelPluginContext } from '@alilc/lowcode-types';function pageResourceType(ctx: IPublicModelPluginContext) { return { category: '頁面', defaultViewType: 'page', defaultTitle: window.pageConfig.title, editorViews: [pageView], icon: PageIcon, async init() { await ctx.plugins.register(pluginDemo) }, }}pageResourceType.resourceName = 'page';pageResourceType.resourceType = 'editor';export default pageResourceType;
注冊頁面資源類型
import { init, workspace } from '@alilc/lowcode-engine';(async function main() { workspace.registerResourceType(pageResourceType); init(undefined, { enableWorkspaceMode: true, })})()
注意事項
正如上面介紹的,我們需要通過插件的 ctx 作用域來獲取 API,而不是通過全局作用域來獲取 API,否則在多視圖/多資源的情況下,作用域可能會混亂,導致 API 在非預期的視圖下使用,出現問題。
示例:在下面的 Plugin 中,使用的是全局的 skeleton API,假設 pluginDemo 在 A 視圖中注入的,這也有可能會調用到 B 視圖的 skeleton API,導致我們的面板注冊到非預期的視圖中。
import { skeleton } from '@alilc/lowcode-engine';import { IPublicModelPluginContext } from '@alilc/lowcode-types';function pluginDemo(ctx: IPublicModelPluginContext) { return { init() { setTimeout(() => { skeleton.add({ area: 'topArea', type: 'Widget', name: 'pluginDemo', props: { align: 'left', width: 800, }, index: -1, content: Content, contentProps: { ctx, }, }); }, 2000) } }}pluginDemo.pluginName = 'pluginDemo';
未來規劃
應用級別的低代碼平臺落地
接下來我們會在集團內使用應用級別的能力,升級已有的低代碼平臺,將其升級成應用級別的設計器,不斷打磨我們的低代碼平臺和低代碼引擎的應用級別的能力,當然落地之后也會對外分享我們的經驗和教訓。
提供應用級的精品插件
我們也會開發更多的應用級別的精品插件,幫助大家使用到應用級別的設計器能力。
應用級別的設計器性能優化
應用級別的設計器會擁有更多的資源類型,更多的插件,也可以同時編輯多個設計區域,后續對于性能的損耗肯定不低,我們在實踐的同時也需要不斷打磨設計器的性能。
作者:劉菊萍(絮黎)
來源:微信公眾號:阿里巴巴終端技術
出處:https://mp.weixin.qq.com/s/dwi40gJjGBHW9MVpag5Oxg
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。