从零开始的可视化搭建系统

从零开始的可视化搭建系统

可视化搭建系统是一个有趣又神秘的话题,但事实上上手并不困难,结合过去云凤蝶在中台应用搭建的探索,我们尝试用一个码农想方设法偷懒的故事来教大家从零开始写一个可视化搭建系统

开始偷懒

阿炮是一个二十五岁的前端码农,在一家互联网企业上班,日常的工作就是为一个营销站点切图,奉守平静但能偷懒尽量偷懒的生活哲学

但营销站点飞速变化,一周换一次广告,阿炮每次都要提交、测试、发布、验证,阿炮想打破痛苦的重复生活

模版与数据

阿炮花了三天把代码里经常变化的内容比如广告地址提炼出来,并搞了一个配置页面,让运营来自己录数据,最后写了一个渲染引擎,能够把数据和模版结合渲染出来

<a href={{ config.banner.url }}><img src={{ config.banner.cover }} /></a>

config: {
  banner: {
    cover: 'https://alicdn.com/guanggao.jpg',
    url: 'https:taobao.com/sth',
  },
}

运营原来需要阿炮转填的地址,现在可以自己直接提交,阿炮偷了懒,运营也少了沟通的时间,大家都很开心,这条路走对了!再看看其他页面能不能也用这个办法偷偷懒,得想个办法把我无敌的配置器放上去

模块化

通过模块化完成复杂度的分治与复用

阿炮开始把更多网站上的可能变化的信息挖成了配置,并录入到系统,眼看着这个运营网站已经快被挖空只剩骨架了,但配置项变成汪洋大海,阿炮现在很头痛怎么分辨这些配置项究竟是干嘛的

正巧阿炮突然接到一个需求,公司开辟了国外的业务,但文化差异导致模块展示不完全相同,阿炮灵光乍现,给每个模块起个名字,导航、广告、老黄历等等,然后按照模块名来做二级管理!再通过标志位表达整个模块的启用/关闭,这样以后加新的需求,就开新的模块,按模块名把动态的东西挖出来,再放进模版里

甚至模版就已经能支持简单的模块级的编排了!

布局系统

又过了一段时间,运营说,赞助商预算调整,顶部的广告模块要一整个放到页面底部,尺寸也要小一号

阿炮仔细盘算,按照这个趋势,模块的尺寸和位置关系也逐渐有了动态性,即使是同样一个模块,也是有的宽有的窄,于是他准备将原来的配置项抽出来,新开到一个单独的命名空间来集中表达模块的尺寸和位置关系,引入最初版的布局系统

又过了一段时间,新来了一个天马星空、超前设计的设计总监,要做整站的设计改版:这几个模块我要摆一个三角形!阿炮原来的模块编排的设计无法支撑了,于是他果断把原来的排版引擎重写为自由布局模式,将基于数组顺序的数据迁移到绝对位置

可视化拖拽

符合直觉的编辑体验

自由布局的描述力很强,但是手写坐标太不直观了,阿炮想起了平时使用的 Sketch、PS,要有一个画布!拖到哪就是哪!自动把位置信息记录下来!于是阿炮花了几个月搞了一个可视化拖拽的画布出来

能自由拖拽以后,大家都很开心,每天画画图,需求就做好了,越来越多的人开始使用阿炮的程序来搭建,但自由拖拽也渐渐暴露问题,鼠标操作自由度很高,但很难控制,模块的位置总是不够整齐,我们要设计上的自由性,但自由需要一些规则来约束,比如说,像 Ant Design 一样,保持八倍数的间距,阿炮深受启发,又写了一个对齐和参考线系统来辅助拖拽

阿炮年终总结拿着可视化搭建系统说,我只是想偷个懒而已,现在我只想过平静的生活

提炼

什么是搭建系统

其实从第一次抽取变量,搭建系统就完成了,一个搭建系统就是基于一份模版语言的数据生产过程

  • 模版引擎:数据的使用者,通过对应用和业务解构,抽象出合适和的数据定义和渲染引擎
  • 编辑器:数据的生产者,通过高效的编辑模式来生产引擎所需的数据

演进

在上述例子中,搭建系统从简单的变量到后续完善的可视化搭建不断演进,编辑器通过按模块组织、可视化拖拽、对齐参考不断提升数据生产效率,而模版引擎通过挖更多的洞、支持布局系统来支撑越来越复杂的需求,渐渐的从一个简单的运营系统搭建演化为一个丰满的可视化搭建系统

每新增一种类型的需求,就相应的定义一份能够描述它的数据,并通过编辑器生产出来,最后在运行时加入能够翻译这部分功能的代码,这样搭建系统整体就可以不断完善和进化

模版引擎

模版引擎是搭建系统的核心,决定了搭建系统的最大复杂度和完备性,通常可以通过将目标应用解构为配置项来提取模版引擎,抽象程度越来越高,就能做越通用的需求,比如 CMS 系统通过可拓展的模版来使站点的搭建范围是开放式的,相比之下,点餐系统商家录入商品信息也是一种模版引擎,但只能解决固定场景的问题,云凤蝶的模版引擎请参考隔壁文章《云凤蝶可视化搭建的推导与实现》


我们可以把一个应用解构为模块 - 属性 - 值的架构模式,通过声明式的方式把模块、模块关系组装起来,同时兼具足够的拓展性

模块 - 属性 -值
  • 模块:可重用最小封装单元
  • 属性:组件的行为的具体体现,包括千人千面的基础属性与通用能力,比如布局、条件渲染
  • 值:联系数据流、绑定的载体,比如单向绑定、双向绑定

模块

引擎的一大部分拓展性是由模块自身的可拓展性来承担的,模版不支持的很多逻辑都可以封装在模块内部,再通过将模块接入模版引擎完成拓展,因此,很多搭建系统都支持导入各种类型的组件,比如 React、Vue、Angular 组件

属性

每个模块通常会有自身的一些属性,比如 React 体系下的 props,就是组件向外暴露的属性,除此之外,引擎还可以赋予组件一些平台级的通用属性,比如自由布局能力就是组件本身不具备,是外层封装赋予的属性,通过赋予属性,可以以声明式的方式极大的拓展组件的横向能力,比如

  • 逻辑控制,if、repeat、switch,组件可以根据条件做不同的渲染
  • 交互行为,跳转、Loading 等

除了几种基本类型的值外,还可以通过拓展一些实体类型的值,完成一些复杂逻辑的封装,比如

  • 维系模块之间的数据流转的关系提取为订阅类型
  • 远端数据加载封装为 Connector 类型的值

对于组件来说,通过将 dataSource 像设为一个静态的数据一样设置为一个 Connector 类型的值,就具备了挂载时发起请求,并把请求结果设置到 dataSource 属性上的能力

编辑器

编辑器很容易起步,万事都可以用一个 Monaco 编辑器来编辑,但用户即使对照文档也很难写出符合要求的数据,在此之上,我们可以做更细粒度的拆分来逐步编辑器的可用性

属性面板

按照上述模块 - 属性 - 值的架构模式,每个应用由模块组成,每个模块的行为由模块本身的属性取值决定,因此可以把对站点的编辑分解到每个模块的编辑

结合 Chrome 和常见编辑器的设计,我们可以为每个模块配备一个属性面板,根据模版自身的属性定义与框架通用属性的定义,推断出最合适的渲染器,比如对于字符串类型,我们可以使用输入框来编辑,对于布尔类型,我们可以使用多选框来编辑,详细可以参考隔壁文章《开放的组件定义与属性面板》

可视化拖拽

模块的位置与布局信息使用数据来直接表达可能并不直观,我们可以像阿炮一样,使用画布中可视化的拖拽来查看和编辑,再花上一段时间来进一步提升效率与准确率,参考隔壁文章《云凤蝶如何打造媲美 sketch 的自由画布》

所以写一个可视化搭建系统需要几步?

三步:

  • 分析业务特征,抽象渲染引擎与数据
  • 写一个配套的信息录入系统
  • 不断的完善它们

回过头再看这句话:搭建系统其实就是一个基于模版语言的数据生产过程

好了,道理你都懂了,再加上其他细节,自己动手写一个搭建系统吧


未来已来,时不我待!

云凤蝶招聘前端、Java、PD、设计岗位,未来等你共创!

如果你感兴趣,欢迎联系 chenyu@antfin.com 或 shuai.shao@antfin.com

编辑于 2019-12-09

文章被以下专栏收录