持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
前言
手摸手实现可视化系统系列我们前面已经介绍了四节,完成了:
- 主舞台的搭建
- 拖放组件到主舞台
- 组件的自由变换
接下来我们来探讨属性配置面板的设计和实现。
需求分析
我们的主功能区大概是这样的: 包括头部区域(一些工具栏、logo、 用户信息等); 左侧是组件列表(选择组件拖动到主舞台上); 中间是主舞台(也叫做屏幕编辑区域); 右侧就是属性编辑区域(在右侧动态修改组件或屏幕的属性,主舞台上同步预览效果)。
今天这篇文章的核心就是探讨下右侧这个面板的实现思路和细节。
方案设计
首先可以明确的一点是配置项肯定是一条一条的,或者叫一项一项的,一般这样的数据呈现我们很容易想到List\table\form
。
因为需要用户输入,所以优先选择form表单。
其实用List也ok,因为我们的提交方式和一般的表单不太一样,我们会维护整个舞台上的组件或屏幕的全部数据, 当用户点击保存之后,我们再一次性提交数据。
属性编辑面板其实包含两部分的属性: 屏幕属性、组件属性。
我们用一个tab进行两者的切换。
那么问题来了: 我们是为每个widget写一份属性配置表单,切换组件时整体切换? 还是划分成颗粒度更小的配置项,根据widget的config动态生成表单呢?
举个栗子🌰:我们以通用文本组件为例
方案一:
- 写一个
commonTextConfig.vue
文件,里面包含文本组件的全部属性 - 当选中
commonText
组件时,我们切换显示commonTextConfig.vue
的表单。
方案二:(灵感来自formGenerator)
- 把配置项切分成颗粒度更小的属性单元,例如
size.vue、 border.vue
,就是把大小、位置、边框等属性拆分成单元小组件。 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文件。
记得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相关的配置。
目前已经完成的效果,整体配置效果还是可以的。
计划
目前的6个基础组件已经基本完成了。
我们接下来会重点实现功能: p0:
- 保存、
- 上一步、下一步
- 预览页面
- 图表组件的完善
p1:
- 单看板导出成文件(可以独立运行)
- 数据接入
源码地址
github: vis-board-webpack 有兴趣的小伙伴可以fork、star、pr,欢迎大佬莅临指导~
写在最后
更文不易,你的支持是我持续创作的动力~
如果对可视化系统感兴趣,可以持续关注专栏。