ToolJet Exposed Variables(暴露变量)实战指南:用{{components.*}}实现组件间的动态数据联动
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
Exposed Variables(暴露变量)是 ToolJet 低代码应用中组件与数据互通的桥梁:每个组件在运行时都会自动暴露一组变量,用于承载用户输入、可见状态、选中结果等实时数据。本指南以 ToolJet 2.50.0-LTS 版本为背景,系统讲解暴露变量的概念、{{components.textinput1.value}}这类访问语法、常见组件的变量清单,并结合仓库源码剖析其自动创建与更新的运行机制,帮助你在属性绑定、事件处理和查询参数中灵活读写组件状态。
什么是 Exposed Variables
在 ToolJet 中,Exposed Variables 帮助开发者访问和操作组件内部的数据。这些变量并非手动定义,而是随着应用运行自动创建、自动更新的——每当用户与应用交互(在文本框中输入文字、切换下拉选项、勾选复选框、隐藏或禁用某个组件),对应的暴露变量都会在运行时被同步刷新。
从源码结构看,每个组件在配置阶段就声明了自己的暴露变量集合。例如 TextInput 组件定义 中:
exposedVariables: { value: '', isMandatory: false, isVisible: true, isDisabled: false, isLoading: false, },这组声明定义了 TextInput 组件在应用运行时对外暴露的 5 个变量及其初始值;随着用户输入与状态切换,这些值会被实时覆盖。无论是捕捉文本编辑器中的文字、检查组件当前是否可见,还是读取下拉菜单的选中项,暴露变量都是 ToolJet 应用内动态数据处理的核心载体。
访问暴露变量的语法:{{components.*}}
每个 ToolJet 组件都拥有自己的一组暴露变量,用于承载与该组件相关的具体数据。开发者可以在任何支持表达式的位置(组件属性、查询参数、事件处理器、JS 代码等)使用 JavaScript 模板语法动态访问它们。
以 Text Input 组件为例,其value变量保存着用户当前输入的内容,每次用户在输入框中键入文字,value都会被更新,访问方式是:
{{components.textinput1.value}}其中:
| 片段 | 含义 |
|---|---|
{{ }} | 表达式求值标记,ToolJet 会将其内部内容作为 JavaScript 表达式执行并替换为结果 |
components | 组件命名空间,表示访问的是画布上的组件 |
textinput1 | 组件 ID,默认为「组件类型名 + 序号」(第一个 Text Input 即textinput1),可在组件属性面板中修改 |
value | 该组件暴露的具体变量名 |
得益于这套语法,开发者可以实时追踪并利用用户在应用中的输入数据,例如把输入框内容实时同步到其他组件、文本展示或后端查询参数中。
常见组件的暴露变量盘点
不同组件的暴露变量集合不同。下面结合仓库源码,列出两个典型组件的完整变量清单。
Text Input 组件
来源:frontend/src/AppBuilder/WidgetManager/widgets/textinput.js
| 暴露变量 | 类型/初始值 | 含义 |
|---|---|---|
value | '' | 当前输入框中的文本内容,随用户输入实时更新 |
isMandatory | false | 当前字段是否为必填(受「Make this field mandatory」校验配置影响) |
isVisible | true | 组件当前是否可见 |
isDisabled | false | 组件当前是否被禁用 |
isLoading | false | 组件当前是否处于加载态 |
例如读取第一个 Text Input 的可见状态:{{components.textinput1.isVisible}}。
Dropdown 组件
来源:frontend/src/AppBuilder/WidgetManager/widgets/dropdown.js
| 暴露变量 | 类型/初始值 | 含义 |
|---|---|---|
value | 2 | 当前选中项的值(对应选项值数组中的元素) |
searchText | '' | 用户在搜索框中输入的搜索文本 |
label | 'Select' | 组件的标签文本 |
optionLabels | ['one', 'two', 'three'] | 全部选项的展示标签数组 |
selectedOptionLabel | 'two' | 当前选中项对应的展示标签 |
例如读取第一个 Dropdown 当前选中的展示标签:{{components.dropdown1.selectedOptionLabel}}。
更多组件
几乎每一个内置组件都在配置文件中声明了自己的暴露变量集合,仓库中对应文件位于 frontend/src/AppBuilder/WidgetManager/widgets/ 目录,例如:
- 复选框(Checkbox):checkbox.js
- 文件选择器(File Picker):filepicker.js
- 手风琴(Accordion):accordion.js
- 日历(Calendar):calendar.js
- 图表(Chart):chart.js
- 级联选择器(Cascader):cascader.ts
- 按钮组(Button Group):buttonGroup.js
- 日期选择器(Date Picker):datepicker.js
编写表达式时,可以直接在组件配置文件中查找对应组件声明(关键字exposedVariables),以确认可用的变量名、初始值类型与语义。各个组件的详细暴露变量说明,也可参考组件各自的官方文档章节。
实战场景:组件间动态联动
暴露变量最常见的用途,就是让一个组件的状态驱动另一个组件或查询的行为。下面是一个典型示例:让下拉菜单的选中结果实时显示在文本输入框中。
- 在画布上放置一个 Dropdown 组件(默认 ID 为
dropdown1),选项值设置为['one', 'two', 'three'],展示标签设置为['one', 'two', 'three']; - 放置一个 Text Input 组件(默认 ID 为
textinput1); - 将 TextInput 的Default value属性(见 textinput.js 中
properties.value的定义)设置为:
{{components.dropdown1.selectedOptionLabel}}保存并预览应用:每当用户在下拉菜单中选择一个新选项,文本输入框就会自动显示对应的选项标签。整个过程无需任何事件绑定或查询,纯粹依赖暴露变量的自动更新机制。
在此基础上,你还可以把暴露变量用于查询参数,例如将某个查询的参数值写为{{components.textinput1.value}},即可让查询动态携带用户输入;也可以在 Dropdown 的On select事件(见 dropdown.js)中触发其他逻辑。
在表达式校验中引用暴露变量
暴露变量同样可用于组件自身的校验规则。以 TextInput 的自定义校验(Custom validation)为例,其占位示例本身就是对组件暴露变量的引用(见 textinput.js):
{{components.text2.text=='yes'&&'valid'}}含义是:当text2这个文本组件的当前值为'yes'时,本字段校验通过(返回'valid'),否则校验失败。这展示了暴露变量在跨组件联动校验中的典型用法——一个组件的输入状态可以直接影响另一个组件的有效性判定。
运行机制:暴露变量如何被自动创建与更新
从源码结构看,暴露变量的「自动创建与自动更新」由前端的状态管理(Store)统一维护。左侧检查器(Left Sidebar Inspector)在渲染时通过useStore读取全局暴露值,相关实现见 frontend/src/AppBuilder/LeftSidebar/LeftSidebarInspector/LeftSidebarInspector.jsx:
const exposedComponentsVariables = useStore((state) => state.getAllExposedValues().components, shallow); const exposedQueries = useStore((state) => state.getAllExposedValues().queries || {}, shallow); const exposedVariables = useStore((state) => state.getAllExposedValues().variables || {}, shallow); const exposedConstants = useStore((state) => state.getAllExposedValues().constants || {}, shallow); const exposedPageVariables = useStore((state) => state.getAllExposedValues().page || {}, shallow); const exposedGlobalVariables = useStore((state) => state.getAllExposedValues().globals || {}, shallow); const exposedModuleInputs = useStore((state) => state.getAllExposedValues(moduleId).input || {}, shallow);可见,暴露值体系不止包含组件(components),还包括查询(queries)、变量(variables)、常量(constants)、页面变量(page)、全局变量(globals)以及模块输入(input)等命名空间。组件的暴露变量只是其中components命名空间的一部分——当组件渲染、用户交互、查询执行时,对应的暴露值会被写入全局状态,任何引用该值的表达式都会随之重新求值,从而形成「状态变化 → 表达式重算 → 界面/查询刷新」的响应式链路。
在 Inspector 中实时查看暴露变量
开发时无需记忆每个变量的名字。ToolJet 的左侧 Inspector(检查器)面板会以树状结构实时展示当前应用的全部暴露值,包括各组件的变量、查询结果、全局变量等。当你选中某个组件或运行应用并与之交互时,Inspector 中对应节点的值会实时变化,是调试暴露变量表达式最直接的辅助工具(数据来源即上文引用的 LeftSidebarInspector.jsx 中的formatInspectorComponentData、formatInspectorQueryData等格式化函数)。
注意事项与最佳实践
- 组件 ID 决定访问路径:
{{components.组件ID.变量名}}中,组件 ID 是访问的关键。画布上同类组件会被自动编号(textinput1、textinput2……),重命名组件后,所有引用该组件暴露变量的表达式都要同步更新,否则会指向不存在的组件。 - 以配置文件为准:不同版本或不同组件的暴露变量集合可能不同,编写表达式前可对照 widgets 目录 下对应组件的
exposedVariables声明确认变量名与类型,避免引用不存在的变量。 - 区分「值」与「状态」:同一组件往往同时暴露数据值(如
value、selectedOptionLabel)与界面状态(如isVisible、isDisabled、isLoading),按需选择,例如控制另一个组件显隐时可读取源组件的isVisible。 - 响应式特性:暴露变量是实时的响应式数据,表达式中引用它意味着「始终取最新值」,无需手动同步——这正是它适合做组件联动与动态查询参数的原因。
总结
Exposed Variables 是 ToolJet 动态数据处理的基石:组件在运行时自动暴露并实时更新一组变量,开发者通过{{components.组件ID.变量名}}即可在任意表达式中访问它们。从捕捉文本输入、读取下拉选中项,到检查可见性、驱动跨组件校验与查询参数,掌握暴露变量意味着你能够用最少的代码搭建出真正"活"起来的内部工具与业务应用。结合 组件配置文件 与 Inspector 实现,你可以在仓库中进一步追溯每个变量的定义与更新链路。
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考