【可视化系统】如何设计组件配置项的颗粒度?

1,363 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

前言

手摸手实现可视化系统系列我们前面已经介绍了四节,完成了:

  • 主舞台的搭建
  • 拖放组件到主舞台
  • 组件的自由变换

接下来我们来探讨属性配置面板的设计和实现。

需求分析

image.png

我们的主功能区大概是这样的: 包括头部区域(一些工具栏、logo、 用户信息等); 左侧是组件列表(选择组件拖动到主舞台上); 中间是主舞台(也叫做屏幕编辑区域); 右侧就是属性编辑区域(在右侧动态修改组件或屏幕的属性,主舞台上同步预览效果)。

今天这篇文章的核心就是探讨下右侧这个面板的实现思路和细节。

方案设计

首先可以明确的一点是配置项肯定是一条一条的,或者叫一项一项的,一般这样的数据呈现我们很容易想到List\table\form

因为需要用户输入,所以优先选择form表单。

其实用List也ok,因为我们的提交方式和一般的表单不太一样,我们会维护整个舞台上的组件或屏幕的全部数据, 当用户点击保存之后,我们再一次性提交数据。

属性编辑面板其实包含两部分的属性: 屏幕属性、组件属性。

image.png

我们用一个tab进行两者的切换。

那么问题来了: 我们是为每个widget写一份属性配置表单,切换组件时整体切换? 还是划分成颗粒度更小的配置项,根据widget的config动态生成表单呢?

举个栗子🌰:我们以通用文本组件为例

方案一:

  1. 写一个commonTextConfig.vue文件,里面包含文本组件的全部属性
  2. 当选中commonText组件时,我们切换显示commonTextConfig.vue的表单。

方案二:(灵感来自formGenerator)

  1. 把配置项切分成颗粒度更小的属性单元,例如size.vue、 border.vue,就是把大小、位置、边框等属性拆分成单元小组件。
  2. commonText组件的配置文件commonTextConfig.json声明了它需要配置的属性(size\position\border等),根据配置文件生成表单项。

方案三:(更小颗粒度的配置token)

在方案二的基础上,我们将form-item拆分成更小的小组件,比如一个width指标,应该包含一个inputNumber输入框 + 单位选择select

方案对比

  • 方案一的心智成本较低,实施起来也比较容易; 缺点也比较明显: 1、重复属性会出现很多重复代码;2. 后续增加更多的组件,需要写特别多的配置表单文件;3. 每增加一个组件,就需要手动添加一个表单,边际成本高,扩展性比较差。

  • 方案二相对来说前期成本比较高(需要编写大量的form token),但后期成本会呈现递减趋势, token逐渐完善,后期添加一个组件可能已经覆盖了组件的全部属性项。

  • 方案三应该是最像formGenerator的思路,但是schema json会变得特别繁琐,带来更高的维护和学习成本。带来的收益应该是有限的token数量。

我们虽然最终选择了方案二,但是大量的 from token编写让我还是会有点怀疑是否还有更好的方案? 大佬可以在评论区一起交流下~

现状

单单是通用样式就写了15个token文件。

image.png

记得webpack用require.context,vite用import.meta批量导入小组件,要不一个个导入写起来很恶心的。

const files = require.context("./libs", false, /\.vue$/);

const modules = files.keys().reduce((total, key) => {
  const name = key.replaceAll(/\.\/|\.vue/g, "");
  const component = files(key)?.default;
  return Object.assign(total, { [name]: component });
}, {});
export default modules;

目前只完成了通用样式的配置,不同的组件需要有自己“独特”的配置型,这部分工作量还是很庞大的。

填充token是个渐进的过程,随着组件的增加,token会逐渐完善,特别是相似的组件能够复用token.例如chart相关的配置。

现状.png

目前已经完成的效果,整体配置效果还是可以的。

计划

目前的6个基础组件已经基本完成了。

image.png

我们接下来会重点实现功能: p0:

  • 保存、
  • 上一步、下一步
  • 预览页面
  • 图表组件的完善

p1:

  • 单看板导出成文件(可以独立运行)
  • 数据接入

源码地址

github: vis-board-webpack 有兴趣的小伙伴可以fork、star、pr,欢迎大佬莅临指导~

写在最后

更文不易,你的支持是我持续创作的动力~

如果对可视化系统感兴趣,可以持续关注专栏。