ToolJet 多页面应用(Multipage App)完整指南:Pages 面板、页面选项与页面变量
【免费下载链接】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
Pages(页面)是 ToolJet 应用构建器(App Builder)中的核心组织单元。它允许你在单个应用(Application)内创建多个页面,让 ToolJet 应用更容易导航、结构更清晰、对最终用户也更友好。本文以官方教程文档为基础,结合 ToolJet 前端源码(frontend/src/AppBuilder相关模块)深入讲解:如何打开并操作 Pages 面板、如何通过 Page Options 管理页面(重命名、Mark Home、隐藏、禁用、删除等)、页面事件(On page load)如何使用,以及通过page对象暴露的动态变量如何在表达式中引用。读完本文,你将能够熟练地在 ToolJet 中搭建多页面业务应用,并掌握利用页面 Handle、页面变量与 Switch Page 动作实现页面间数据传递的实战能力。
Pages Panel(页面面板)
Pages Panel 是管理应用内所有页面的入口。在应用构建器(App Builder)的左侧边栏中,点击Pages 图标即可打开Pages Panel。
打开面板后,你可以看到应用内所有页面的列表。在面板顶部,提供了以下几个核心操作:
Add Page(添加页面)
- 在 Pages Panel 的头部,有一个+按钮,用于向应用添加更多页面。
- 点击+按钮即可新增一个页面。
- 输入新页面的名称(Name),按回车确认即可完成添加。
从源码看,新增页面会生成一个唯一的id(使用uuid),同时自动推导一个handle,并将index设置为当前页面数量加一,随后通过appVersionService.autoSaveApp以create操作自动保存到对应应用版本中(参见 pageMenuSlice.js 中的addNewPage)。如果在添加时检测到同名页面,会弹出 "Page with same name already exists" 的提示,这是源码中通过pages.some((page) => page.name === name)校验后给出的反馈(pageMenuSlice.js)。
Search(搜索页面)
- 在 Pages Panel 顶部的**搜索栏(Search bar)**中,可以按页面名称快速检索特定页面。
源码中的handleSearch使用 Fuse.js 对页面名称做模糊搜索(keys: ['name'],threshold: 0.3),匹配结果会以高亮列表的形式呈现在面板中(pageMenuSlice.js)。
Pin(固定面板)
- 默认情况下,当你点击面板外部区域时,Pages Panel 会自动关闭。
- 点击Pin(固定)按钮可以将 Pages Panel 钉住,面板在**取消固定(unpin)**之前不会自动关闭。
Settings(页面导航设置)
- 在Settings中启用Hide Page Navigation(隐藏页面导航)选项后,**查看模式(Viewer mode)**下将不会显示页面导航侧边栏。
该设置在源码中对应页面级设置项,最终随pageSettings一同以page_settings类型通过autoSaveApp持久化(pageMenuSlice.js 中的pageSettingChanged)。
Page Options(页面操作选项)
每个页面都有多个可用的操作选项。使用方式:点击页面卡片(Page Card)右侧的 kebab 菜单(三个点图标),即可展开该页面的操作列表。
Page Handle(页面句柄/别名)
Page Handle是附加在应用 URL 末尾的 slug(别名)。默认情况下,page handle 是页面名称的小写形式,并将空格替换为连字符(-)。你可以点击 page handle 旁边的Edit(编辑)符号来修改它。
- 例如:页面名称为
Customer Details,默认 handle 为customer-details。 - 修改 handle 后,应用 URL 会相应变化,例如
https://app.tooljet.com/applications/<app-slug>/customer-details。
源码中的updatePageHandle会在保存前校验新 handle 是否与现有页面冲突,若重复则提示 "Page with same handle already exists"(pageMenuSlice.js)。另外,addNewPage在创建页面时会自动检查 handle 冲突,并自动追加序号(如page-1)以保证 handle 唯一(pageMenuSlice.js)。
Rename(重命名页面)
Rename选项允许你重命名页面。需要注意的是:重命名页面不会改变其 slug / page handle——名称(name)与句柄(handle)是两个相互独立的字段。
源码中updatePageName与updatePageHandle分别通过独立的命令更新['name']和['handle']路径(pageMenuSlice.js),这印证了"重命名不影响 handle"的行为。
Mark Home(设为首页)
Mark Home选项可以把某个页面设置为应用的默认落地页(default landing page)。打开应用时,被标记为 home 的页面将是用户看到的第一个页面。
:::info 提示 被标记为 home 的页面,其页面卡片(Page Card)左侧会显示一个 Home 图标。 :::
从源码看,markAsHomePage会将homePageId写入应用定义并自动保存(diff 为{ homePageId: pageId },pageMenuSlice.js);应用启动时的默认路由、以及删除当前页/禁用页面时的回退逻辑,都会依据homePageId定位首页(appSlice.js 中的getHomePageId)。
Hide Page on app menu(从应用菜单隐藏页面)
Hide Page选项可以将页面从查看模式下的**页面导航侧边栏(page navigation sidebar)**中隐藏。你可以再次进入选项菜单并选择Unhide来将其恢复显示。
需要特别注意的规则:
- 被标记为 home 的页面不能被隐藏。
- 隐藏后,该页面虽然不会出现在导航侧边栏中,但仍然可以通过 Switch Page 动作或直接访问页面 URL 来进入。
源码中,隐藏页面对应页面对象的hidden字段,由updatePageVisibility(命令路径['hidden'])处理并自动保存(pageMenuSlice.js)。同时,查看模式下的侧边栏渲染逻辑会依据页面的hidden与disabled状态决定是否展示该导航项(PagesSidebarNavigation.jsx)。
Duplicate(复制页面)
Duplicate选项可以创建并添加一个当前页面的副本到页面列表中。复制出的页面是原页面的精确副本(exact replica),包含其组件、布局与配置。
源码中的clonePage通过appVersionService.clonePage在后端完成页面克隆,返回新的页面数据与事件数据后,将新页面插入状态,并自动切换到新页面(pageMenuSlice.js)。
Event Handlers(页面事件处理器)
与 ToolJet 的其他组件类似,页面本身也可以挂接事件处理器。对页面而言,可用的事件是On page load(页面加载时)。你可以为该事件使用所有可用的动作(Action),此外还有三个专门为页面新增的动作:
- Switch Page(切换页面):跳转到应用内的其他页面;
- Set Page Variable(设置页面变量):在当前页面作用域内创建/赋值一个变量;
- Unset Page Variable(移除页面变量):清除通过 Set Page Variable 创建的变量。
结合动作文档的进阶用法
Switch Page 支持携带 Query Params(查询参数)。查询参数会以?key=value的形式追加到目标页面 URL 末尾,多个参数可用+按钮继续添加。典型场景:把username作为 key,值为{{globals.currentUser.email}},即可在切换页面时将当前登录用户邮箱动态传递给新页面(switch-page.md)。
三个页面动作均可在RunJS 查询中通过actions对象以代码方式触发:
// 切换页面 await actions.switchPage('<page-handle>'); // 切换页面并携带查询参数(数组形式的键值对) actions.switchPage('<pageHandle>', [['param1', 'value1'], ['param2', 'value2']]); // 设置页面变量(key 必须是字符串;数值类型的 value 无需加引号) await actions.setPageVariable('<variablekey>', <variablevalue>); // 移除页面变量 await actions.unsetPageVariable('<variablename>');(参见 switch-page.md、set-page-var.md、unset-page-var.md。)
Disable Page(禁用页面)
Disable Page选项可以禁用某个页面。被禁用的页面在查看模式下将无法访问。
注意:被标记为 home 的页面不能被禁用。
源码中,禁用页面对应页面对象的disabled字段,由disableOrEnablePage(命令路径['disabled'])处理并自动保存(pageMenuSlice.js);侧边栏渲染时会过滤掉disabled的页面(PagesSidebarNavigation.jsx)。
Delete Page(删除页面)
你可以使用Delete选项从应用中删除一个页面。
注意:被标记为 home 的页面不能被删除,且删除选项会被禁用。
源码中的deletePage还包含额外的保护逻辑:当应用只剩一个页面时,会拒绝删除并提示 "You cannot delete the only page in your app.";当删除的是当前正在编辑的页面时,会自动切换到 home 页面(pageMenuSlice.js)。
Exposed variables(页面暴露的动态变量)
每个页面都会向运行时暴露一个page对象,其中包含以下可直接在表达式中引用的变量:
| 变量 | 说明 |
|---|---|
handle | 页面的 slug(句柄)。在 URLhttps://app.tooljet.com/applications/crm2/home中,crm2是应用名,home是页面的 handle。handle 在页面创建时自动设置,也可通过 Page options 中的 Rename 修改。动态访问方式:{{page.handle}} |
name | 页面创建时设置的名称。动态访问方式:{{page.name}} |
id | 每个页面在创建时获得的唯一标识符。动态访问方式:{{page.id}} |
variables | 一个对象,包含为该页面通过Set Page Variable动作创建的所有变量。动态访问方式:{{page.variables.<pageVariableName>}},其中<pageVariableName>是使用 Set Page Variable 动作创建的变量名 |
实战:用页面变量做页面级状态隔离
page.variables的典型用途是页面级状态管理:通过 Set Page Variable 创建的变量仅存在于其所属页面作用域内,无法像普通(全局)变量那样在整个应用中访问(set-page-var.md)。这意味着你可以放心地在不同页面使用同名的局部变量,而不必担心互相覆盖。
一个完整的跨页面数据流转示例:
- 在"订单列表"页面的表格行按钮上添加On click事件,选择Switch Page动作,目标页面为
订单详情,并在 Query Params 中传入orderId = {{table1.selectedRow.id}}; - 在"订单详情"页面放置一个文本组件,将其 Text 属性设置为
Order #{{page.variables.orderId}}; - 在"订单详情"页面的On page load事件上添加Set Page Variable动作,key 为
orderId,value 引用{{page.variables.orderId}}或直接读取 URL 查询参数(如{{globals.urlparams.orderId}})。
这样,页面加载时会自动初始化页面级变量,后续在同一页面内的查询、组件与条件逻辑都可以通过{{page.variables.*}}引用,实现整洁的页面级状态传递。
小结与最佳实践
- 多页面组织:利用 Pages Panel 的
+快速创建页面,配合拖拽排序(源码中reorderPages会持久化每个页面的index与分组,pageMenuSlice.js),将复杂业务拆分为多个职责单一的页面。 - URL 与导航语义:
handle决定页面 URL,name决定显示名称,两者解耦——请为 handle 选择简短、稳定、对 SEO 友好的 slug;重命名页面不会破坏已对外发布的链接。 - 首页与访问控制:通过Mark Home控制默认落地页;用Hide隐藏次要页面(仍可通过 Switch Page/URL 直达),用Disable彻底关闭某页面的访问。
- 页面事件与变量:在On page load事件上挂接页面动作完成初始化;用Set/Unset Page Variable管理页面级状态,用Switch Page + Query Params在页面间传递上下文数据。
通过以上能力,你可以在单个 ToolJet 应用中构建从登录页、仪表盘到业务表单的完整多页面工作流,让内部工具与应用既清晰易导航,又保持页面间数据的高效流转。
【免费下载链接】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),仅供参考