可视化界面编辑器设计

一 设计理念

界面、编辑器、播放器

界面是一棵组件树。

image

界面编辑器就是对这棵组件树进行编辑和持久化的工具。

编辑器维护这颗树的数据,对外开放增删改查,撤销重做等接口。

界面播放器输入组件树,可以得到界面展示

未来甚至可以做到通过不同的播放器来适配不同的平台。

组件

树上的每一个组件通过输入属性决定自己的

  • 展示
  • 交互

组件可以通过组件编辑器的接口知晓是否处于编辑状态。 编辑状态下,组件可以提供交互编辑自己的输入属性。

这么做有两点好处

  • 编辑器关注的始终只有组件树,组件的属性,无需关注如何编辑组件属性
  • 组件可以为自己的业务需要,量身定做最适合的交互来编辑属性

例:设计一个 Text 组件逻辑 当处在编辑状态下,显示光标,文字为可编辑状态

image

不处于编辑状态,则显示文本内容

image

Strikingly 正是实践该理念的优秀产品[www.sxl.cn]

image

视图组件

进一步,我们可以利用组件可以在编辑状态下,提供自己的交互逻辑编辑自身属性这一特性,我们可以设计出一个特殊组件—视图组件。

视图组件本质就是组件。只不过视图组件的属性是组件列表。 可以在视图组件中可视化增加、删除、调整组件的顺序,通过视图组件,我们获得了编排组件的能力。 视图组件的交互很大程度上决定了可视化编辑器最终是什么样子,如何使用。

例如:

  • 我们可以在视图组件里放一个输入框,通过输入组件名称,回车,来添加组件,也可以通过感知拖进来的组件,来更友好地添加组件。
  • 视图组件可以是一个默认的 block ,添加进来的组件都基于默认的流式布局。也可以是一个经过扩展的有具体长宽的区域,可以把组件拖到区域的任何一个位置,获得坐标位置,成为一个绝对定位的容器。

根据具体目标可以设计出不同的视图组件,甚至可以多个视图组件共存。

视图注入点

有了视图组件,我们就可以开始往视图组件里“注入”组件、寻找需要的组件定制自己的界面了。 很多界面编辑器可能底层并不如此灵活,但是表面上都是按上述那么做的。 截止这一步,已经可以获得足够优秀好用的界面编辑器了。如 strikingly 、structor 等。

image

[https://github.com/ipselon/structor]Structor - React UI 编辑器 这是一套非常常见的理念:编辑器负责告诉组件它应该在哪里、用户选择了什么样的个性化方案。而最终能实现啥由组件库决定。 这里其实对组件的设计提出了非常大的挑战:编辑器把一块田地分给了你,你要做到尽量灵活地实现用户更多需求。

这里提出一个我认为非常具有代表性的问题:如何灵活地设计一个 Nav Bar 。

image

对照上图,我们代入前面的设计思想,可以设计出如下的属性数据结构: {logo, [{icon, name}]}

菜单文字可以自由选择是否有 icon ,有就给显示。预先提供了一些灵活性呢。 接下来考虑如何实现点击菜单触发相应的界面变化。

太难了,还是不考虑了吧。

Strikingly 就没有做这个事情。在 strikingly 里整个模板就是一个完整的程序,菜单也是这个程序的一部分,所以可以轻松实现菜单点击的页面联动效果。但是,如果你想保留这个菜单,但是页面内容部分换成其他的。嗯,strikingly 没有提供这个功能。

归根结底,我作为一个组件,拿着编辑器分配给我的一亩三分地,要能在自己的地盘上花式满足用户需求已经非常不容易了,现在还要我去管其他地方怎么显示? —太难了。

于是呢,干脆就把要交给我管的地也给我吧。 用户点击菜单1,我就让菜单下面一大块显示 1 号地,点击菜单2,就显示 2 号地…… 然后不知道 1 号地,2 号地具体显示什么怎么办呢? 也好说,让编辑器来分配新的组件过来管理就行了。

说了一大堆,总算是成功引到了正题—视图注入点。

任何组件都可以通过显示视图组件的方式,提供了视图的注入点,交由用户进一步编排组件。

举上面 Nav Bar 的例子,Nav Bar 组件把整个屏都占满,bar 的下方留下的大块空白区域是一个视图组件,用户可以使用这个视图组件的编排组件能力,把空白区域用其他组件填满。Nav Bar 这里就只负责控制空白区域是显示视图组件1还是视图组件2,至于视图组件1和2到底显示些什么,完全不用管。

再举一个 Nav Bar 上的细节:显示菜单的位置也可以通过放置视图组件来处理,用户往视图组件里加 Text 就显示文字,再往里添一个 Icon ,那就是文字+图标。还可以调换文字和图标的位置,变成不常见的左文字右图标,甚至左右俩图标,中间是文字。随心所欲。

总结

  • 可视化编辑从功能上分是两大块:编辑器和播放器
  • 界面是一棵组件树,编辑器做的就是对这棵树进行编辑,和数据持久化
  • 组件通过输入的属性决定如何显示和交互,这一点同样适用于编辑的过程
  • 编辑器需要至少一个编排组件的组件 — 视图组件,视图组件可替换,籍此实现了编辑器的可扩展性。
  • 任何组件都可以通过内嵌视图组件来实现更高的灵活性。

猜你喜欢

转载自juejin.im/post/5b655ac9f265da0f6a0376f4