当前位置: 首页 > 科技观察

低代码平台组件间通信方案回顾

时间:2023-03-12 22:36:32 科技观察

背景介绍我在3年前开发了一个零代码搭建平台H5-Dooring。主要目的是为了用更低的成本和更快的效率来推出网页(其实我不想写重复的代码,很无聊)还好,经过3年的折腾,现在可以满足基本页面了设计和构建能力强,并能快速推出页面。之前在社区分享过很多低代码和零代码的技术实现,接下来会继续和大家分享一下低代码平台中组件间的通信方案设计。可视化构建平台的基本能力根据我自己设计可视化构建平台的经验,它需要具备最基本的两个能力:静态页面设计能力(即利用可视化平台创建页面的能力)want)组件交互能力(制作静态页面后,页面元素可以有一定的交互,比如跳转链接,打开弹窗等)以上能力让我们可以通过拖拽的方式来构建页面:虽然这样可以满足很多演示需求,但是还是有局限性。例如,可视化平台的组件无法相互通信。这里为大家提供一个更加灵活独立的可视化平台。一个实际的场景,比如我们要做一个转盘H5页面,它由一个转盘组件和一个按钮组件组成。当点击按钮时,转盘开始移动:这种场景需要转盘组件和按钮组件相互通信,实现交互功能。因此,在可视化构建平台中,如果能够实现组件间的通信,将会覆盖更多的业务场景,从而为个人或企业带来更大的价值。下面我就给大家分享一下低代码平台中组件之间的通信。几种沟通方案,供大家参考。组件间通信的几种实现方案对于组件通信我们可能并不陌生。比如在vue或者React框架中,经常会涉及到父子组件的通信,组件之间的通信。通信常用的解决方案有很多,比如:props/$emit子组件传值给父组件eventBus($emit/$on)vuex/redux$attrs/$listenersprovide/inject当然还有很多方式帮助我们实现传统组件之间的通信,那么我们可以参考类似的方式在低代码组件中实现,但是唯一不同的是,我们需要设计一套规则来保证组件之间的通信能够运行通过用户配置。接下来我们来分析一下低代码组件之间的几种通信方案。1、在设计websocket的组件通信方案之前,我们需要在全局维护一个公共的状态。以H5-Dooring可视化平台为例。我们使用redux来管理公共状态。组件之间通信的本质是触发公共状态的更新:为了保证低代码组件库足够纯净,比如组件中不应该连接redux,所以我们需要将reduxtriggerdispatch放在全局页面中,这里可以使用websocket来触发socket组件中command,页面全局监听并触发dispatch:当然,使用socket方式还是会让低代码的组件库往前走(虽然可以实现更自由的通信场景,比如组件自更新,life循环回调,控制业务hook等),因为我们要为它搭建一个socket服务,需要为它设计一个稳定的通信桥梁,比如socket心跳连接等。2.iframe通信postmessage虽然API如iframe的postmessage也可以实现组件间的通信,但是我们需要设计一个通信机制来保证iframe能够接受组件发送的指令,并将共享状态暴露给outside:从Iframe的通信方式我们可以发现,它不仅可以作为通信的中间桥梁,还有点类似于eventBus的方式。并且还可以实现页面间的通信。比如很多微前端架构的底层支持也是用iframe设计的。但是对于更细粒度的低代码组件,就有点小题大做了。接下来给大家分享一下iframe通信的基本代码实现//父页面和子页面通信//A.html(parent)constmsg={name:"H5-Dooring"}window.onload=()=>{//自动调用必须放在onload中,不能通过事件调用//让frame=document.querySelector("#Bframe").contentWindowletframe=window.frames[0]frame.postMessage(msg,"http://h5.dooring.cn/preview")}//B.htmlwindow.addEventListener("消息",(e)=>{console.log(e.data)控制台le.log(e.origin)console.log(e.source)})//子页面与父页面的通信//A.html(parent)window.addEventListener("message",(e)=>{console.log(e.data)console.log(e.origin)console.log(e.source)})//B.htmlconstmsg={name:"DooringH5"}window.top.postMessage(msg,"http://h5.dooring.cn/preview")3.EventEmittersEventEmitters我认为该方法是最适合低代码组件之间通信的方案,类似于js中的事件监听机制,我们可以绑定dom来监听,将事件暴露给用户,实现手动触发机制。(虽然不一定是用户手动Trigger,但也有逻辑触发的情况,比如当页面的某个组件达到某个状态时,会自动触发一个事件来改变其他组件的状态)EventEmitters类似于一个观察者模式,我们可以使用javascript设计模式来实现它,并在组件内部监听或触发,一个简单的实现如下:interfaceEvents{[key:string]:Function[];}exportclassEventEmitter{publicevents:活动;构造函数(事件?:事件){this.events=events||{};}publicsubscribe(name:string,cb:Function){(this.events[name]||(this.events[name]=[])).push(cb);返回{退订:()this.events[name]&&this.events[name].splice(this.events[name].indexOf(cb)>>>0,1)};}publicemit(name:string,...args:any[]):void{(this.events[name]||[]).forEach(fnfn(...args));}}具体的设计过程有点像我之前设计的iframe通信架构,但是会更容易使用:low上面的代码组件事件队列设计只是实现了组件通信,并没有把通信和实际应用场景结合起来,比如至于低代码用户需要如何操作来实现组件通信。这里我之前也设计了一套模型:每个Components都有一套事件列表。用户可以在一个组件中添加多个交互事件,在第一段代码中通过循环遍历依次触发事件队列:我会继续给大家分享更多H5-Dooring低代码的实践和思考,如果你对低-代码可视化,也可以参考我的低代码可视化专栏。