当前位置: 首页 > Web前端 > HTML

页面构建系统的那些事儿

时间:2023-03-28 16:51:37 HTML

在降本增效的大背景下,LowCode这两年讨论的比较多,社区也涌现出很多不错的方案。对于前端来说,页面构建是LowCode实践的一种具体形式,也是一种行之有效的提高技术和业务效率的手段。从社区的主流做法来看,页面建设只能解决一些纵向的问题,比如电商营销、中后台管理页面等,换句话说,通常适合用页面建设来解决的问题具有以下两个特点:页面比较规范,或者页面布局和业务逻辑比较固定。开发任务相对重复,各方沟通时间长。除了以上两个特点,还有一个共同的特点,就是资源瓶颈问题。人力资源紧缺,短时间内很难招到满意的人。当然,在一些特定的领域,比如电商营销,需求会比较高,开发时间短,上线时间紧。比如一周有好几场活动,时间要求很高,需要马上上线。什么是页面构建系统?简单的说,就是通过可视化和自动化的方式来完成交付页面的生产过程。这种制作过程会屏蔽很多专业领域的知识(比如编码、技术概念等),同时可以极大地复用已有的工作成果,最终达到降本增效的目的。从技术角度来说,页面构建系统就是将HTML、CSS、JS组装成页面。现代前端开发都是开发组件,然后通过框架完成页面渲染。因此,页面构建系统实际上完成了组件到页面的组装。页面构建系统的组件和模板组件是页面构建系统中最小的组件。无论是基于React还是Vue开发,还是基于WebComponent开发,组件都需要对外提供一定的接口,以便于外界使用组件。这些接口可以通俗地理解为props。当页面构建系统发展到一定规模时,系统中的组件会越来越多,组件库甚至组件市场也会逐渐衍生出来。这时候我们就需要一些辅助系统来管理组件。模板是组件的固定集合。当一些页面结构重复出现,只有内容发生变化时,比如一些活跃的页面,我们可以将这些页面提取到模板中。与组件一样,模板将逐渐演变成模板库和模板市场。下面以组件为例,看看组件是如何管理的。通常,有两种组件管理方法。一种是直接将组件放入代码仓库,另一种是将组件发布为独立的包,托管在包管理库中,比如npm。第一种方法通常在项目早期采用。立项之初,整个系统还处于验证打磨阶段,组件相对较少。与页面构建系统放在同一个代码仓库中,管理复杂度低,使用方便,可以实现快速迭代。但是当系统逐渐成熟,连接的服务越来越多,组件的数量呈指数级增长。通过统一的代码仓库来管理,无论是代码复杂度还是管理通信复杂度,都已经不现实了。那么你需要使用第二种方法。第二种方式是将组件发布为一个独立的npm包,页面构建系统按照一定的方式识别并加载组件包,实现组件包的访问。这种方法可以解决组件数量呈指数增长的问题,但是实现成本比较高。一般来说,需要约定一个组件接口规范,组件需要实现这个接口规范才能被系统识别和使用。但是也有一些做的比较好,比如阿里的云风蝶,就是利用云服务,借助一些工具分析npm包,推导出组件的能力。这样对组件开发的约束更少,可以直接复用已有的组件,但技术挑战也更大。可视化编辑器页面构建系统的核心应该是可视化编辑器。通常看起来像这样。可视化编辑器有两个主要问题需要解决。页面布局这里所说的页面布局不是指最终交付的页面布局,而是指页面制作时编辑器中的布局方式。为了让不懂技术的人也能完成页面的搭建,页面搭建系统需要屏蔽一些技术细节。因此,可视化编辑通常通过拖拽的方式来实现页面结构的布局。通常,可视化编辑器有多种布局选项可供选择。不同的业务场景对布局灵活性的要求不同。Flex或Grid布局会先确定画布上的布局方式,然后再填充里面的组件。这种布局方式多用于H5页面。比如在营销场景中,这种布局方式用得比较多。自由布局自由布局意味着你可以在画布上随意拖放组件。页面构建系统最终会通过一系列方法将画布中组件的相对位置处理成页面中的位置,并能适应屏幕尺寸的变化。阿里的云风蝶主要解决了中后台的页面构建问题,页面结构相对复杂,采用了自由布局的方式。这里的技术复杂性远高于使用Flex或Grid布局的系统。首先,需要正确识别组件的父子关系,也就是能够正确识别用户拖动的画布上的组件树。这里会用到一些位置计算算法。其次,canvas中组件的位置关系必须在页面上正确体现,自适应问题才能处理好。因为组件在画布中的位置是绝对定位的,在实际页面上不可能是绝对定位的,需要转换。通常需要借助行列栅格化等算法来完成。状态管理用户在可视化编辑器中编辑页面时,通常需要对组件进行增删改查,还需要对组件数据进行编辑。因此,一般来说,可视化编辑器需要一个状态管理器来管理整个应用程序的状态。当然,基于事件同步组件数据是比较简单的,但是当页面规模比较大的时候,事件的跟踪和管理就会变得非常复杂,成本会成倍增加。因此,我们这里选择了外部的全局状态管理方案。可视化编辑器针对不同业务场景的状态设计可能不同,我们简单讨论一下。一般来说,全局状态主要处理组件的增删改查,即在画布中拖拽删除组件,在组件属性编辑区修改组件属性。因此,我们可以简单的设计如下:{state:{//添加到画布的所有组件数据componentData:[],},reducers:{//添加组件到componentDataaddComponentData(){},//编辑组件,更新componentDataeditComponentData(){},//从componentData中删除组件delComponentData(){}}}整个应用的数据都保存在componentData中。在画布区域添加和移除组件时,编辑器通过addComponentData和delComponentData更新全局组件数据。当在右侧组件属性编辑区修改组件属性时,通过editComponentData更新全局组件数据。有了基本的全局状态设计,剩下的就是做一些胶水工作,比如组件属性编辑区,会有一个Form表单来编辑属性,我们需要把表单的数据变化和全局状态胶水在一起。一个常见的例子是将字段onChange粘合到editComponentData。如果是自由画布,需要处理一些拖拽动作,然后在对应的事件中粘上addComponentData和delComponentData。可视化编辑器中有很多技术细节需要解决。这篇文章对页面可视化工具的技术要点有很多讨论,大家可以看看。一般如果页面比较简单,比如营销业务中的活动页面,上面的设计就足以解决问题。但是如果是在中后台业务场景,页面会有一定的复杂度,上面的设计会显得单薄。在中后台业务场景中,组件之间往往存在关联,页面结构较为复杂,简单的editComponentData无法满足业务需求。比如组件A会依赖组件B的变化,组件B会依赖组件C的变化,这在Form表单场景中很常见。因此,我们需要使用其他方案来解决。例如,使用一些响应式解决方案。nx-js/observer-util是一个很好的响应式解决方案。发布页面编辑页面后,下一步就是发布页面。其实在编辑的时候,一般都会有预览的功能,因为原理和页面发布是一样的,我们把它放在页面发布里面。发布页面一般有两种方式,一种是直接发布为静态页面,另一种是使用渲染SDK动态获取页面数据完成渲染。静态页面直接发布为静态页面,对于业务来说是最容易使用的,只要控制好页面的缓存策略,就可以更新页面。缺点是适用性比较差。在一些需要内嵌页面的场景下,可能只有iframe等有限的选项。发布为静态页面,其实有多种技术方案可供选择。发布页面时,可以在服务端使用webpack等构建工具,根据每个页面的不同组件构建页面特定的静态资源,避免引入所有组件。也可以将页面需要的组件信息导入到HTML文档中,然后浏览器在解析文档时,会加载组件,通过渲染SDK来渲染页面。这与动态渲染的工作方式非常相似。动态渲染通过SDK进行渲染,适用性广,灵活性高,但缺点也很明显。系统需要额外提供页面数据获取接口,大大提高了系统的易用性。同时,SDK版本的升级管理也是需要考虑的问题。动态渲染需要SDK根据接口返回的信息加载各个组件的代码。也就是说,加载每个组件的js模块。模块加载方案有很多种,比如可以直接将组件构建到umd模块中,然后直接在浏览器中使用。也可以通过SystemJS等模块加载方案来实现。组件模块加载完成后,SDK即可完成页面渲染。综上所述,以上概念性讨论已经讨论了页面构建系统的很多内容。一般来说,页面构建系统的流程不是很长,核心在可视化编辑器。考虑到页面制作过程中会有非开发同学参与,整个系统能否在支持业务需求的同时真正做到降本增效,很大程度上取决于可视化编辑器是否好用。对于可视化编辑器来说,为了简单易用,需要打磨很多细节,技术投入会非常大。比如做一个免费的堪比Sketch的canvas,投入成本肯定比一个只能简单增删组件的canvas要高。因此,在考虑一个页面构建系统之前,需要明确的问题是当前的业务需求是否真的适合页面构建。在构建页面构建系统时,也需要高度结合业务需求,有针对性地选择技术方案,才能获得相对满意的输入输出。常见面试知识点、技术方案解析、教程,可扫描二维码关注公众号“何里千寻”获取,或来这里https://everfind.github.io/po....