低代码表单联动配置:从节点驱动到数据驱动

前言

低代码从概念到产品落地已有十多年,从早期的全民追捧、资本热炒,到如今行业洗牌分化,市场早已褪去了"低代码万能"的泡沫。其实并不是低代码不火了,AI时代研发的人力成本被重新定义:AI代码工具不再是简单的补全代码片段,而是让开发者回归产品思维,兼顾架构设计与细节体验,快速响应用户反馈完成产品迭代,低代码恰恰在这个周期里重新迎来了爆发窗口。更关键的是,AI智能体正在打通从低代码到无代码的最后一公里,让业务人员也能通过自然语言直接生成可用表单,低代码的生产力边界被彻底拓宽

市面上绝大多数 Vue3 低代码表单方案,要么是基于开源项目二次封装,底层依然沿用类 DOM 的节点 API 做联动,开发者必须手动调用 getWidgetByNamesetValue 这类命令式接口才能完成字段交互,本质上没有脱离"节点操作"的旧思路;要么深度绑定特定生态,跨系统集成成本高,复杂业务里处处受限。

我们自研的这款 Vue3 原生低代码表单,直接建在 Vue3 的响应式之上,联动按数据走,而不是按控件节点走。字段的值、显隐和级联,落在同一条响应式作用域链里,改数据即可带动界面,不必再去找节点、设控件 。这更贴近 Vue 开发者的习惯,也少掉传统低代码表单里常见的数据对不齐、联动难收口、后期难维护。

下面咱们以实际的案例,来介绍和对比下大家比较关注的这两种机制下的低码平台的字段联动功能配置。

联动案例

考生填报志愿

联动逻辑

  • 语数外三科输入分数,自动实时累加计算总分
  • 按总分档位动态更新志愿提示:一流大学/二流大学/三流大学
  • 总分低于合格线判定为落榜,志愿输入框自动标红高亮,占位符切换为"请填写落榜原因"
  • 有字段值缺失时页面无"脏"状态

成绩单联动

联动逻辑

  • 按照有效的成绩行来合计
  • 体育不及格(低于60分)成绩单将行高亮
  • 成绩不合格则对应科目单元格高亮

联动配置

传统低码表单

这里以vform3代码平台为代表,来介绍传统低码表单平台以节点API驱动的机制如何在页面实现关联配置。就以咱们第一个简单的联动案例为需求,看下vform3平台如何配置吧。

先看预览的效果

接下来咱们来看下vform3这块的联动配置,先看求总分的,这块依赖数值框的计算公式特性,操作以点选的形式,觉得再提供一个直接编辑表达式的模式会更直接

以上对数值框提供的计算能力,算是对其他数值字段做到了关联监听,处理方式单一,仅做到算术求值;而对于填报志愿文本框与其他字段框的联动与更新需求,vform3并不支持对目标字段直接设置要关联监听的字段,我们可以考虑两种钩子:

  • 表单全局的监听事件钩子

它用于表单数据变化要做的统一处理逻辑,另外作为绑定特定目标字段的关联多源字段处理逻辑的备选方案

  • 字段onChange钩子 只适合单源字段的依赖监听,而多源字段只能回退到全局钩子的分支判断

这里我们在总分的onChange字段钩子上加控制逻辑

从代码的风格可以看出,vform3在底层组件之间的交互并不是 vue的机制,而是回退到节点API的操作方式,vue更多的用于单个组件的渲染,组件间的交互无法做到数据响应式还是很遗憾的。

对于稍微复杂点的联动需求,这里就不再用该平台演示了。

Vue3原生低码表单

就像前端开发框架从基于DOMjQuery到基于MVVMVUEReactAngular,低代码表单从基于节点API到完全对齐数据驱动,这在AI时代下,为无代码平台的终极目标创造了更好的条件,因为基于数据驱动的json schema相比节点API驱动的低代码平台,无疑配置上更加灵活、简洁易扩展,作为无代码平台的底座,让AI智能体更容易读写和维护。

看回咱们初版的低码平台,这里基本的输入控件通过字段名实现双向绑定

文本表达式

对于文本元素,通过表达式来求值,结果是否展示在界面上以及是否写入模型都由开关控制

双击表达式输入框,将弹出带智能提示自动补全和代码高亮的代码编辑器

这里可以直接写表达式,字段可基于所在作用域自动联想出来,支持一些内置的辅助函数比如:isEmptysumAll(如果操作数有空值,则整体不计算)、sumSkip(忽略空的操作数进行求和)等等。除了表达式还可以写箭头函数,下面的实现等同于sumAll(...)的逻辑,这里我们展开介绍下:

js 复制代码
(scope, api) => api.hasEmpty(scope.chinese, scope.math, scope.english)
  ? undefined
  : scope.chinese + scope.math + scope.english

这里提供了当前字段所在的作用域,通过作用域获取关联字段,作用域还支持寻址,比如在表达式中可以直接写:$parent.role$root.totalScore$parent.$parent.obj.remark等等,而对于箭头函数则使用第二个参数api的相关方法来访问,比如这里调用辅助函数api.hasEmpty(...),而要通过寻址获取字段值,则调用api.get('$root.name')类似的。

通常箭头函数中获取作用域变量,咱们可以用解构的形式来简化,比如上面的形式解构为:

js 复制代码
({ chinese, math, english }, api) => {
  if (api.hasEmpty(chinese, math, english)) return undefined
  return chinese + math + english
}

vue3 对齐机制

这里的 expression 所绑定的对应到 vue3computed 计算属性。

明白了文本元素的表达式属性,这里再配置一个页面隐藏且不写入模型的分数档字段,按照之前的总分字段来计算表达式

控件样式

按照vue中对html元素通过计算属性来动态绑定样式的机制,这里很自然的支持类似的页面配置

这里的样式直接采用应用文件中已经被预编译的TailwindCSSclass即可。看下效果:

单源联动处理

当目标字段框依赖某个字段的值变化去做更新逻辑时,可以直接对目标元素采用联动配置,比如这里的填报志愿文本框对分数档文本的监听配置

要监听的字段按照数据模型的层级,这里会是一个多级下拉框,这里我们先不涉及跨数据对象层级的字段监听。

当源字段值发生变化时,会执行handler,双击弹出编辑器,第一个入参为监听的源字段变化后的值,第二个为配置的宿主元素的字段对象,它是一个vue响应式的对象,按照这里的逻辑去更新字段配置元数据即可。

咱们初版低码平台的组件目前仅考虑ant design vue作为UI,因此这里对于大文本框控件其实可以直接对field.props.status属性去更新error就能达到之前控件样式配置的需求了。从这也发现,数据驱动的配置渠道多样化了,更灵活,用户有更多选择。

揭秘单源联动 vue3 对齐机制

表单引擎底层对源字段的监听对齐了 vue3watch特性,目标字段可以添加多个联动配置以监听不同的源字段,而对于同一个源字段,这里只会 watch 一次,对注册的多个 handler,以数组的形式来触发。

如果源字段因页面联动被卸载,对应的 watch 会停掉,监听方先收到 undefined 以便复位;源字段再出现则重新订阅。设计器中删除源字段则随表单重新编译,旧订阅一并释放。

如果目标字段(依赖方)被隐藏,监听没有意义,会从该源的激活表中拿掉,不再执行 handler;若它是这个源的最后一个听众,源上的 watch 一并停掉并移除。目标字段再显示时重新激活,按源字段当时的值再跑一遍 handler

多源联动处理

针对多个源字段的关联监听来对目标字段做不同处理这种复杂的场景,我们提供了表单和子容器的插件配置特色功能,可以添加一个或多个插件的配置来完成不同的复杂联动处理任务。

对于咱们之前演示的考生填报志愿的大文本框联动的例子,这里我们配置表单级的插件

when部分代码触发插件执行的条件,可以基于其他字段联动来触发,这里咱们始终触发。handler则相当于一个"万能"的监听处理器,它可以处理当前数据对象层级乃至跨层级的多源字段监听,并对当前层级的乃至跨层级的目标字段进行更新,一般来说,推荐的做法是,插件配置在哪个层级配置的,就作用于当前层级的字段。

看下咱们通过插件来替换之前单源字段监听,显然这里我们通过exp中提供的回调来向表单引擎层注入计算属性来监听参与处理的字段,而要更新的目标字段,则通过api.at('...')来获取,这相比输入控件上的联动绑定,这里的作用范围更大,更灵活。

这里的exp可以调用多次来构建不同的监听链路,比如这里咱们将关联的三个源字段的一次绑定拆成两次:

js 复制代码
(exp, api) => {
  const cm = exp((scope) => (scope.chinese || 0) + (scope.math || 0))
  const english = exp((scope) => scope.english || 0)
  const t = Number(cm) + Number(english)
  const band = t >= 280 ? 'tier1' : t >= 250 ? 'tier2' : t >= 220 ? 'tier3' : 'fail'
  ...
}

执行的链路:exp内层的执行由 vue 的计算属性来盯,修改语文或数学字段,绑定的english计算属性会缓存,不会重新计算;单独更新英语字段同理。而对于 handler的执行,由咱们表单引擎来盯,盯的是whenexp执行结果的变化,所以说整个handler处理的功能由这两层"盯人"机制一起协作完成。

总结

写到这里,诚惶诚恐,通过一个多月的表单引擎到低码拖拽配置平台的整个辛勤自研,做出来点新型低码平台的雏形。中间迭代很多轮,解决了数据驱动的表单引擎测试中很多性能问题。也参考了市面上同类产品使用体验,通过对比写下这篇拙作,没想过与同行的成熟的低码表单解决方案去鸡蛋碰石头,只是把 vue3 写代码去实现表单的那种直接操作数据的体验,从代码文件搬到了页面配置上,想不到能解决很复杂灵活的企业表单联动需求,又深感欣慰。再接再厉!

相关推荐
DianSan_ERP1 小时前
WMS接入电商平台自动化履约实战:一张订单从平台到出库的接口时序设计
java·前端·网络·数据库·安全·架构·自动化
莪_幻尘1 小时前
手把手书写你的第一个 AI Agent:当 Skill 有了记忆、角色和主动性
前端·agent
原则猫2 小时前
设计模式
前端
光影少年2 小时前
react navite环境与工程化
前端·react native·react.js
PedroQue992 小时前
v2.6.0 新增全局返回守卫与 iOS 侧滑拦截,补齐跨端路由拦截能力
前端·uni-app
lichenyang4532 小时前
从「房间」到「实时通知」:用 NestJS + Socket.IO 实现团队邀请的完整工程实践
前端·后端
ly76893 小时前
Vue 3 从入门到工程实践:基础语法、组件化、路由、状态管理与项目部署
前端·javascript·vue.js
掘金酱3 小时前
TRAE Work 实战帮征文 | 获奖名单公示
前端·人工智能·后端
陆枫Larry3 小时前
Chromium和Chrome到底是什么关系?
前端