Compare commits

...

155 Commits

Author SHA1 Message Date
roymondchen
7a161cab00 refactor(editor): 历史记录数据源/代码块 tab 复用通用 BucketTab 2026-06-02 19:07:38 +08:00
roymondchen
1cd69b33fe feat(editor): 对比表单支持自定义 loadConfig 加载逻辑
将 CompareCategory 等类型抽取到 type.ts,
新增 CompareFormLoadConfig 支持外部接管表单配置加载,
HistoryDiffDialog 透传 loadConfig 并支持 width 配置及对外导出。
2026-06-02 17:03:27 +08:00
roymondchen
12069e0937 feat(form): submitForm 支持返回 changeRecords
新增 returnChangeRecords 选项,开启后 resolve { values, changeRecords },
便于命令式调用时获取表单变更记录,并同步更新文档与单测。
2026-06-02 16:43:07 +08:00
roymondchen
1b66ab1b88 refactor(editor): 抽取 serializeConfig 工具统一序列化配置
将分散在 CodeLink、CodeEditor 及 playground 中重复的 serialize-javascript
序列化逻辑收敛为 @editor/utils/editor 的 serializeConfig 并对外导出复用。
2026-06-02 16:34:23 +08:00
roymondchen
64d35d5363 fix(form): 对比模式下无 name 字段时不展示差异
避免 name 为空时拿整个 model/lastValues 做对比导致误判

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 16:28:08 +08:00
roymondchen
35fc394199 feat(form): fieldset legend 支持函数动态生成标题 2026-06-02 14:24:09 +08:00
roymondchen
8612311db1 feat(editor): 历史记录面板支持自定义扩展 tab 并开放 Bucket/goto 配置
新增 historyListExtraTabs 配置,可在内置页面/数据源/代码块 tab 后追加业务自定义历史 tab。
导出 HistoryListBucket 供复用,GroupRow 支持配置是否允许跳转,Bucket 支持配置是否展示初始项。
2026-06-01 19:21:36 +08:00
roymondchen
818b41f07f chore: update lockfile v1.8.0-beta.2 2026-05-29 18:56:40 +08:00
roymondchen
9b34124805 chore: release v1.8.0-beta.2 2026-05-29 18:55:38 +08:00
roymondchen
7a61a35664 fix(editor): 显式标注 CompareForm 的 defineExpose 类型以修复 DTS 构建报错
defineExpose 同时暴露 MForm 实例 ref 与递归的 FormConfig ref,导致
vue-tsc 生成声明文件时推断类型过大无法序列化(TS7056)。改为显式标注
暴露类型,使其引用具名别名而非展开完整结构。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 18:53:08 +08:00
roymondchen
025cca365c perf(dep): 依赖收集改为单次遍历批量处理多 target
将 collectItems/removeTargetsDep 改为整棵树只遍历一次、在每个属性上检查所有
target,把结构遍历开销从 ×targets 降到 ×1,收集结果保持一致。

同时修正 dataSourceMethodDeps 字段命名并补充到 MApp schema。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 17:55:13 +08:00
roymondchen
a3333e2b4e feat(editor): 新增 hideSidebar 配置支持隐藏左侧面板
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 16:49:10 +08:00
roymondchen
cbc4b25072 feat(editor): 字段对比模式逐项展示差异并补充历史记录面板文档
- CodeSelect/CodeSelectCol/EventSelect/DataSource 等复合字段在对比模式下
  按索引对齐前后值,逐项展示新增/删除/修改高亮,并隐藏写操作按钮
- form 容器/列表/表格支持对比模式只读展示
- 新增「历史记录面板」指南文档,完善表单对比文档及 menu props 说明
- 补充相关单元测试

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 15:51:47 +08:00
roymondchen
b02aa75ddc feat(editor): 历史记录面板支持单步回滚(类 git revert)
将目标历史步骤的修改作为一次新操作反向应用,不破坏原有栈结构,
page/dataSource/codeBlock 三类 service 均提供 revert 能力;
面板新增关闭按钮、步骤编号展示与合并组卡片样式优化。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 14:19:44 +08:00
roymondchen
f0c66427b8 feat: form 新增 showDiff prop 支持自定义对比判断
- form: MForm/Container 新增 showDiff prop,允许调用方自定义

  '是否展示对比内容' 的判断逻辑,并在嵌套 Container 中自动透传;

  不传时沿用默认的 isEqual 行为

- editor: CompareForm 利用该能力处理 code-select 字段中 '' 与

  { hookType: 'code', hookData: [] } 两种语义为空形态被 isEqual 误判为差异的问题

- docs: 补充 form-props.md 中 showDiff 的说明与示例

- test: 补充 Code 字段相关单测
2026-05-28 20:30:05 +08:00
roymondchen
c854dfa8bf feat(editor): vs-code 字段对比模式改用 monaco diff 编辑器
- Container.vue 新增「自接管对比」字段类型白名单(当前含 vs-code),命中时只渲染一次组件并透传 model/lastValues/isCompare,由字段内部展示差异
- Code.vue 在 isCompare 模式下切换到 type='diff',使用 monaco 内置 diff 视图替代两个独立编辑器实例
- CodeEditor.vue 补充对 modifiedValues 的 watch,避免 diff 模式下右侧值停留在初始快照
2026-05-28 20:12:46 +08:00
roymondchen
59f4e0edac feat(editor): 历史记录面板支持差异对比
- 新增 HistoryDiffDialog 历史差异对比弹窗
- 新增 CompareForm 表单对比组件
- 抽取 code-block 工具函数到 utils/code-block.ts
- 历史列表面板支持选择两个版本进行对比
2026-05-28 19:49:03 +08:00
roymondchen
0f8abf7298 fix: 对比模式下关闭 tab-pane 的 lazy,确保差异数能正确统计 2026-05-28 19:32:54 +08:00
roymondchen
62a2ee6693 feat(editor): 历史记录面板支持点击跳转与回到初始状态
- 单步组头部点击跳转到该步骤;合并组头部点击展开/收起,子步行点击跳转到具体步骤
- 列表底部新增「初始」记录项,可一键回到所有修改之前的状态
- editorService/dataSourceService/codeBlockService 新增 goto API;historyService 暴露 cursor 读取器
2026-05-28 18:52:11 +08:00
roymondchen
0446202ba6 feat(editor): 新增历史记录列表面板
- 新增 history-list 模块(面板、Tab、Bucket、GroupRow 与 composables)
- NavMenu 接入历史记录面板入口
- history/editor/codeBlock/dataSource service 配合面板能力调整
- utils/undo-redo 适配新面板
- 扩展 type.ts 相关类型定义
- 新增 history-list-panel.scss 并在 theme.scss 引入
- 补充 history-list 模块完整单元测试
- playground 同步小幅调整
2026-05-28 17:51:52 +08:00
roymondchen
285434ef3e feat(form): 支持自定义 label slot
在 MForm / Container 上新增具名作用域插槽 label,允许使用方自定义表单项标题渲染。
Slot 作用域参数:config、type、text、prop、disabled。
类型 FormLabelSlotProps / FormSlots 提取到 schema.ts 复用。
2026-05-28 16:45:11 +08:00
roymondchen
8dae67769c feat(editor): 数据源与代码块 service 支持 undo/redo
- dataSourceService / codeBlockService 新增 undo / redo / canUndo / canRedo 方法
- undo/redo 内部复用 add / update / remove / setCodeDslByIdSync / deleteCodeDslByIds 写回,
  并强制 doNotPushHistory,借此自动驱动 initService 中的依赖收集链路
  (DepTargetType.DATA_SOURCE / DATA_SOURCE_COND / DATA_SOURCE_METHOD / CODE_BLOCK)
- 更新场景下若 step 带 changeRecords,按 propPath 局部 patch,不冲掉同节点其它无关变更;
  缺省退化为整 schema / 整内容替换
- 补充对应单测与 API 文档
2026-05-28 16:40:49 +08:00
roymondchen
09558fa027 feat(editor): 历史记录接入 changeRecords,undo/redo 按 propPath 局部更新
- 节点 / 数据源 / 代码块的 history step 增加 changeRecords 字段

- editor.update / dataSource.update / codeBlock.setCodeDslById(Sync) 透传 changeRecords 入历史

- applyHistoryOp 的 update 分支:携带 changeRecords 时,按 propPath 从 oldNode/newNode 取值

  构造最小 patch 走 update,不冲掉同节点上其它无关变更;缺省退化为整节点替换

  (覆盖 sort/moveLayer/拖动等纯快照场景)

- editor.update 增加 changeRecordList 形参,多节点场景每个节点单独保留 records;

  use-stage 多选拖动 / 缩放改用 changeRecordList,避免 records 在多节点间共享

- use-code-block-edit.submitCodeBlockHandler 透传 form changeRecords

- 同步更新 editor / dataSource / codeBlock / history service 文档
2026-05-28 16:28:35 +08:00
roymondchen
4c855ba50b feat(editor): 写操作支持 doNotPushHistory 选项以跳过历史记录
- editor/codeBlock/dataSource 的 add/update/delete 等接口新增 doNotPushHistory 选项
- 移除不再使用的 editor-history 工具及其单测
- 修复 layer 节点状态在重建时丢失已有 status 的问题
- 同步更新 service 方法文档,新增 dragto 复现用例
2026-05-28 16:03:29 +08:00
roymondchen
e2c065f90d feat(editor): 代码块与数据源支持按 id 独立的历史记录
- history service 新增 pushCodeBlock/undoCodeBlock/redoCodeBlock
  /canUndoCodeBlock/canRedoCodeBlock 及数据源对称 API
- 按 id 维度各自维护独立 UndoRedo 栈,与页面/节点历史完全解耦
- type 新增 CodeBlockStepValue / DataSourceStepValue 独立类型
- HistoryState 扩展 codeBlockState / dataSourceState 字段
- codeBlockService.setCodeDslByIdSync / deleteCodeDslByIds 自动入历史
- dataSourceService.add / update / remove 自动入历史
- 入栈成功时 emit code-block-history-change / data-source-history-change
- 补充单测共 21 例,更新 history/codeBlock/dataSource 相关文档
2026-05-27 19:50:17 +08:00
roymondchen
a341c7d73e fix(editor): 多选时对多个节点的操作合并入同一条历史记录
- moveToContainer 支持数组形参,多选移动整批只产生一条历史记录

- use-stage 拖动多选元素入容器 / 多选拖动缩放整批合成一次调用

- 右键移动至改走 moveToContainer,避免 remove+add 切成两条历史

- 跳过选中目标节点的分支清理 state.nodes 残留旧引用

- history.push 新增可选 pageId 参数,跨页操作正确落到目标页栈

- pushOpHistory 显式按 step.data.id 入栈,避免跨页操作错配
2026-05-27 19:09:34 +08:00
roymondchen
de94a75803 refactor(editor): 移除 BaseService 废弃的 use/middleware 机制
- 删除已 @deprecated 的 BaseService.use 方法及其 middleware 通道

- 删除 utils/compose.ts 及对应测试(仅服务于 middleware,无其他引用)

- editor.ts 移除 safeOptions/safeParent 兜底,相关方法 options 改用形参默认值

- props.ts fillConfig 的 labelWidth 改为形参默认值,移除 typeof function 兜底

- 同步更新 5 份 service 方法文档,删除 ## use 章节
2026-05-27 18:55:38 +08:00
roymondchen
d01a28ce76 fix(editor): 修复移动到菜单导致节点引用异常的问题 2026-05-27 17:17:43 +08:00
roymondchen
6c40425d8c chore: update lockfile v1.8.0-beta.1 2026-05-27 11:28:31 +08:00
roymondchen
b8b0490260 chore: release v1.8.0-beta.1 2026-05-27 11:27:14 +08:00
roymondchen
2846f9eb2a fix(core): app.emit 在节点配置事件时不应短路 super.emit
去掉 eventHelper.emit 前的 return,避免节点配置 events 后 app.on 注册的监听器被吞掉,并补充回归测试。
2026-05-27 11:20:48 +08:00
roymondchen
62fc818ae1 refactor(form-schema): style-setter 继承 containercommonconfig 2026-05-26 21:10:22 +08:00
roymondchen
ff810d09e4 feat(editor): 数据源字段选择按钮在对比模式与禁用态下禁止切换
- 按钮新增 disabled 绑定 (props.disabled || mForm?.isCompare)

- 抽取 onToggleDataSourceFieldSelectHandler 增加 guard 防御

- 补充对应单元测试
2026-05-26 21:05:01 +08:00
roymondchen
b1193b909e feat(editor): 样式设置器 StyleSetter 支持表单对比模式
- Index.vue 透传 lastValues/isCompare 给各分类子组件,并冒泡 addDiffCount

- pro 下 6 个分类组件接受新 props 并向 MContainer 传递

- Layout/Border 同时将新 props 传递给内部 Box/Border 组件

- components/Border.vue 接受新 props 并冒泡 MContainer 的 addDiffCount

- components/Box.vue 接受 props 以保持接口一致

- 补充单元测试覆盖透传与事件冒泡
2026-05-26 20:59:43 +08:00
roymondchen
540a2716d8 fix(editor): serializeConfig 只去掉对象 key 的引号,避免破坏字符串 value 内的引号 2026-05-26 20:20:51 +08:00
roymondchen
a1fcb191d2 feat(eslint-config): 禁止匿名 default class/function 导出
新增 no-restricted-syntax 规则,禁止匿名形式的
`export default class {}` 与 `export default function () {}`。

匿名 default 导出在 dts 聚合(rolldown / api-extractor /
vue-tsc 等)时会被命名为 `export_default`,导致跨包继承链在
.vue / .tsx 下解析失败,父类成员(如 EventEmitter 的 on/off)
无法被 ts-plugin 推断。

同时重申 base.mjs 中已有的 ForIn / Labeled / With 选择器,
避免在 .ts/.tsx 下被本规则整体覆盖。
2026-05-26 17:09:37 +08:00
roymondchen
b9a6dd5b84 fix(editor): 修复 root 整体替换时图层面板节点状态残留与组件树闪烁问题 2026-05-26 17:06:45 +08:00
roymondchen
08011efd6d refactor(form): 使用 getter 访问 props 字段并补充单元测试
- formState 中与 props 对应的字段改用 getter,避免 props 与 formState 之间的同步中间态
- 完善 extendState 同步段的响应式追踪说明注释
- 新增 Form.extra.spec.ts 覆盖 isCompare 模式与 config 变化场景
2026-05-26 11:51:34 +08:00
roymondchen
fbbd05e291 chore: update lockfile v1.8.0-beta.0 2026-05-22 16:54:18 +08:00
roymondchen
9b65917371 chore: release v1.8.0-beta.0 2026-05-22 16:53:17 +08:00
roymondchen
3d038513e3 feat(editor): 新增 DSL 修改方法的 doNotSwitchPage 选项
在 add / remove / doRemove / sort / paste / alignCenter / moveToContainer
的 options 对象中新增 doNotSwitchPage,与 doNotSelect 合并为同一配置 DslOpOptions,
用于在 DSL 操作(新增 / 删除 / 跨页移动)会引发当前页面切换时跳过该次切换。

- 抽取共用类型 DslOpOptions 到 type.ts 并对外导出
- 新增 editorService.isOnDifferentPage 辅助方法用于跨页判断
- 修复 doUpdate 同步 state.page 时无条件覆盖的问题:只在被更新页就是当前页时才同步引用,避免「更新非当前页」误把编辑器切到该页
- doRemove 中对已删除节点的引用清理与当前页清空逻辑提升为无条件执行,避免 doNotSelect / doNotSwitchPage 跳过后续 select 时 state 持有已删除节点
- 补充对应单元测试与 API 文档

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 16:49:52 +08:00
roymondchen
eb1c5a3ec1 fix(editor): 属性面板 padding 仅作用于最外层表单
为 PropsPanel 顶层 MForm 增加 .m-editor-props-form-panel-form 专属类名,
将原本挂在通用 .tmagic-design-form 上的 padding 与 tab 样式迁移到该类,
避免子组件中嵌套的 .tmagic-design-form 被错误命中。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 15:57:13 +08:00
roymondchen
7ff590b1b6 chore: update lockfile v1.7.14-beta.3 2026-05-21 16:11:51 +08:00
roymondchen
7eeb9b544e chore: release v1.7.14-beta.3 2026-05-21 16:10:48 +08:00
roymondchen
638c3e9f3c feat(form): 新增 submitForm 命令式提交函数
提供脱离组件树以函数方式完成一次表单校验/提交的能力,类似 ElMessage 用法:
传入 config/initValues 等 props 后内部临时挂载 Form 实例,
初始化完成即调用 submitForm,校验通过 resolve 表单值、失败 reject,
最后自动卸载,并支持 appContext 继承、timeout 与 native 透传。

同步补充单元测试、API 文档及侧边栏入口。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 15:55:28 +08:00
roymondchen
2d31b3812f feat(form): 容器组件新增 extendState 属性
FormBox、FormDialog、FormDrawer 新增 extendState 属性,并透传给内部 MForm,
方便外层注入 $message、$store 等扩展上下文到 formState。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 14:58:43 +08:00
roymondchen
05e512b1fe feat(editor): 新增 DSL 修改方法的 doNotSelect 选项
- add/remove/sort/alignCenter/moveToContainer/paste 新增 doNotSelect 选项,控制操作后是否自动触发选中变化
- doUpdate/doRemove 改为始终同步当前选中列表中的节点引用,避免 state 持有已被替换/已删除的过期节点
- 顺手修复 doUpdate 在 splice(-1) 时误改最后一个选中项的 bug
- 移除 update/doUpdate 的 selectedAfterUpdate 参数(语义已内化),move 不再暴露无意义的 doNotSelect
- 新增 safeOptions / safeParent 辅助函数,兜底插件机制将 dispatch 注入到形参位置的场景

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 17:20:04 +08:00
roymondchen
1e69bc221d refactor(utils): 放宽 isPop/isPage/isPageFragment 入参为仅需 type 字段
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 16:25:42 +08:00
roymondchen
12ce19fb02 fix(form): 修复table-group-list中model属性可能为undefined导致的报错 2026-05-18 20:07:49 +08:00
roymondchen
aa2ee9fd4b fix(form): select 在 model 值变化时补拉 init 选项
配置 config.option 时监听 model 字段变化,若当前 options 缺少对应项则重新 getInitOption,并补充单测覆盖。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 17:49:21 +08:00
roymondchen
f00e84793d chore: update lockfile v1.7.14-beta.2 2026-05-18 13:36:06 +08:00
roymondchen
297e5cebb0 chore: release v1.7.14-beta.2 2026-05-18 13:35:04 +08:00
roymondchen
5ba2019d0b chore: 更新pnpm 2026-05-18 13:17:57 +08:00
roymondchen
c45df6f6ec build: 优化test性能 2026-05-18 12:49:04 +08:00
roymondchen
f1aedc4ce7 fix(editor): 修复 CodeEditor setValue 时滚动位置与折叠等视图状态丢失
使用 saveViewState/restoreViewState 替代 getPosition/setPosition,并放到
nextTick 中执行,避免被 setAutoHeight 的 setScrollTop(0) 覆盖,导致光标
位置变化时编辑器滚动跳回顶部。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 12:09:45 +08:00
roymondchen
873a51fc87 docs: 升级 VitePress 至 v2 alpha,类型引用改为源码片段同步
- 升级 vitepress 到 ^2.0.0-alpha.17
- vite.optimizeDeps.rolldownOptions.transform.define 迁移至 vite.define 以适配 v2 API
- 同步升级 vitest/rolldown/vue/vite 等周边依赖
- 文档中类型链接统一改为 <<< 片段引用源码 region,避免 commit hash 链接失效
- packages/{core,editor,form-schema,schema,stage} 相关类型加 // #region 锚点
- 移除已废弃的 docs/guide/advanced/tmagic-ui.md 及侧栏入口

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 11:47:03 +08:00
roymondchen
d16ab9a805 docs: 重写快速开始与 runtime 指南,与 playground/runtime 源码对齐
快速开始:
- 补充 admin-client / runtime 项目结构说明
- 完善 UI adapter(element-plus / tdesign-vue-next)说明
- 增加 Monaco worker 注入与常见报错处理
- 重写 m-editor 完整示例,对齐 playground 源码

runtime 指南:
- 完善 tmagic.config.ts 与 .tmagic 入口产物说明
- 拆分 playground / page 双入口实现细节
- 新增 vite 多入口构建、跨域方案
- 补充 @tmagic/vue-runtime-help 常用 Hook 表格

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 19:40:49 +08:00
roymondchen
df8790042f feat(editor): 导航菜单支持菜单项溢出收纳,新增 NavMenuColumn 组件
- 抽离每列渲染逻辑为 NavMenuColumn 组件,监听容器宽度
- 容器空间不足时自动隐藏溢出项,并通过更多按钮 Popover 展开
- ToolButton 暴露根元素引用,便于父级测量宽度
- design ButtonProps 新增 bg 属性,用于更多按钮的激活态样式
- 补充 NavMenuColumn / NavMenu / ToolButton 的单元测试

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 19:33:53 +08:00
roymondchen
e64d86660d fix(form): 修复 Select 在 value 为空时仍发起 initUrl 请求的问题
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 19:32:04 +08:00
roymondchen
0efd23d6ab chore: update lockfile v1.7.14-beta.1 2026-05-14 19:38:24 +08:00
roymondchen
f13f94ca2d chore: release v1.7.14-beta.1 2026-05-14 19:37:22 +08:00
roymondchen
54a5570419 feat(form): 支持 TextConfig handler 返回 Promise,buttonClickHandler 改为 async await
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 19:32:19 +08:00
roymondchen
2ad5101471 fix(editor): 修复 StyleSetter 嵌套场景下 propPath 丢失上下文路径的问题
当 prop 与 name 不一致(如 data.items.0.style)时,原实现固定使用 name 会丢失上下文路径,
改为优先使用 prop,回退到 name,确保 changeRecords 携带完整路径。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 19:17:48 +08:00
roymondchen
ab6918f43d test: 完善测试用例 2026-05-14 15:26:22 +08:00
roymondchen
258617536d chore: update lockfile v1.7.14-beta.0 2026-05-11 17:06:57 +08:00
roymondchen
fd770f76f1 chore: release v1.7.14-beta.0 2026-05-11 17:05:46 +08:00
roymondchen
49428c57bc chore: update deps 2026-05-11 17:01:42 +08:00
roymondchen
aab73249d1 feat(editor): 新增 alwaysMultiSelect 配置开启常驻多选模式
新增编辑器配置项 alwaysMultiSelect(默认 false),开启后无需按住 Ctrl/Meta
键,组件树与画布点击即多选;当 disabledMultiSelect=true 时本配置失效。同步
在 stage 层 ActionManager 暴露 setAlwaysMultiSelect 方法用于运行时切换,并
补充组件树/服务/画布的状态联动、文档与单元测试。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 16:50:40 +08:00
roymondchen
2475a4f901 feat(editor): 新增"已选组件"面板节点双击事件 layer-node-dblclick 与 beforeLayerNodeDblclick 钩子
- TreeNode/Tree 增加 node-dblclick 事件透传
- LayerPanel 默认双击切换可展开节点的展开/收起状态,并向上抛出 node-dblclick
- Sidebar/Editor 暴露 layer-node-dblclick 事件与 beforeLayerNodeDblclick 拦截钩子
- 补充 props/events 文档

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-09 16:52:15 +08:00
roymondchen
5af9f6e27a feat(editor): 新增 canDropIn 配置统一控制 layer/stage 拖拽放入行为
支持通过 scene 区分图层树、画布拖动、组件库新增三种场景;
返回 false 阻止放入,返回 Id 可重定向放入目标节点。
layer 场景下若禁用某节点的 inner,其子节点的 before/after 也会被同步禁用以避免被绕过。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-09 16:38:10 +08:00
roymondchen
d8133629b4 feat(editor): props 服务新增配置/值的批量获取与存在性判断方法
新增 getPropsConfigs、hasPropsConfig、getPropsValues、hasPropsValue 方法,便于外部按类型查询表单配置与初始值。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-08 19:57:06 +08:00
roymondchen
a1f71f02d1 chore: update lockfile v1.7.13-beta.0 2026-05-08 17:48:31 +08:00
roymondchen
29026be6a0 chore: release v1.7.13-beta.0 2026-05-08 17:47:16 +08:00
roymondchen
7ce640627d feat(editor): 新增 stage-top 插槽用于在画布上方插入自定义元素
ScrollViewer 增加 before 具名插槽,Stage 据此暴露 stage-top 插槽,
经 Workspace、Editor 逐层透传,并补充对应类型定义与文档说明。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 20:31:25 +08:00
roymondchen
7b870e5908 feat(editor): 面包屑超出父容器 80% 时折叠中间项并对单项打点
- 路径过长时仅保留首项 + ... + 末两项,避免横向溢出工作区
- 单项设置 max-width 并通过内部 span 显示省略号,悬浮 tooltip 展示完整名称
- 通过 ResizeObserver 监听父容器宽度变化实时重测

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 19:20:46 +08:00
roymondchen
0724c76689 test: 补齐 schema/form-schema/table 包测试并扩充 utils/stage/core 用例
- schema/form-schema/table 三个此前无测试的包补齐基础用例
- utils 扩充 dom helpers、compiledCond、getDefaultValueFromFields 等边界场景
- stage 补充常量/枚举与 selected class、getTargetElStyle 等工具用例
- core 新增 utils(style2Obj/transformStyle/getTransform)、Env、Store、FlowState、Page 用例

测试文件总数 43 -> 51, 用例数 419 -> 559。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 18:54:48 +08:00
roymondchen
c9cef3e20c fix(form): form-dialog save 时浅拷贝 changeRecords 避免引用被污染
直接传递 form.changeRecords 引用会导致 emit('submit') 后表单内部继续修改时影响外部使用方,改为浅拷贝。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 17:34:52 +08:00
roymondchen
3eb8cc0614 docs: 完善 editor/form/runtime/stage 等 API 文档参数与说明
补全方法的参数类型、返回值类型与详情说明,规范字段编辑器/字段配置/运行时 API 等文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 17:33:58 +08:00
roymondchen
a520626ef6 feat(editor): getPropsConfig 支持传入 node 参数并修正 CondOpSelectConfig 类型
- props service 的 getPropsConfig 增加可选 data 参数以传递当前节点信息
- 修正 CondOpSelectConfig 的 type 字段为 'cond-op-select'

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 16:24:17 +08:00
roymondchen
3cde69f6f9 feat(editor): 支持自定义组件树节点是否可展开的判断函数
新增 layerNodeIsExpandable 配置项,业务方可自定义"已选组件"面板中
节点是否显示为可展开形态。同时导出默认实现 defaultIsExpandable 与
类型 IsExpandableFunction 供第三方复用。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 13:53:51 +08:00
roymondchen
cce8b63fc3 chore: update lockfile v1.7.13 2026-04-29 15:53:10 +08:00
roymondchen
bd0c5a7514 chore: release v1.7.13 2026-04-29 15:52:06 +08:00
roymondchen
96801e2ccb fix(core): getTransform 支持 string 类型并适配 hippy
Made-with: Cursor
2026-04-29 15:38:17 +08:00
roymondchen
26efa75ff2 feat(editor): update 支持 selectedAfterUpdate 参数控制是否更新 nodes
Made-with: Cursor
2026-04-28 15:50:03 +08:00
roymondchen
59716e909b chore(vue-runtime-help): release v2.0.3
useEditorDsl 返回 root 以便外部访问根节点

Made-with: Cursor
2026-04-24 16:23:11 +08:00
roymondchen
4a102c1277 chore: update lockfile v1.7.12 2026-04-24 15:50:13 +08:00
roymondchen
94e58342e5 chore: release v1.7.12 2026-04-24 15:48:55 +08:00
roymondchen
3c41091f96 refactor(form): 重构 table/group-list 目录结构与新增行逻辑
- 将 table 相关文件迁移至 containers/table 与 containers/table-group-list 目录
- 将新增行处理统一上移至 TableGroupList,通过 add 事件触发
- 抽取 TableGroupListCommonConfig 公共配置类型
- useFullscreen 内聚管理 zIndex
- TableColumnConfig 支持 text 作为 label 别名

Made-with: Cursor
2026-04-24 15:45:15 +08:00
roymondchen
b5af91f86c chore: update lock 2026-04-23 20:52:39 +08:00
roymondchen
540d9cd5bb chore(vue-runtime-help): release v2.0.2 2026-04-23 20:50:21 +08:00
roymondchen
407572ee3a chore: release v1.7.11 2026-04-23 20:41:21 +08:00
roymondchen
d7ad63d3a2 refactor(form): 调整 table-group-list 属性透传与切换按钮控制方式
- TableGroupList 新增 showIndex、sortKey、sort 属性透传至 Table
- 切换按钮显示改由 config.enableToggleMode 或组件 prop 控制,Table 不再内置 enableToggleMode
- GroupList 新增 showIndex 属性
- DisplayConds 关闭切换模式
- GroupListConfig.beforeAddRow 返回值去掉 Promise 支持

Made-with: Cursor
2026-04-23 20:38:56 +08:00
roymondchen
4cd54d1397 feat(table): 支持列排序配置
- design: TableColumnOptions.sortable 支持 boolean | string
- table: 将 sortable 传递到表格列配置

Made-with: Cursor
2026-04-23 20:04:44 +08:00
roymondchen
7249b5106e fix(form): group-list lastValues 为空时兼容取值报错
Made-with: Cursor
2026-04-23 19:45:43 +08:00
roymondchen
9ba12e97af fix(form): table 全屏每次进入重新获取 z-index
close #672

Made-with: Cursor
2026-04-23 17:19:52 +08:00
roymondchen
e106c081c8 feat(editor): 样式面板布局分组新增透明度配置
closes #675

Made-with: Cursor
2026-04-23 17:08:51 +08:00
roymondchen
9f21f8f1d5 refactor(form): 抽出 TableGroupList 父组件统一管理 Table/GroupList 切换
- 新增 TableGroupList 父组件集中持有 displayMode 状态并派生两种形态的
  config,避免原实现通过直接改写 props.config 来触发视图切换
- 将公共的 toggle/add 按钮上移到 TableGroupList,Table/GroupList 通过
  具名 slot + scoped slot 暴露位置与业务钩子(newHandler/addHandler)
- m-form-table、m-form-group-list 统一注册为 TableGroupList,对外导出
  的 MTable/MGroupList 也指向它,新增 MTableGroupList 显式导出
- useAdd 移除重复的 addable 计算,由父组件统一管理

Made-with: Cursor
2026-04-23 17:03:04 +08:00
roymondchen
b46b571214 feat(editor): 没有参考线时不显示参考线切换按钮
Made-with: Cursor
2026-04-23 15:42:10 +08:00
roymondchen
6a4a4ed122 fix(vue-runtime-help): 删除所有页面后,新增页面出错
fix #668
2026-04-23 15:33:19 +08:00
roymondchen
63698af00a chore: update deps 2026-04-23 15:13:37 +08:00
roymondchen
ac755ac3d0 feat(form): group-list 支持 max 限制和 beforeAddRow 前置校验
- group-list 新增 max 配置项,限制最大行数
- group-list 支持 beforeAddRow 异步前置校验回调
- table 的 beforeAddRow 支持返回 Promise

Made-with: Cursor
2026-04-23 15:06:45 +08:00
EvanWu
9bf42f9007 docs: 更新 README.md 环境要求
更新 Node.js 和 pnpm 版本要求,与 package.json engines 和 packageManager 保持一致。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 11:24:53 +08:00
roymondchen
3875ccde33 build: 升级 vite@8.0.8 并修复 rolldown UMD Symbol.toStringTag 遮蔽问题
- 升级 vite 至 ^8.0.8(catalog 及 lockfile 同步)
- 在 scripts/build.mjs 中新增 fixUmdSymbolShadow 插件,将 UMD 产物中
  `Object.defineProperty(exports, Symbol.toStringTag, ...)` 替换为
  `globalThis.Symbol.toStringTag`,规避 lodash-es 内联 `var Symbol` 声明
  因变量提升遮蔽全局 Symbol 导致运行时报错的问题

Made-with: Cursor
2026-04-17 15:20:28 +08:00
roymondchen
62a488ac66 chore: update lockfile v1.7.10 2026-04-13 20:39:20 +08:00
roymondchen
27bb886054 chore: release v1.7.10 2026-04-13 20:30:30 +08:00
roymondchen
fa09ab0b30 feat(editor): 样式配置添加变形项 2026-04-13 20:04:23 +08:00
roymondchen
31f4d2b4e2 fix(editor): 数据源方法选择器展示所有数据源并支持字段非叶子节点选择
移除 methodsOptions 中过滤无自定义方法数据源的逻辑,因为所有数据源都有内置"设置数据"方法;字段选择增加 checkStrictly 支持选择非叶子节点

Made-with: Cursor
2026-04-09 15:32:35 +08:00
roymondchen
b2888962df style(schema,editor,data-source): 代码块类型定义中content去掉string类型 2026-04-09 15:28:03 +08:00
roymondchen
b3f4e42716 feat(stage): 支持将指定id的dom生成图片 2026-04-09 15:05:41 +08:00
roymondchen
6e07d5762b chore(eslint-config): release 0.1.0 2026-04-09 12:15:05 +08:00
roymondchen
cfd5998242 fix(stage): 新增组件后等待渲染完后选中 2026-04-09 12:03:36 +08:00
roymondchen
26dc70d70c fix(editor): 历史记录信息中添加页面信息 2026-04-08 17:19:15 +08:00
roymondchen
99c8274a1e fix(editor): 修复 getTMagicAppPrimise 变量名拼写错误
Made-with: Cursor
2026-04-07 20:30:39 +08:00
roymondchen
334569e2d7 feat(editor): 添加 stage beforeDblclick 钩子,支持拦截默认双击行为
在 StageOptions 和 EditorProps 中新增 beforeDblclick 配置项,
该函数返回 false 或 Promise<false> 时将阻止 stage 默认的双击处理逻辑。

Made-with: Cursor
2026-04-07 19:19:00 +08:00
roymondchen
f583c7daec feat(editor,data-source): 数据源支持内置"设置数据"方法
支持通过事件调用数据源的 setData 方法,可以选择数据源字段并根据字段类型动态设置数据;
重构 CodeParams 参数配置支持动态类型; DataSourceFieldSelect 支持指定数据源ID;
常量抽取到 utils/const.ts

Made-with: Cursor
2026-04-07 18:25:35 +08:00
roymondchen
172a7a1c92 feat(editor,stage): 支持双击穿透选中鼠标下方的下一个可选中元素
将 dblclick 处理统一到 Stage.vue,新增 ActionManager.getNextElementFromPoint
方法跳过最上层元素返回下方第二个可选中元素,双击时若无特殊处理则穿透选中下方组件。

Made-with: Cursor
2026-04-07 18:25:35 +08:00
roymondchen
73c676931f build: 更新ts@10 2026-04-07 18:25:35 +08:00
roymondchen
df2d635682 fix(editor): 优化 StageOverlay 双击行为,仅在元素被滚动容器裁剪时打开 overlay
双击页面片容器时直接选中对应页面片;新增 isClippedByScrollContainer
判断元素是否被非页面级滚动容器裁剪,避免不必要的 overlay 弹出。

Made-with: Cursor
2026-04-07 18:25:35 +08:00
roymondchen
0c2f2fd2b5 refactor(editor): 拆分 editor service,提取工具函数减少文件行数
将 services/editor.ts 从 1335 行精简到 1075 行,提取以下内容:

- 新增 utils/editor-history.ts:历史操作处理函数(add/remove/update)
- utils/editor.ts 新增:resolveSelectedNode、toggleFixedPosition、
  calcMoveStyle、calcAlignCenterStyle、calcLayerTargetIndex、
  editorNodeMergeCustomizer、collectRelatedNodes、classifyDragSources
- type.ts 新增:EditorEvents、canUsePluginMethods、AsyncMethodName
- 补充完整的单元测试覆盖所有新增工具函数

Made-with: Cursor
2026-04-07 18:25:35 +08:00
oceanzhu
a7274198bf docs: add AGENTS.md for AI navigation 2026-04-07 10:13:37 +08:00
Linzsong
6f2e8d8d74 fix(stage): 修复隐藏标尺后无法显示问题 2026-03-27 15:35:01 +08:00
roymondchen
637a5bb69a refactor(editor): 历史记录改成记录操作而不是记录副本 2026-03-27 15:27:41 +08:00
roymondchen
42e7ac1b2e chore: update lockfile v1.7.9 2026-03-23 15:32:49 +08:00
roymondchen
a3cdad9d91 chore: release v1.7.9 2026-03-23 15:31:42 +08:00
roymondchen
711af79d72 fix(form): row容器中如果配置没有type显示异常 2026-03-23 15:23:41 +08:00
roymondchen
728fbc035c chore: update lockfile v1.7.8 2026-03-20 19:44:45 +08:00
roymondchen
01795455e9 chore: release v1.7.8 2026-03-20 19:43:37 +08:00
roymondchen
9b56223359 fix(editor): 组件配置样式显示出错 2026-03-20 19:41:18 +08:00
roymondchen
984cea7ca3 chore: update lockfile v1.7.8-beta.4 2026-03-20 18:54:57 +08:00
roymondchen
9921ed8a2d chore: release v1.7.8-beta.4 2026-03-20 18:53:49 +08:00
roymondchen
e36d8d7cf8 fix(form-schema): 表单 schema 中 display 与 component 部分字段改为可选
Made-with: Cursor
2026-03-20 18:45:19 +08:00
roymondchen
35aa81514b chore: update lockfile v1.7.8-beta.3 2026-03-20 17:41:38 +08:00
roymondchen
450376872e chore: release v1.7.8-beta.3 2026-03-20 17:40:26 +08:00
roymondchen
e8714c96c9 feat(form-schema,form,editor,table): 完善表单配置类型 2026-03-20 17:38:11 +08:00
roymondchen
feefd3779e chore: update lockfile v1.7.8-beta.2 2026-03-20 12:36:12 +08:00
roymondchen
1ae023db8c chore: release v1.7.8-beta.2 2026-03-20 12:34:50 +08:00
roymondchen
55eb546ad6 feat(form-schema,form,editor): 完善表单配置类型 2026-03-20 12:31:55 +08:00
roymondchen
1664559d8f refactor(dep): 优化性能 2026-03-19 16:02:41 +08:00
roymondchen
a34d0cdccc build: 构建的类型文件中别名没有消除 2026-03-19 15:53:01 +08:00
roymondchen
210ac436fc chore: update lockfile v1.7.8-beta.1 2026-03-19 12:10:29 +08:00
roymondchen
64c8ed15ab chore: release v1.7.8-beta.1 2026-03-19 12:09:15 +08:00
roymondchen
bada79e519 fix: GitHub Pages 默认使用 Jekyll 处理站点文件,而 Jekyll 会忽略所有以下划线开头的文件和目录 2026-03-19 12:00:50 +08:00
roymondchen
06a6068c47 build: 优化type check性能 2026-03-19 11:47:08 +08:00
roymondchen
58281a345b chore(playground): 删除多样代码 2026-03-19 11:36:11 +08:00
roymondchen
0bbafa153d fix(core,data-source): 多个页面片容器引用同一个页面片时,其他有未渲染的页面片容器时会导致数据源编译后数据无法更新 2026-03-19 11:34:51 +08:00
roymondchen
f6bd647958 test(editor): 更新monaco-editor依赖 2026-03-18 20:27:09 +08:00
roymondchen
c79034befc feat(editor,form): 支持按需设置表单组件 2026-03-18 20:19:05 +08:00
roymondchen
88e6c7d377 build: es产物不要合并文件,保证能够tree-shaking 2026-03-18 19:19:29 +08:00
moonszhang
92bd5cf942 feat(core): runDataSourceMethod 返回 await 方法的执行结果 2026-03-18 09:15:01 +00:00
roymondchen
5ae667b7ee chore: update eslint 10 2026-03-17 20:03:45 +08:00
roymondchen
18bfbefaf2 chore: 更新版权协议 2026-03-17 17:31:43 +08:00
roymondchen
1b9492165c build: playground构建忽略lightningcss错误 2026-03-17 17:30:26 +08:00
roymondchen
61f00a0fb7 chore(editor): 完善类型检验 2026-03-17 16:57:28 +08:00
roymondchen
6d91a7a844 chore: 更新vite 2026-03-17 16:52:46 +08:00
roymondchen
3e4d49dd45 chore: update pnpm 2026-03-17 15:52:53 +08:00
471 changed files with 46925 additions and 8607 deletions

View File

@ -41,6 +41,9 @@ jobs:
- name: move to dist - name: move to dist
run: mv docs/.vitepress/dist/* dist/docs && mv playground/dist/* dist/playground run: mv docs/.vitepress/dist/* dist/docs && mv playground/dist/* dist/playground
- name: Bypass Jekyll on GitHub Pages
run: touch dist/.nojekyll
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
uses: crazy-max/ghaction-github-pages@v2 uses: crazy-max/ghaction-github-pages@v2
with: with:

View File

@ -1 +1 @@
npm test npm run test

56
AGENTS.md Normal file
View File

@ -0,0 +1,56 @@
# AGENTS.md — TMagic编辑器
> 魔方平台可视化编辑器核心,提供拖拽式活动页面编辑能力。
> 负责人roymondchen | 创建2026-04-03
## 项目概述
TMagic Editor 是魔方平台的可视化编辑器核心库,提供拖拽式组件编辑、配置面板、预览发布等能力。支持 Vue 和 React 双框架 Runtime采用 pnpm monorepo 管理多个核心包。开源项目,同时支持内部业务定制。
**技术栈:** Vue 3, Element Plus, TypeScript, Vite, vitest, VitePress
**主仓库:** `https://git.woa.com/vft-magic/tmagic-editor.git`
**开源仓库:** `https://github.com/Tencent/tmagic-editor.git`
## 架构地图
关键目录:
- `packages/` — 核心编辑器包202 *.vue, 194 *.ts
- `runtime/` — Vue/React Runtime 实现
- `vue-components/` — Vue 组件封装
- `react-components/` — React 组件封装
- `playground/` — 演示 playground
- `docs/` — VitePress 文档100 *.md
- `scripts/` — 构建和发布脚本
- `eslint-config/` — 共享 ESLint 配置
## 开发约定
**分支策略:** dev=dev, test/prod=master
**提交规范:** commitlint + husky`type: 描述`
**禁止事项:**
- 禁止在核心包中引入腾讯内部专有依赖(开源项目)
- 禁止直接修改 CHANGELOG.md应通过 `pnpm changelog` 生成
## 常用命令
pnpm bootstrap # 安装依赖并构建
pnpm pg # 启动 Vue playground
pnpm pg:react # 启动 React playground
pnpm build # 完整构建DTS + 包)
pnpm test # 运行测试
pnpm lint-fix # ESLint 修复
pnpm docs:dev # 启动文档开发
pnpm release # 发版
## 当前状态
**当前里程碑:** {待人工填写}
## 深入阅读
| 文档 | 说明 |
|------|------|
| docs/ | VitePress 文档站 |
| CONTRIBUTING.md | 贡献指南 |
| CHANGELOG.md | 变更日志 |

File diff suppressed because it is too large Load Diff

477
LICENSE
View File

@ -74,15 +74,6 @@ Open Source Software Licensed under the Apache License Version 2.0:
1. typescript 1. typescript
Copyright (c) Microsoft Corporation. All rights reserved. Copyright (c) Microsoft Corporation. All rights reserved.
2. log4js
Copyright 2015 Gareth Jones (with contributions from many other people)
3. reflect-metadata
Copyright (c) Microsoft Corporation. All rights reserved.
4. xlsx
Copyright (C) 2013-present SheetJS
Terms of the Apache License Version 2.0: Terms of the Apache License Version 2.0:
-------------------------------------------------------------------- --------------------------------------------------------------------
@ -355,8 +346,8 @@ Open Source Software Licensed under the BSD 2-Clause License:
1. @typescript-eslint/parser 1. @typescript-eslint/parser
Copyright JS Foundation and other contributors, https://js.foundation Copyright JS Foundation and other contributors, https://js.foundation
2. uglify-js 2. terser
Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com> Copyright 2012-2018 (c) Mihai Bazon <mihai.bazon@gmail.com>
Terms of the BSD 2-Clause License: Terms of the BSD 2-Clause License:
@ -390,8 +381,8 @@ Open Source Software Licensed under the BSD 3-Clause License:
Copyright 2014 Yahoo! Inc. Copyright 2014 Yahoo! Inc.
All rights reserved. All rights reserved.
2. serialize-javascript 2. highlight.js
Copyright 2014 Yahoo! Inc. Copyright (c) 2006, Ivan Sagalaev.
All rights reserved. All rights reserved.
@ -411,11 +402,14 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Open Source Software Licensed under the ISC License: Open Source Software Licensed under the ISC License:
-------------------------------------------------------------------- --------------------------------------------------------------------
1. raiz 1. c8
Copyright raiz original authour and authors Copyright (c) 2017, Contributors
2. axios-jsonp 2. picocolors
Copyright (c) Adonis Copyright (c) 2021 Alexey Raspopov, Kostiantyn Denysov, Anton Verinov
3. semver
Copyright (c) Isaac Z. Schlueter and Contributors
Terms of the ISC License: Terms of the ISC License:
@ -428,232 +422,239 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE
Open Source Software Licensed under the MIT License: Open Source Software Licensed under the MIT License:
-------------------------------------------------------------------- --------------------------------------------------------------------
1. events 1. @commitlint/cli
Copyright Joyent, Inc. and other Node contributors.
2. vite-plugin-dts
Copyright (c) 2021-present qmhc
3. color
Copyright (c) 2012 Heather Arthur
4. element-plus
Copyright element-plus original authour and authors
5. @types/node
Copyright (c) Microsoft TypeScript, DefinitelyTyped, Alberto Schiabel, Alvis HT Tang, Andrew Makarov, Benjamin Toueg, Chigozirim C., David Junger, Deividas Bakanas, Eugene Y. Q. Shen, Hannes Magnusson, Hoàng Văn Khải, Huw, Kelvin Jin, Klaus Meinhardt, Lishude, Mariusz Wiktorczyk, Mohsen Azimi, Nicolas Even, Nikita Galkin, Parambir Singh, Sebastian Silbermann, Simon Schick, Thomas den Hollander, Wilco Bakker, wwwy3y3, Zane Hannan AU, Samuel Ainsworth, Kyle Uehlein, Thanik Bhongbhibhat, Marcin Kopacz, Trivikram Kamat, Junxiao Shi, Ilia Baryshnikov, and ExE Boss.
6. vue
Copyright (c) 2018-present, Yuxi (Evan) You
7. @vitejs/plugin-vue
Copyright (c) 2019-present, Yuxi (Evan) You and contributors
8. @vitejs/plugin-vue-jsx
Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
9. @vue/compiler-sfc
Copyright (c) 2018-present, Yuxi (Evan) You
10. @vue/test-utils
Copyright (c) 2021-present vuejs
11. sass
Copyright (c) 2016, Google Inc.
12. vue-tsc
Copyright (c) 2021-present Johnson Chu
13. moment
Copyright (c) JS Foundation and other contributors
14. sortablejs
Copyright (c) 2019 All contributors to Sortable
15. @scena/guides
Copyright (c) 2019 Daybrush
16. moveable
Copyright (c) 2019 Daybrush
17. delegate
Copyright (c) Zeno Rocha
18. tiny-emitter
Copyright (c) 2017 Scott Corgan
19. @testing-library/vue
Copyright (c) 2018 Daniel Cook
Copyright (c) 2017 Kent C. Dodds
20. react
Copyright (c) Facebook, Inc. and its affiliates.
21. react-dom
Copyright (c) Facebook, Inc. and its affiliates.
22. vue
Copyright (c) 2013-present, Yuxi (Evan) You
23. @vue/composition-api
Copyright (c) 2019-present, liximomo(X.L)
24. vite-plugin-vue2
Copyright © underfin
25. vue-template-compiler
Copyright (c)-present, Yuxi (Evan) You
26. rollup-plugin-external-globals
Copyright (c) 2018 eight
27. recast
Copyright (c) 2012 Ben Newman <bn@cs.stanford.edu>
28. @babel/preset-env
Copyright (c) 2014-present Sebastian McKenzie and other contributors
29. @vitejs/plugin-react-refresh
Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
30. @commitlint/cli
Copyright (c) 2016 - present Mario Nebl Copyright (c) 2016 - present Mario Nebl
31. @commitlint/config-conventional 2. @commitlint/config-conventional
Copyright (c) 2016 - present Mario Nebl Copyright (c) 2016 - present Mario Nebl
32. @typescript-eslint/eslint-plugin 3. @element-plus/icons-vue
Copyright (c) element-plus contributors
4. @eslint/js
Copyright OpenJS Foundation and other contributors
5. @popperjs/core
Copyright (c) 2019 Federico Zivolo
6. @scena/guides
Copyright (c) 2019 Daybrush
7. @stylistic/eslint-plugin
Copyright (c) Anthony Fu
8. @types/events
Copyright (c) Microsoft Corporation.
9. @types/fs-extra
Copyright (c) Microsoft Corporation.
10. @types/lodash-es
Copyright (c) Microsoft Corporation.
11. @types/node
Copyright (c) Microsoft Corporation.
12. @types/qrcode
Copyright (c) Microsoft Corporation.
13. @types/react
Copyright (c) Microsoft Corporation.
14. @types/react-dom
Copyright (c) Microsoft Corporation.
15. @types/serialize-javascript
Copyright (c) Microsoft Corporation.
16. @types/sortablejs
Copyright (c) Microsoft Corporation.
17. @typescript-eslint/eslint-plugin
Copyright (c) 2019 TypeScript ESLint and other contributors Copyright (c) 2019 TypeScript ESLint and other contributors
33. @vue/cli-plugin-babel 18. @vitejs/plugin-legacy
Copyright (c) 2017-present, Yuxi (Evan) You Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
34. @vue/cli-plugin-unit-jest 19. @vitejs/plugin-react-refresh
Copyright (c) 2017-present, Yuxi (Evan) You Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
35. babel-eslint 20. @vitejs/plugin-vue
Copyright (c) 2014-2016 Sebastian McKenzie <sebmck@gmail.com> Copyright (c) 2019-present, Yuxi (Evan) You and contributors
36. cz-conventional-changelog 21. @vitejs/plugin-vue-jsx
Copyright (c) 2015-2018 Commitizen Contributors Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
37. eslint 22. @vitest/coverage-v8
Copyright JS Foundation and other contributors, https://js.foundation Copyright (c) 2021-present, Anthony Fu and Vitest contributors
38. eslint-plugin-import 23. @vue/compiler-sfc
Copyright (c) 2015 Ben Mosher Copyright (c) 2018-present, Yuxi (Evan) You
39. eslint-plugin-prettier 24. @vue/test-utils
Copyright © 2017 Andres Suarez and Teddy Katz Copyright (c) 2021-present vuejs
40. eslint-plugin-simple-import-sort 25. axios
Copyright (c) 2018, 2019, 2020 Simon Lydell
41. eslint-plugin-vue
Copyright (c) 2017 Toru Nagashima
42. husky
Copyright (c) 2021 typicode
43. lerna
Copyright (c) 2015-present Lerna Contributors
44. lint-staged
Copyright (c) 2016 Andrey Okonetchnikov
45. prettier
Copyright © James Long and contributors
46. vue-jest
Copyright (c) 2017 Edd Yerburgh
47. axios
Copyright (c) 2014-present Matt Zabriskie Copyright (c) 2014-present Matt Zabriskie
48. core-js 26. buffer
Copyright (c) 2014-2021 Denis Pushkarev Copyright (c) Feross Aboukhadijeh, and other contributors
49. js-cookie 27. cac
Copyright (c) 2018 Copyright 2018 Klaus Hartl, Fagner Brack, GitHub Contributors Copyright (c) egoist <0x142857@gmail.com>
50. vue-router 28. chokidar
Copyright (c) 2020 Eduardo San Martin Morote Copyright (c) Paul Miller (https://paulmillr.com)
51. koa 29. commitizen
Copyright (c) 2019 Koa contributors Copyright (c) 2015 Jim Cummins
52. koa-bodyparser 30. conventional-changelog-cli
Copyright (c) 2014 dead_horse Copyright (c) Steve Mao
53. koa-router 31. cosmiconfig
Copyright (c) 2015 Alexander C. Mingoia Copyright (c) 2015 David Clark
54. koa-send 32. cz-conventional-changelog
Copyright (c) 2020 Koa contributors Copyright (c) 2015-2018 Commitizen Contributors
55. module-alias 33. dayjs
Copyright (c) 2018, Nick Gavrilov Copyright (c) 2018-present, iamkun
56. mysql2 34. deep-object-diff
Copyright (c) 2016 Andrey Sidorov (sidorares@yandex.ru) and contributors Copyright (c) 2017 Matt Phillips
57. sequelize 35. deep-state-observer
Copyright (c) 2014-present Sequelize contributors Copyright (c) neuronet.io
58. sequelize-typescript 36. element-plus
Copyright (c) 2017 Robin Buschmann Copyright element-plus original authour and authors
59. lodash 37. emmet-monaco-es
Copyright OpenJS Foundation and other contributors <https://openjsf.org/> Copyright (c) Troy
60. jest 38. enquirer
Copyright (c) Facebook, Inc. and its affiliates. Copyright (c) 2016-present, Jon Schlinkert
61. fs-extra 39. esbuild
Copyright (c) 2020 Evan Wallace
40. eslint
Copyright JS Foundation and other contributors, https://js.foundation
41. eslint-config-prettier
Copyright (c) 2017 Simon Lydell
42. eslint-plugin-import
Copyright (c) 2015 Ben Mosher
43. eslint-plugin-prettier
Copyright © 2017 Andres Suarez and Teddy Katz
44. eslint-plugin-simple-import-sort
Copyright (c) 2018, 2019, 2020 Simon Lydell
45. eslint-plugin-vue
Copyright (c) 2017 Toru Nagashima
46. events
Copyright Joyent, Inc. and other Node contributors.
47. execa
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com>
48. fs-extra
Copyright (c) 2011-2017 JP Richardson Copyright (c) 2011-2017 JP Richardson
62. moment-timezone 49. gesto
Copyright (c) JS Foundation and other contributors Copyright (c) 2019 Daybrush
63. nodemon 50. globals
Copyright (C) Remy Sharp Copyright (c) Sindre Sorhus <sindresorhus@gmail.com>
64. ts-node 51. husky
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) Copyright (c) 2021 typicode
65. tsconfig-paths 52. jsdom
Copyright (c) 2016 Jonas Kello Copyright (c) 2010 Elijah Insua
66. prettier 53. keycon
Copyright © James Long and contributors Copyright (c) 2019 Daybrush
67. @babel/core 54. lint-staged
Copyright (c) 2014-present Sebastian McKenzie and other contributors Copyright (c) 2016 Andrey Okonetchnikov
68. @babel/preset-typescript 55. merge-options
Copyright (c) 2014-present Sebastian McKenzie and other contributors Copyright (c) Michael Mayer
69. @types/fs-extra 56. minimist
Copyright (c) Microsoft Corporation. Copyright (c) James Halliday
70. @types/jest 57. monaco-editor
Copyright (c) Microsoft Corporation.
71. @types/koa
Copyright (C) DavidCai1993, jKey Lu, Brice Bernard, harryparkdotio, Wooram Jun, Christian Vaagland Tellnes, Piotr Kuczynski, and vnoder.
72. @types/koa-bodyparser
Copyright (C) Jerry Chin, Anup Kishore, Hiroshi Ioka, Alexi Maschas, and Pirasis Leelatanon.
73. zepto
Copyright (c) 2010-2016 Thomas Fuchs
http://zeptojs.com/
74. monaco-editor
Copyright (c) 2016 - present Microsoft Corporation Copyright (c) 2016 - present Microsoft Corporation
75. @types/koa-router 58. moveable
Copyright (C) Jerry Chin, Pavel Ivanov, JounQin, Romain Faust, Guillaume Mayer, Andrea Gueugnaut, and Yves Kaufmann. Copyright (c) 2019 Daybrush
59. moveable-helper
Copyright (c) 2019 Daybrush
60. prettier
Copyright © James Long and contributors
61. qrcode
Copyright (c) Ryan Day
62. react
Copyright (c) Facebook, Inc. and its affiliates.
63. react-dom
Copyright (c) Facebook, Inc. and its affiliates.
64. recast
Copyright (c) 2012 Ben Newman <bn@cs.stanford.edu>
65. rolldown
Copyright (c) 2023-present Rolldown contributors
66. rolldown-plugin-dts
Copyright (c) Kevin Deng
67. sass-embedded
Copyright (c) 2019 Google Inc.
68. scenejs
Copyright (c) 2019 Daybrush
69. shx
Copyright (c) ShellJS contributors
70. sortablejs
Copyright (c) 2019 All contributors to Sortable
71. tdesign-vue-next
Copyright (c) Tencent
72. typescript-eslint
Copyright (c) 2019 TypeScript ESLint and other contributors
73. vite-plugin-commonjs
Copyright (c) vite-plugin contributors
74. vitepress
Copyright (c) 2019-present, Yuxi (Evan) You
75. vitest
Copyright (c) 2021-present, Anthony Fu and Vitest contributors
76. vue
Copyright (c) 2018-present, Yuxi (Evan) You
77. vue-router
Copyright (c) 2020 Eduardo San Martin Morote
78. vue-tsc
Copyright (c) 2021-present Johnson Chu
Terms of the MIT License: Terms of the MIT License:
@ -5430,3 +5431,73 @@ Repository: github:eemeli/yaml
> TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF > TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
> THIS SOFTWARE. > THIS SOFTWARE.
Open Source Software Licensed under the Zero-Clause BSD License (0BSD):
--------------------------------------------------------------------
1. tslib
Copyright (c) Microsoft Corp.
Terms of the Zero-Clause BSD License (0BSD):
--------------------------------------------------------------------
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Open Source Software Licensed under the Blue Oak Model License 1.0.0:
--------------------------------------------------------------------
1. rimraf
Copyright (c) Isaac Z. Schlueter and Contributors
Terms of the Blue Oak Model License 1.0.0:
--------------------------------------------------------------------
Blue Oak Model License
Version 1.0.0
Purpose
This license gives everyone as much permission to work with this software as possible, while protecting contributors from liability.
Acceptance
In order to receive this license, you must agree to its rules. The rules of this license are both obligations under that agreement and conditions to your license. You must not do anything with this software that triggers a rule that you cannot or will not follow.
Copyright
Each contributor licenses you to do everything with this software that would otherwise infringe that contributor's copyright in it.
Notices
You must ensure that everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license or a link to https://blueoakcouncil.org/license/1.0.0.
Excuse
If anyone notifies you in writing that you have not complied with Notices, you can keep your license by taking all practical steps to comply within 30 days after the notice. If you do not do so, your license ends immediately.
Patent
Each contributor licenses you to do everything with this software that would otherwise infringe any patent claims they can license or become able to license.
Reliability
No contributor can revoke this license.
No Liability
As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim.
Open Source Software Licensed under the (MIT OR CC0-1.0) License:
--------------------------------------------------------------------
1. type-fest
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
A copy of the MIT License is included in this file.

View File

@ -16,9 +16,9 @@ https://tencent.github.io/tmagic-editor/playground/index.html
## 环境准备 ## 环境准备
node.js >= 18 node.js ^20.19.0 || >=22.12.0
pnpm >= 9 pnpm >= 10
先安装 pnpm 先安装 pnpm

View File

@ -103,9 +103,10 @@ export default defineConfig({
link: '/guide/advanced/data-source.md' link: '/guide/advanced/data-source.md'
}, },
{ {
text: '@tmagic/ui', text: '历史记录面板',
link: '/guide/advanced/tmagic-ui.md', link: '/guide/advanced/history-list.md',
}, },
{ {
text: '@tmagic/form', text: '@tmagic/form',
link: '/guide/advanced/tmagic-form.md', link: '/guide/advanced/tmagic-form.md',
@ -253,6 +254,15 @@ export default defineConfig({
}, },
] ]
}, },
{
text: '工具函数',
items: [
{
text: 'submitForm',
link: '/api/form/submit-form'
},
]
},
], ],
}, },
{ {
@ -551,13 +561,9 @@ export default defineConfig({
}, },
vite: { vite: {
optimizeDeps: {
esbuildOptions: {
define: { define: {
global: 'globalThis', global: 'globalThis',
}, },
},
},
resolve: { resolve: {
alias:[ alias:[
{ find: /^@tmagic\/form-schema/, replacement: path.join(__dirname, '../../packages/form-schema/src/index.ts') }, { find: /^@tmagic\/form-schema/, replacement: path.join(__dirname, '../../packages/form-schema/src/index.ts') },

View File

@ -189,6 +189,8 @@
import hljs from 'highlight.js'; import hljs from 'highlight.js';
import serialize from 'serialize-javascript'; import serialize from 'serialize-javascript';
import { MForm } from '@tmagic/form';
export function stripScript(content) { export function stripScript(content) {
const result = content.match(/<(script)>([\s\S]+)<\/\1>/); const result = content.match(/<(script)>([\s\S]+)<\/\1>/);
return result && result[2] ? result[2].trim() : ''; return result && result[2] ? result[2].trim() : '';
@ -210,6 +212,10 @@ export function stripTemplate(content) {
export default { export default {
props: ['type', 'config'], props: ['type', 'config'],
components: {
MForm,
},
data() { data() {
return { return {
codepen: { codepen: {

View File

@ -1,364 +1,388 @@
# codeBlockService方法 # codeBlockService方法
## setCodeDsl ## setCodeDsl
- **参数:** - **参数:**
- {`CodeBlockDSL`} codeDsl 代码块DSL
- ::: details 查看 CodeBlockDSL 及关联类型定义
<<< @/../packages/schema/src/index.ts#CodeBlockDSL{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockContent{ts}
<<< @/../packages/schema/src/index.ts#CodeParam{ts}
:::
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
设置活动的代码块dsl数据源并触发 `code-dsl-change` 事件
## getCodeDsl ## getCodeDsl
- **参数:**
-
- **返回:** - **返回:**
- {`CodeBlockDSL` | null}
- `{Promise<void>}`
- **详情:** - **详情:**
获取活动的代码块dsl数据源默认从dsl中的codeBlocks字段读取
## getCodeContentById ## getCodeContentById
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string | number}` id 代码块id
-
- **返回:** - **返回:**
- {`CodeBlockContent` | null}
- `{Promise<void>}`
- **详情:** - **详情:**
根据代码块id获取代码块内容
## setCodeDslById ## setCodeDslById
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string | number}` id 代码块id
- {Partial<`CodeBlockContent`>} codeConfig 代码块内容配置信息
- `{Object}` options 可选配置
- {`ChangeRecord`[]} changeRecords form 端变更记录,用于历史记录的精细化撤销/重做
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- ::: details 查看 ChangeRecord 类型定义
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
设置代码块ID和代码内容到源dsl强制写入底层调用 [setCodeDslByIdSync](#setcodedslbyidsync)
## setCodeDslByIdSync
- **参数:**
- `{string | number}` id 代码块id
- {Partial<`CodeBlockContent`>} codeConfig 代码块内容配置信息
- `{boolean}` force 是否强制写入,默认 `true`;为 `false` 时若同 id 已存在则跳过
- `{Object}` options 可选配置
- {`ChangeRecord`[]} changeRecords form 端变更记录,用于历史记录的精细化撤销/重做
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:**
- `{void}`
- **详情:**
同步版本的 [setCodeDslById](#setcodedslbyid),并会触发 `addOrUpdate` 事件
::: tip
写入成功时(`force=false` 且同 id 已存在的跳过场景除外)会自动调用 `historyService.pushCodeBlock`
把本次变更入历史栈,参见 [historyService.pushCodeBlock](./historyServiceMethods.md#pushcodeblock)。
传入的 `changeRecords` 会一同写进 step撤销/重做时调用方可据此按 `propPath` 局部回放。
传入 `doNotPushHistory: true` 可跳过写入历史栈,常用于批量导入、外部同步等非用户操作场景。
:::
## getCodeDslByIds ## getCodeDslByIds
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string[]}` ids 代码块id数组
-
- **返回:** - **返回:**
- {`CodeBlockDSL`} 命中的代码块dsl
- `{Promise<void>}`
- **详情:** - **详情:**
## setCodeEditorShowStatus 根据代码块id数组获取代码dsl
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## getCodeEditorShowStatus
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## setCodeEditorContent
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## getCurrentDsl
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## getEditStatus ## getEditStatus
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **返回:**
- `{boolean}` 是否可编辑
- **详情:**
获取当前编辑状态
## setEditStatus ## setEditStatus
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## setId
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## getId
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## getMode
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{boolean}` status 是否可编辑
-
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
## setMode 设置代码块编辑状态
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## setCombineIds ## setCombineIds
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string[]}` ids 代码块id数组
-
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
设置当前选中组件已关联绑定的代码块id数组
## getCombineIds ## getCombineIds
- **参数:**
-
- **返回:** - **返回:**
- `{string[]}` 代码块id数组
- `{Promise<void>}`
- **详情:** - **详情:**
## refreshAllRelations 获取当前选中组件已关联绑定的代码块id数组
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## getCombineInfo
- **参数:**
-
- **返回:**
- `{Promise<void>}`
- **详情:**
## getUndeletableList ## getUndeletableList
- **参数:**
-
- **返回:** - **返回:**
- `{(string | number)[]}` 代码块id数组
- `{Promise<void>}`
- **详情:** - **详情:**
获取不可删除列表
## setUndeleteableList ## setUndeleteableList
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{(string | number)[]}` codeIds 代码块id数组
-
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
设置不可删除列表:为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除)
## setCodeDraft ## setCodeDraft
- **参数:** - **参数:**
- `{string | number}` codeId 代码块id
- - `{string}` content 代码草稿内容
- **返回:** - **返回:**
- `{void}`
- `{Promise<void>}`
- **详情:** - **详情:**
将代码草稿写入 localStorage
## getCodeDraft ## getCodeDraft
- **参数:** - **参数:**
- `{string | number}` codeId 代码块id
-
- **返回:** - **返回:**
- `{string | null}` 代码草稿内容
- `{Promise<void>}`
- **详情:** - **详情:**
从 localStorage 读取代码草稿
## removeCodeDraft ## removeCodeDraft
- **参数:** - **参数:**
- `{string | number}` codeId 代码块id
-
- **返回:** - **返回:**
- `{void}`
- `{Promise<void>}`
- **详情:** - **详情:**
删除 localStorage 中的代码草稿
## deleteCodeDslByIds ## deleteCodeDslByIds
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{(string | number)[]}` codeIds 需要删除的代码块id数组
- - `{Object}` options 可选配置
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
在dsl数据源中删除指定id的代码块每删除一个会触发一次 `remove` 事件
::: tip
对每个实际存在并被删除的代码块,会自动调用 `historyService.pushCodeBlock` 入栈一条
`newContent=null` 的删除记录;不存在的 id 不会入历史。传入 `doNotPushHistory: true` 也可显式跳过写入历史栈。
:::
## undo
- **参数:**
- `{Id}` id 代码块id
- **返回:**
- `{Promise<CodeBlockStepValue | null>}` 撤销的 step栈不存在或已无可撤销时返回 `null`
- **详情:**
撤销指定代码块的最近一次变更。内部根据 [historyService](./historyServiceMethods.md) 取出 step 后,
复用 [setCodeDslByIdSync](#setcodedslbyidsync) / [deleteCodeDslByIds](#deletecodedslbyids) 写回,
并自动带上 `doNotPushHistory: true`,确保不会再次入栈。
写回会触发对应的 `addOrUpdate` / `remove` 事件,编辑器内部据此重新维护
`DepTargetType.CODE_BLOCK` 的 dep target无需调用方额外处理。
对于带有 `changeRecords` 的更新 step会按 `propPath` 局部 patch 当前代码块内容;缺省才退化为整内容替换,
避免冲掉同代码块上的其它无关变更。
- **示例:**
```js
import { codeBlockService } from "@tmagic/editor";
if (codeBlockService.canUndo("code_1234")) {
await codeBlockService.undo("code_1234");
}
```
## redo
- **参数:**
- `{Id}` id 代码块id
- **返回:**
- `{Promise<CodeBlockStepValue | null>}` 重做的 step栈不存在或已无可重做时返回 `null`
- **详情:**
重做指定代码块的下一次变更。其它行为同 [undo](#undo)。
## canUndo
- **参数:**
- `{Id}` id 代码块id
- **返回:**
- `{boolean}`
- **详情:**
当前指定代码块是否可撤销,等价于 `historyService.canUndoCodeBlock(id)`
## canRedo
- **参数:**
- `{Id}` id 代码块id
- **返回:**
- `{boolean}`
- **详情:**
当前指定代码块是否可重做,等价于 `historyService.canRedoCodeBlock(id)`
## setParamsColConfig
- **参数:**
- `{TableColumnConfig}` config 参数列配置
- **返回:**
- `{void}`
- **详情:**
设置代码块入参表格列配置
## getParamsColConfig
- **返回:**
- `{TableColumnConfig | undefined}` 参数列配置
- **详情:**
获取代码块入参表格列配置
## getUniqueId ## getUniqueId
- **参数:**
-
- **返回:** - **返回:**
- `{Promise<string>}` 代码块唯一id
- `{Promise<void>}`
- **详情:** - **详情:**
## deleteCompsInRelation 生成代码块唯一id格式为 `code_xxxx`与已有id冲突时会递归重试
## copyWithRelated
- **参数:** - **参数:**
- {`MNode` | `MNode`[]} config 组件节点配置
- `{TargetOptions}` collectorOptions 可选的依赖收集器配置
- ::: details 查看 MNode 及关联类型定义
<<< @/../packages/schema/src/index.ts#MNode{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#MContainer{ts}
<<< @/../packages/schema/src/index.ts#MIteratorContainer{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MApp{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
:::
- **返回:** - **返回:**
- `{void}`
- `{Promise<void>}`
- **详情:** - **详情:**
复制组件时会带上组件关联的代码块将关联的代码块dsl存储到 localStorage
## paste
- **返回:**
- `{void}`
- **详情:**
粘贴代码块。从 localStorage 读取已复制的代码块dsl并写入当前dsl已存在同id的代码块不会被覆盖
## resetState
- **返回:**
- `{void}`
- **详情:**
重置 codeBlockService 状态
## destroy ## destroy
- **参数:**
-
- **返回:** - **返回:**
- `{void}`
- `{Promise<void>}`
- **详情:** - **详情:**
## use 销毁 codeBlockService重置状态并移除所有事件监听和插件
使用中间件的方式扩展方法,上述方法中标记有`扩展支持: 是`的方法都支持使用use扩展
## usePlugin ## usePlugin
- **详情:** - **详情:**
相对于[use](#use), usePlugin支持更加灵活更加细致的扩展 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展 usePlugin支持灵活细致的扩展, 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展
每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值 每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值

View File

@ -4,7 +4,13 @@
- **参数:** - **参数:**
- {[ComponentGroup](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/editor/src/type.ts#L355)[]} componentGroupList 组件列表配置 - {`ComponentGroup`[]} componentGroupList 组件列表配置
::: details 查看 ComponentGroup 及关联类型定义
<<< @/../packages/editor/src/type.ts#ComponentGroup{ts}
<<< @/../packages/editor/src/type.ts#ComponentItem{ts}
:::
- **返回:** - **返回:**
@ -48,7 +54,7 @@ componentListService.setList([
- **返回:** - **返回:**
- {[ComponentGroup](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/editor/src/type.ts#L355)[]} 组件列表配置 - {`ComponentGroup`[]} 组件列表配置
- **详情:** - **详情:**
@ -102,3 +108,4 @@ import { componentListService } from '@tmagic/editor';
componentListService.destroy(); componentListService.destroy();
``` ```

View File

@ -3,11 +3,9 @@
## get ## get
- **参数:** - **参数:**
- `{StateKey}` name 状态键名 - `{StateKey}` name 状态键名
- **返回:** - **返回:**
- `{any}` 对应的状态值 - `{any}` 对应的状态值
- **详情:** - **详情:**
@ -26,21 +24,19 @@
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const dataSources = dataSourceService.get('dataSources'); const dataSources = dataSourceService.get("dataSources");
console.log(dataSources); console.log(dataSources);
``` ```
## set ## set
- **参数:** - **参数:**
- `{StateKey}` name 状态键名 - `{StateKey}` name 状态键名
- `{any}` value 状态值 - `{any}` value 状态值
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -50,9 +46,9 @@ console.log(dataSources);
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.set('editable', false); dataSourceService.set("editable", false);
``` ```
## getFormConfig ## getFormConfig
@ -60,12 +56,22 @@ dataSourceService.set('editable', false);
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型,默认为 'base' - `{string}` type 数据源类型,默认为 'base'
- **返回:** - **返回:**
- {`FormConfig`} 表单配置
- {[FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706)} 表单配置 ::: details 查看 FormConfig 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FormConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItemConfig{ts}
<<< @/../packages/form-schema/src/base.ts#ChildConfig{ts}
<<< @/../packages/form-schema/src/base.ts#DynamicTypeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
- **详情:** - **详情:**
@ -74,9 +80,9 @@ dataSourceService.set('editable', false);
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const config = dataSourceService.getFormConfig('http'); const config = dataSourceService.getFormConfig("http");
console.log(config); console.log(config);
``` ```
@ -85,12 +91,10 @@ console.log(config);
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型 - `{string}` type 数据源类型
- {[FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706)} config 表单配置 - {`FormConfig`} config 表单配置
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -100,21 +104,21 @@ console.log(config);
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.setFormConfig('http', [ dataSourceService.setFormConfig("http", [
{ {
name: 'url', name: "url",
text: '请求地址', text: "请求地址",
type: 'text', type: "text",
}, },
{ {
name: 'method', name: "method",
text: '请求方法', text: "请求方法",
type: 'select', type: "select",
options: [ options: [
{ text: 'GET', value: 'GET' }, { text: "GET", value: "GET" },
{ text: 'POST', value: 'POST' }, { text: "POST", value: "POST" },
], ],
}, },
]); ]);
@ -125,12 +129,26 @@ dataSourceService.setFormConfig('http', [
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型,默认为 'base' - `{string}` type 数据源类型,默认为 'base'
- **返回:** - **返回:**
- {Partial<`DataSourceSchema`>} 数据源默认值
- {Partial<[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221)>} 数据源默认值 ::: details 查看 DataSourceSchema 及关联类型定义
<<< @/../packages/schema/src/index.ts#DataSourceSchema{ts}
<<< @/../packages/schema/src/index.ts#DataSchema{ts}
<<< @/../packages/schema/src/index.ts#MockSchema{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockContent{ts}
<<< @/../packages/schema/src/index.ts#CodeParam{ts}
<<< @/../packages/schema/src/index.ts#EventConfig{ts}
<<< @/../packages/schema/src/index.ts#JsEngine{ts}
:::
- **详情:** - **详情:**
@ -139,9 +157,9 @@ dataSourceService.setFormConfig('http', [
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const defaultValue = dataSourceService.getFormValue('http'); const defaultValue = dataSourceService.getFormValue("http");
console.log(defaultValue); console.log(defaultValue);
``` ```
@ -150,12 +168,10 @@ console.log(defaultValue);
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型 - `{string}` type 数据源类型
- {Partial<[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221)>} value 数据源默认值 - {Partial<`DataSourceSchema`>} value 数据源默认值
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -165,12 +181,12 @@ console.log(defaultValue);
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.setFormValue('http', { dataSourceService.setFormValue("http", {
type: 'http', type: "http",
method: 'GET', method: "GET",
url: '', url: "",
}); });
``` ```
@ -179,12 +195,14 @@ dataSourceService.setFormValue('http', {
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型,默认为 'base' - `{string}` type 数据源类型,默认为 'base'
- **返回:** - **返回:**
- {`EventOption`[]} 事件列表
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} 事件列表 ::: details 查看 EventOption 类型定义
<<< @/../packages/core/src/utils.ts#EventOption{ts}
:::
- **详情:** - **详情:**
@ -193,9 +211,9 @@ dataSourceService.setFormValue('http', {
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const events = dataSourceService.getFormEvent('http'); const events = dataSourceService.getFormEvent("http");
console.log(events); console.log(events);
``` ```
@ -204,12 +222,10 @@ console.log(events);
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型 - `{string}` type 数据源类型
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} value 事件列表 - {`EventOption`[]} value 事件列表
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -219,11 +235,11 @@ console.log(events);
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.setFormEvent('http', [ dataSourceService.setFormEvent("http", [
{ label: '请求成功', value: 'success' }, { label: "请求成功", value: "success" },
{ label: '请求失败', value: 'error' }, { label: "请求失败", value: "error" },
]); ]);
``` ```
@ -232,12 +248,10 @@ dataSourceService.setFormEvent('http', [
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型,默认为 'base' - `{string}` type 数据源类型,默认为 'base'
- **返回:** - **返回:**
- {`EventOption`[]} 方法列表
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} 方法列表
- **详情:** - **详情:**
@ -246,9 +260,9 @@ dataSourceService.setFormEvent('http', [
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const methods = dataSourceService.getFormMethod('http'); const methods = dataSourceService.getFormMethod("http");
console.log(methods); console.log(methods);
``` ```
@ -257,12 +271,10 @@ console.log(methods);
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 数据源类型 - `{string}` type 数据源类型
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} value 方法列表 - {`EventOption`[]} value 方法列表
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -272,11 +284,11 @@ console.log(methods);
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.setFormMethod('http', [ dataSourceService.setFormMethod("http", [
{ label: '发起请求', value: 'request' }, { label: "发起请求", value: "request" },
{ label: '重试', value: 'retry' }, { label: "重试", value: "retry" },
]); ]);
``` ```
@ -285,27 +297,33 @@ dataSourceService.setFormMethod('http', [
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`DataSourceSchema`} config 数据源配置
- {[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221)} config 数据源配置 - `{Object}` options 可选配置
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- {`DataSourceSchema`} 添加后的数据源配置
- {[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221)} 添加后的数据源配置
- **详情:** - **详情:**
添加一个数据源如果配置中没有id或id已存在会自动生成新的id 添加一个数据源如果配置中没有id或id已存在会自动生成新的id
::: tip
添加成功会自动调用 `historyService.pushDataSource` 入栈一条 `oldSchema=null` 的新增记录,
参见 [historyService.pushDataSource](./historyServiceMethods.md#pushdatasource)。
传入 `doNotPushHistory: true` 可跳过写入历史栈,常用于批量导入、外部同步等非用户操作场景。
:::
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const newDs = dataSourceService.add({ const newDs = dataSourceService.add({
type: 'http', type: "http",
title: '用户信息', title: "用户信息",
url: '/api/user', url: "/api/user",
method: 'GET', method: "GET",
}); });
console.log(newDs.id); // 自动生成的id console.log(newDs.id); // 自动生成的id
@ -316,29 +334,38 @@ console.log(newDs.id); // 自动生成的id
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`DataSourceSchema`} config 数据源配置
- {[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221)} config 数据源配置
- `{Object}` options 可选配置 - `{Object}` options 可选配置
- {[ChangeRecord](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/form/src/schema.ts#L27-L39)[]} changeRecords 变更记录 - {`ChangeRecord`[]} changeRecords 变更记录
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
::: details 查看 ChangeRecord 类型定义
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
- **返回:** - **返回:**
- {`DataSourceSchema`} 更新后的数据源配置
- {[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221)} 更新后的数据源配置
- **详情:** - **详情:**
更新数据源 更新数据源
::: tip
更新成功会自动调用 `historyService.pushDataSource` 入栈一条 `oldSchema` / `newSchema`
均为对应 schema 的更新记录,传入的 `changeRecords` 也会一并写进 step撤销/重做时调用方可据此按
`propPath` 局部回放,缺省才退化为整 schema 替换。传入 `doNotPushHistory: true` 可跳过写入历史栈。
:::
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const updatedDs = dataSourceService.update({ const updatedDs = dataSourceService.update({
id: 'ds_123', id: "ds_123",
type: 'http', type: "http",
title: '用户详情', title: "用户详情",
url: '/api/user/detail', url: "/api/user/detail",
}); });
console.log(updatedDs); console.log(updatedDs);
@ -349,23 +376,28 @@ console.log(updatedDs);
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` id 数据源id - `{string}` id 数据源id
- `{Object}` options 可选配置
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
删除指定id的数据源 删除指定id的数据源
::: tip
对实际存在的数据源会自动调用 `historyService.pushDataSource` 入栈一条 `newSchema=null`
的删除记录;不存在的 id 不会入历史。传入 `doNotPushHistory: true` 也可显式跳过写入历史栈。
:::
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.remove('ds_123'); dataSourceService.remove("ds_123");
``` ```
## createId ## createId
@ -375,7 +407,6 @@ dataSourceService.remove('ds_123');
- **参数:** - **参数:**
- **返回:** - **返回:**
- `{string}` 生成的唯一id - `{string}` 生成的唯一id
- **详情:** - **详情:**
@ -385,7 +416,7 @@ dataSourceService.remove('ds_123');
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const id = dataSourceService.createId(); const id = dataSourceService.createId();
console.log(id); // 'ds_xxx-xxx-xxx' console.log(id); // 'ds_xxx-xxx-xxx'
@ -394,12 +425,10 @@ console.log(id); // 'ds_xxx-xxx-xxx'
## getDataSourceById ## getDataSourceById
- **参数:** - **参数:**
- `{string}` id 数据源id - `{string}` id 数据源id
- **返回:** - **返回:**
- {`DataSourceSchema` | undefined} 数据源配置
- {[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221) | undefined} 数据源配置
- **详情:** - **详情:**
@ -408,21 +437,101 @@ console.log(id); // 'ds_xxx-xxx-xxx'
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
const ds = dataSourceService.getDataSourceById('ds_123'); const ds = dataSourceService.getDataSourceById("ds_123");
console.log(ds); console.log(ds);
``` ```
## undo
- **参数:**
- `{Id}` id 数据源id
- **返回:**
- {`DataSourceStepValue` | null} 撤销的 step栈不存在或已无可撤销时返回 `null`
- **详情:**
撤销指定数据源的最近一次变更。内部根据 [historyService](./historyServiceMethods.md) 取出 step 后,
复用 [add](#add) / [update](#update) / [remove](#remove) 写回,并自动带上 `doNotPushHistory: true`
确保不会再次入栈。
写回会触发对应的 `add` / `update` / `remove` 事件,编辑器内部据此重新维护数据源相关的依赖收集
`DepTargetType.DATA_SOURCE` / `DATA_SOURCE_COND` / `DATA_SOURCE_METHOD`),无需调用方额外处理。
对于带有 `changeRecords` 的更新 step会按 `propPath` 局部 patch 当前数据源;缺省才退化为整 schema 替换,
避免冲掉同节点上的其它无关变更。
- **示例:**
```js
import { dataSourceService } from "@tmagic/editor";
if (dataSourceService.canUndo("ds_123")) {
dataSourceService.undo("ds_123");
}
```
## redo
- **参数:**
- `{Id}` id 数据源id
- **返回:**
- {`DataSourceStepValue` | null} 重做的 step栈不存在或已无可重做时返回 `null`
- **详情:**
重做指定数据源的下一次变更。其它行为同 [undo](#undo)。
## canUndo
- **参数:**
- `{Id}` id 数据源id
- **返回:**
- `{boolean}`
- **详情:**
当前指定数据源是否可撤销,等价于 `historyService.canUndoDataSource(id)`
## canRedo
- **参数:**
- `{Id}` id 数据源id
- **返回:**
- `{boolean}`
- **详情:**
当前指定数据源是否可重做,等价于 `historyService.canRedoDataSource(id)`
## copyWithRelated ## copyWithRelated
- **参数:** - **参数:**
- {`MNode` | `MNode`[]} config 组件节点配置
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]} config 组件节点配置
- `{TargetOptions}` collectorOptions 可选的收集器配置 - `{TargetOptions}` collectorOptions 可选的收集器配置
- **返回:** ::: details 查看 MNode 及关联类型定义
<<< @/../packages/schema/src/index.ts#MNode{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#MContainer{ts}
<<< @/../packages/schema/src/index.ts#MIteratorContainer{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MApp{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
:::
- **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -432,9 +541,9 @@ console.log(ds);
- **示例:** - **示例:**
```js ```js
import { dataSourceService, editorService } from '@tmagic/editor'; import { dataSourceService, editorService } from "@tmagic/editor";
const node = editorService.get('node'); const node = editorService.get("node");
dataSourceService.copyWithRelated(node); dataSourceService.copyWithRelated(node);
``` ```
@ -443,7 +552,6 @@ dataSourceService.copyWithRelated(node);
- **参数:** - **参数:**
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -455,7 +563,7 @@ dataSourceService.copyWithRelated(node);
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.paste(); dataSourceService.paste();
``` ```
@ -465,7 +573,6 @@ dataSourceService.paste();
- **参数:** - **参数:**
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -475,7 +582,7 @@ dataSourceService.paste();
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.resetState(); dataSourceService.resetState();
``` ```
@ -485,7 +592,6 @@ dataSourceService.resetState();
- **参数:** - **参数:**
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -495,7 +601,7 @@ dataSourceService.resetState();
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.destroy(); dataSourceService.destroy();
``` ```
@ -504,23 +610,23 @@ dataSourceService.destroy();
- **详情:** - **详情:**
相对于[use](#use), usePlugin支持更加灵活更加细致的扩展 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展 usePlugin支持更加灵活更加细致的扩展 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展
每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值 每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.usePlugin({ dataSourceService.usePlugin({
beforeAdd(config) { beforeAdd(config) {
console.log('添加前:', config); console.log("添加前:", config);
return [config]; return [config];
}, },
afterAdd(result, config) { afterAdd(result, config) {
console.log('添加后:', result); console.log("添加后:", result);
return result; return result;
}, },
}); });
@ -535,7 +641,8 @@ dataSourceService.usePlugin({
- **示例:** - **示例:**
```js ```js
import { dataSourceService } from '@tmagic/editor'; import { dataSourceService } from "@tmagic/editor";
dataSourceService.removeAllPlugins(); dataSourceService.removeAllPlugins();
``` ```

View File

@ -1,40 +1,89 @@
# editorService事件 # editorService事件
## root-change ## root-change
- **详情:** dsl跟节点发生变化[editorService.set('root', {})](./editorServiceMethods.md#set)后触发 - **详情:** dsl跟节点发生变化[editorService.set('root', {})](./editorServiceMethods.md#set)后触发
- **回调函数:** (value: [MApp](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/schema/src/index.ts?plain=1#L66-L73), preValue: [MApp](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/schema/src/index.ts?plain=1#L66-L73)) => void - **事件回调函数:** `(value: MApp, preValue?: MApp) => void`
::: details 查看 MApp 及关联类型定义
<<< @/../packages/schema/src/index.ts#MApp{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#NodeType{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockDSL{ts}
<<< @/../packages/schema/src/index.ts#DataSourceSchema{ts}
<<< @/../packages/schema/src/index.ts#DataSourceDeps{ts}
:::
## select ## select
- **详情:** 选中组件,[editorService.select()](./editorServiceMethods.md#select)后触发 - **详情:** 选中组件,[editorService.select()](./editorServiceMethods.md#select)后触发
- **回调函数:** (node: [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)) => void - **事件回调函数:** `(node: MNode) => void`
::: details 查看 MNode 及关联类型定义
<<< @/../packages/schema/src/index.ts#MNode{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#MContainer{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
:::
## add ## add
- **详情:** 选中组件,[editorService.add()](./editorServiceMethods.md#add)后触发 - **详情:** 添加节点后触发,[editorService.add()](./editorServiceMethods.md#add)后触发
- **回调函数:** (node: [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]) => void
- **事件回调函数:** `(node: MNode[]) => void`
## remove ## remove
- **详情:** 选中组件,[editorService.remove()](./editorServiceMethods.md#remove)后触发 - **详情:** 删除节点后触发,[editorService.remove()](./editorServiceMethods.md#remove)后触发
- **回调函数:** (node: [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]) => void
- **事件回调函数:** `(node: MNode[]) => void`
## update ## update
- **详情:** 选中组件[editorService.update()](./editorServiceMethods.md#update)后触发 - **详情:** 更新组件后触发[editorService.update()](./editorServiceMethods.md#update)后触发
- **回调函数:** (node: [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]) => void - **事件回调函数:** `(data: Array<{ newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] }>) => void`
::: details 查看 ChangeRecord 类型定义
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
## move-layer
- **详情:** 移动节点层级后触发,[editorService.moveLayer()](./editorServiceMethods.md#movelayer)后触发
- **事件回调函数:** `(offset: number | LayerOffset) => void`
其中 `LayerOffset` 枚举值为 `'top'` / `'bottom'`
## drag-to
- **详情:** 拖拽节点到指定容器后触发,[editorService.dragTo()](./editorServiceMethods.md#dragto)后触发
- **事件回调函数:** `(data: { targetIndex: number; configs: MNode | MNode[]; targetParent: MContainer }) => void`
::: details 查看 MContainer 类型定义
<<< @/../packages/schema/src/index.ts#MContainer{ts}
:::
## history-change ## history-change
- **详情:** 历史记录改变,[editorService.redo()editorService.undo()](./editorServiceMethods.html#undo)后触发
- **回调函数:** (node: [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)) => void - **详情:** 历史记录改变,[editorService.redo()editorService.undo()](./editorServiceMethods.md#undo)后触发
- **事件回调函数:** `(data: MPage | MPageFragment) => void`

View File

@ -3,11 +3,9 @@
## get ## get
- **参数:** - **参数:**
- `{'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength' | 'stage' | 'stageLoading' | 'disabledMultiSelect' | 'alwaysMultiSelect'} name`
- `{'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'modifiedNodeIds' | 'pageLength' | 'stage'} name`
- **返回:** - **返回:**
- `{any} value` - `{any} value`
- **详情:** - **详情:**
@ -30,19 +28,28 @@
'pageLength': 所以页面个数 'pageLength': 所以页面个数
'pageFragmentLength': 页面片个数
'stage': [StageCore](../stage/coreMethods.md)实例 'stage': [StageCore](../stage/coreMethods.md)实例
'stageLoading': 画布是否加载中
'disabledMultiSelect': 是否禁用多选
'alwaysMultiSelect': 是否始终启用多选模式(无需按住 Ctrl/Meta
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
const node = editorService.get('node'); const node = editorService.get("node");
``` ```
## set ## set
- `{'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'modifiedNodeIds' | 'pageLength' | 'stage'} name`
- `{any} value` - `{'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength' | 'stage' | 'stageLoading' | 'disabledMultiSelect' | 'alwaysMultiSelect'} name`
- `{any} value`
- **详情:** - **详情:**
参考[get](#get)方法 参考[get](#get)方法
@ -50,23 +57,20 @@ const node = editorService.get('node');
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
const node = editorService.get('node'); const node = editorService.get("node");
editorService.set('node', { editorService.set("node", {
...node, ...node,
name: 'new name' name: "new name",
}); });
``` ```
## getNodeInfo ## getNodeInfo
- **参数:** - **参数:**
- `{number | string}` id 组件id - `{number | string}` id 组件id
- `{boolean}` raw 是否使用toRaw默认为true - `{boolean}` raw 是否使用toRaw默认为true
:::tip :::tip
@ -74,8 +78,19 @@ editorService.set('node', {
::: :::
- **返回:** - **返回:**
- {`EditorNodeInfo`}
- {[EditorNodeInfo](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/editor/src/type.ts#L139-L143)} ::: details 查看 EditorNodeInfo 及关联类型定义
<<< @/../packages/editor/src/type.ts#EditorNodeInfo{ts}
<<< @/../packages/schema/src/index.ts#MNode{ts}
<<< @/../packages/schema/src/index.ts#MContainer{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
:::
- **详情:** - **详情:**
@ -84,9 +99,9 @@ editorService.set('node', {
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
const info = editorService.getNodeInfo('text_123'); const info = editorService.getNodeInfo("text_123");
console.log(info.node); console.log(info.node);
console.log(info.parent); console.log(info.parent);
@ -96,14 +111,27 @@ console.log(info.page);
## getNodeById ## getNodeById
- **参数:** - **参数:**
- `{number | string}` id - `{number | string}` id
- `{boolean}` raw 是否使用toRaw默认为true - `{boolean}` raw 是否使用toRaw默认为true
- **返回:** - **返回:**
- {`MNode`} 组件节点配置
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} 组件节点配置 ::: details 查看 MNode 及关联类型定义
<<< @/../packages/schema/src/index.ts#MNode{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#MContainer{ts}
<<< @/../packages/schema/src/index.ts#MIteratorContainer{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MApp{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
:::
- **详情:** - **详情:**
@ -112,9 +140,9 @@ console.log(info.page);
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
const node = editorService.getNodeById('text_123'); const node = editorService.getNodeById("text_123");
console.log(node); console.log(node);
``` ```
@ -122,14 +150,11 @@ console.log(node);
## getParentById ## getParentById
- **参数:** - **参数:**
- `{number | string}` id - `{number | string}` id
- `{boolean}` raw 是否使用toRaw默认为true - `{boolean}` raw 是否使用toRaw默认为true
- **返回:** - **返回:**
- {`MNode`} 指点组件的父节点配置
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} 指点组件的父节点配置
- **详情:** - **详情:**
@ -138,26 +163,50 @@ console.log(node);
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
const parent = editorService.getParentById('text_123'); const parent = editorService.getParentById("text_123");
console.log(parent); console.log(parent);
``` ```
## isOnDifferentPage
- **参数:**
- {`MNode`} node 节点配置
- **返回:**
- `{boolean}` true 表示该节点位于非当前页面(即选中该节点将会引起当前页面切换)
- **详情:**
判断给定节点是否位于非当前页面,通常用于配合 `doNotSwitchPage` 选项判断 DSL 操作是否会引起页面切换
- **示例:**
```js
import { editorService } from "@tmagic/editor";
const otherPageNode = editorService.getNodeById("text_456");
if (editorService.isOnDifferentPage(otherPageNode)) {
console.log("该节点在其它页面,操作会触发页面切换");
}
```
## getLayout ## getLayout
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode`} parent
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} parent - {`MNode`} node 可选
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} node 可选
- **返回:** - **返回:**
- {Promise<`Layout`>} 当前布局模式
- {Promise<[Layout](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/editor/src/type.ts#L297-L302)>} 当前布局模式 ::: details 查看 Layout 类型定义
<<< @/../packages/editor/src/type.ts#Layout{ts}
:::
- **详情:** - **详情:**
@ -172,9 +221,9 @@ console.log(parent);
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
const parent = editorService.getParentById('text_123'); const parent = editorService.getParentById("text_123");
editorService.getLayout(parent).then((layout) => { editorService.getLayout(parent).then((layout) => {
console.log(parent); console.log(parent);
}); });
@ -185,12 +234,10 @@ editorService.getLayout(parent).then((layout) => {
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {number | string | `MNode`} config 需要选中的节点或节点ID
- {number | string | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} config 需要选中的节点或节点ID
- **返回:** - **返回:**
- {Promise<`MNode`>} 当前选中的节点配置
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)>} 当前选中的节点配置
- **详情:** - **详情:**
@ -203,20 +250,18 @@ editorService.getLayout(parent).then((layout) => {
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
editorService.select('text_123'); editorService.select("text_123");
editorService.get('stage')?.select('text_123'); editorService.get("stage")?.select("text_123");
``` ```
## multiSelect ## multiSelect
- **参数:** - **参数:**
- {(number | string)[]} ids 需要选中的节点ID集合 - {(number | string)[]} ids 需要选中的节点ID集合
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -230,22 +275,47 @@ editorService.get('stage')?.select('text_123');
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
editorService.multiSelect(['text_123', 'button_123']); editorService.multiSelect(["text_123", "button_123"]);
editorService.get('stage')?.multiSelect(['text_123', 'button_123']); editorService.get("stage")?.multiSelect(["text_123", "button_123"]);
``` ```
## selectNextNode
- **返回:**
- {Promise<`MNode` | null>} 选中后的节点配置
- **详情:**
选中当前节点同层级(同一父节点)的下一个节点,已经是最后一个时回到第一个
## selectNextPage
- **返回:**
- {Promise<`MNode`>} 选中后的页面配置
- **详情:**
选中下一页,已经是最后一页时回到第一页
## selectRoot
- **返回:**
- `{void}`
- **详情:**
选中根节点root同时清空当前选中的页面、父节点、画布及高亮节点
## highlight ## highlight
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {number | string | `MNode`} config 需要高亮的节点或节点ID
- {number | string | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} config 需要高亮的节点或节点ID
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -255,9 +325,9 @@ editorService.get('stage')?.multiSelect(['text_123', 'button_123']);
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
editorService.highlight('text_123'); editorService.highlight("text_123");
``` ```
## doAdd ## doAdd
@ -265,14 +335,12 @@ editorService.highlight('text_123');
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode`} node 新组件节点
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} node 新组件节点 - {`MContainer`} parent 指定的容器节点
- {[MContainer](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L54-L59)} parent 指定的容器节点
- **返回:** - **返回:**
- {Promise<`MNode`>} 新增的组件
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)>} 新增的组件
- **详情:** - **详情:**
@ -283,14 +351,17 @@ editorService.highlight('text_123');
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode` | `MNode`[]} node 新组件节点配置或多个节点集合
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]} node 新组件节点配置或多个节点集合 - {`MContainer`} parent 指定的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
- {[MContainer](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L54-L59)} parent 指定的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点 - `{Object}` options 可选配置
- `{boolean}` doNotSelect 添加后是否不更新当前选中节点(默认 false添加后会选中新增的节点
- `{boolean}` doNotSwitchPage 添加后是否不切换当前页面(默认 false新增页面 / 跨页新增时为 true 会跳过会引发页面切换的选中操作)
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- {Promise<`MNode` | `MNode`[]>} 新增的组件或组件集合
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]>} 新增的组件或组件集合
- **详情:** - **详情:**
@ -307,30 +378,35 @@ editorService.highlight('text_123');
## doRemove ## doRemove
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode`} node 要删除的节点
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} node 要删除的节点 - `{Object}` options 可选配置
- `{boolean}` doNotSelect 删除后是否不更新当前选中节点(默认 false
- `{boolean}` doNotSwitchPage 删除后是否不切换当前页面(默认 false删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
删除指定的组件或者页面 删除指定的组件或者页面
:::tip
无论是否传入 `doNotSelect` / `doNotSwitchPage`当被删除节点在当前选中列表中时state 都会自动移除该节点的引用当被删除的正好是当前页面时state.page 也会同步清空,避免持有已删除节点
:::
## remove ## remove
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode` | `MNode`[])} node 要删除的节点或节点集合
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[])} node 要删除的节点或节点集合 - `{Object}` options 可选配置
- `{boolean}` doNotSelect 删除后是否不更新当前选中节点(默认 false删除后会选中父节点或首个页面
- `{boolean}` doNotSwitchPage 删除后是否不切换当前页面(默认 false删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -350,12 +426,16 @@ editorService.highlight('text_123');
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode`} config 新的节点
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99))} node 新的节点 - `{Object}` data 可选配置
- {`ChangeRecord`[]} changeRecords 变更记录
- **返回:** - **返回:**
- `{Promise<{ newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] }>}` 更新前后的节点信息
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)>} 新的节点 ::: details 查看 ChangeRecord 类型定义
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
- **详情:** - **详情:**
@ -363,6 +443,10 @@ editorService.highlight('text_123');
:::tip :::tip
节点中应该要有id不然不知道要更新哪个节点 节点中应该要有id不然不知道要更新哪个节点
当被更新节点正好在当前选中列表中时state 会自动同步到新的节点引用,无需调用方处理
当被更新节点正好是当前页面时state.page 也会同步到新的节点引用;更新非当前页面(不同 ID时不会把编辑器切到该页
::: :::
## update ## update
@ -370,13 +454,18 @@ editorService.highlight('text_123');
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode` | `MNode`[]} config 新的节点或节点集合
- `{Object}` data 可选配置
- {`ChangeRecord`[]} changeRecords 单节点 form 端变更记录(多节点场景下被忽略,使用 `changeRecordList`
- {`ChangeRecord`[][]} changeRecordList 多节点 form 端变更记录列表,按 `config` 数组同序对应每个节点;优先级高于 `changeRecords`
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]>} node 新的节点或节点集合 ::: details 查看 ChangeRecord 类型定义
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
- **返回:** - **返回:**
- {Promise<`MNode` | `MNode`[]>} 新的节点或节点集合
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]>} 新的节点或节点集合
- **详情:** - **详情:**
@ -390,17 +479,29 @@ editorService.highlight('text_123');
编辑器内部更新组件都是调用update来实现的update除了更新操作外还会记录历史堆还会更新[代码块](../../guide/advanced/code-block.md)关系链。 编辑器内部更新组件都是调用update来实现的update除了更新操作外还会记录历史堆还会更新[代码块](../../guide/advanced/code-block.md)关系链。
::: :::
:::tip
**多节点场景必须使用 `changeRecordList`**:每个节点应保留自己独立的 records不能把多个节点的
records 合并到同一个 `changeRecords` 数组里,否则 `doUpdate` / 依赖收集 / 历史回放都会按错误的
`propPath` 处理。
写入历史时,每个节点的 records 会单独保存到 `updatedItems[i].changeRecords`;撤销/重做时若有
records则仅按 `propPath` 局部更新对应字段,避免整节点替换冲掉同节点上的其它无关变更;缺省
才退化为整节点替换(如内部 `sort` / `moveLayer` / 拖动等纯快照场景)。
:::
## sort ## sort
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{ string | number }` id1 - `{ string | number }` id1
- `{ string | number }` id2 - `{ string | number }` id2
- `{Object}` options 可选配置
- `{boolean}` doNotSelect 排序后是否不更新当前选中节点(默认 false
- `{boolean}` doNotSwitchPage 排序后是否不切换当前页面(排序只发生在同一父节点内,方法内为空操作;保留以与其它 DSL 操作 API 一致)
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -414,29 +515,37 @@ editorService.highlight('text_123');
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode` | `MNode`[]} config 需要复制的节点或节点集合
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]>} node 需要复制的节点或节点集合
- **返回:** - **返回:**
- `{void}`
- `{Promise<void>}`
- **详情:** - **详情:**
复制组件节点或节点集合 复制组件节点或节点集合
通过[storageService.setItem](./storageServiceMethods.md#setitem),将组将节点配置转化成string然后存储到localStorage中 通过[storageService.setItem](./storageServiceMethods.md#setitem),将组件节点配置存储到localStorage中
## copyWithRelated
- **参数:**
- {`MNode` | `MNode`[]} config 需要复制的节点或节点集合
- `{TargetOptions}` collectorOptions 可选的依赖收集器配置
- **返回:**
- `{void}`
- **详情:**
复制节点时会同时收集组件关联的依赖(如 dataSource、codeBlock 等),并一起存储到 localStorage 中,便于粘贴时一起带入
## doPaste ## doPaste
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - ## **参数:**
-
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -448,31 +557,36 @@ editorService.highlight('text_123');
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`PastePosition`} position 粘贴的坐标
- {[PastePosition](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L152-L163)} position 粘贴的坐标 ::: details 查看 PastePosition 类型定义
<<< @/../packages/editor/src/type.ts#PastePosition{ts}
:::
- `{TargetOptions}` collectorOptions 可选的依赖收集器配置
- `{Object}` options 可选配置
- `{boolean}` doNotSelect 粘贴后是否不更新当前选中节点(默认 false
- `{boolean}` doNotSwitchPage 粘贴后是否不切换当前页面(默认 false跨页粘贴时为 true 会跳过页面切换)
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- {Promise<`MNode` | `MNode`[]>} 添加后的组件节点配置
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]>} 添加后的组件节点配置
- **详情:** - **详情:**
粘贴组件节点或节点集合 粘贴组件节点或节点集合
通过[storageService.getItem](./storageServiceMethods.md#setitem),从localStorage中获取节点然后添加到当前容器中 通过[storageService.getItem](./storageServiceMethods.md#getItem),从localStorage中获取节点然后添加到当前容器中
## doAlignCenter ## doAlignCenter
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode`} config 需要居中的组件
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} config 需要居中的组件
- **返回:** - **返回:**
- {Promise<`MNode`>}
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)>}
- **详情:** - **详情:**
@ -487,13 +601,14 @@ editorService.highlight('text_123');
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode` | `MNode`[]} config 需要居中的组件或者组件集合
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]>} config 需要居中的组件或者组件集合 - `{Object}` options 可选配置
- `{boolean}` doNotSelect 居中后是否不更新当前选中节点(默认 false
- `{boolean}` doNotSwitchPage 居中后是否不切换当前页面(居中只更新节点 style方法内为空操作保留以与其它 DSL 操作 API 一致)
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- {Promise<`MNode` | `MNode`[]>}
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)[]>}
- **详情:** - **详情:**
@ -504,16 +619,17 @@ editorService.highlight('text_123');
alignCenter可以支持一次水平居中多个组件alignCenter是通过调用[doAlignCenter](#doaligncentere)来获取到已设置好水平居中的位置信息的节点然后调用update更新。 alignCenter可以支持一次水平居中多个组件alignCenter是通过调用[doAlignCenter](#doaligncentere)来获取到已设置好水平居中的位置信息的节点然后调用update更新。
::: :::
## moveLayer ## moveLayer
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{number | 'top' | 'bottom'}` offset - `{number | 'top' | 'bottom'}` offset
- `{Object}` options 可选配置
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -522,31 +638,55 @@ alignCenter可以支持一次水平居中多个组件alignCenter是通过调
用于实现上移一层、下移一层、置顶、置底 用于实现上移一层、下移一层、置顶、置底
## moveToContainer ## moveToContainer
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode`} config 需要移动的节点
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} config 需要移动的节点
- `{string | number}` targetId 容器ID - `{string | number}` targetId 容器ID
- `{Object}` options 可选配置
- `{boolean}` doNotSelect 移动后是否不更新当前选中节点(默认 false
- `{boolean}` doNotSwitchPage 移动后是否不切换当前页面(默认 false目标容器位于其它页面时为 true 会跳过自动选中以避免页面切换)
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- Promise<`MNode` | undefined>
- Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99) | undefined>
- **详情:** - **详情:**
移动到指定容器中 移动到指定容器中
## dragTo
- **参数:**
- {`MNode` | `MNode`[]} config 需要拖拽的节点或节点集合
- {`MContainer`} targetParent 目标父容器
- `{number}` targetIndex 目标位置索引
- `{Object}` options 可选配置
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:**
- `{Promise<void>}`
- **详情:**
将节点(支持多选)拖拽到目标容器的指定位置,会自动处理跨容器布局切换并记录历史
## undo ## undo
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **返回:** - **返回:**
- {Promise<`StepValue` | null>}
- {Promise<[StepValue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L400-L404) | null>} ::: details 查看 StepValue 及关联类型定义
<<< @/../packages/editor/src/type.ts#StepValue{ts}
<<< @/../packages/editor/src/type.ts#HistoryOpType{ts}
<<< @/../packages/schema/src/index.ts#Id{ts}
:::
- **详情:** - **详情:**
@ -557,8 +697,7 @@ alignCenter可以支持一次水平居中多个组件alignCenter是通过调
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **返回:** - **返回:**
- {Promise<`StepValue` | null>}
- {Promise<[StepValue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L400-L404) | null>}
- **详情:** - **详情:**
@ -569,12 +708,12 @@ alignCenter可以支持一次水平居中多个组件alignCenter是通过调
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{number}` left - `{number}` left
- `{number}` top - `{number}` top
- `{Object}` options 可选配置
- `{boolean}` doNotPushHistory 是否不写入历史记录(默认 false
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -601,52 +740,18 @@ alignCenter可以支持一次水平居中多个组件alignCenter是通过调
移除所有事件监听清空state移除所有插件 移除所有事件监听清空state移除所有插件
## use
使用中间件的方式扩展方法,上述方法中标记有`扩展支持: 是`的方法都支持使用use扩展
- **示例:**
```js
import { editorService, getAddParent } from '@tmagic/editor';
import { ElMessageBox } from 'element-plus';
editorService.use({
// 添加是否删除节点确认提示
async remove(node, next) {
await ElMessageBox.confirm('是否删除', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
next();
},
add(node, next) {
// text组件只能添加到container中
const parentNode = getAddParent(node);
if (node.type === 'text' && parentNode?.type !== 'container') {
return;
}
next();
},
});
```
## usePlugin ## usePlugin
- **详情:** - **详情:**
相对于[use](#use), usePlugin支持更加灵活更加细致的扩展, 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展 usePlugin支持灵活细致的扩展 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展
每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值 每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值
- **示例:** - **示例:**
```js ```js
import { editorService } from '@tmagic/editor'; import { editorService } from "@tmagic/editor";
editorService.usePlugin({ editorService.usePlugin({
// 添加组件的时候设置一个添加时间 // 添加组件的时候设置一个添加时间
@ -663,3 +768,4 @@ editorService.usePlugin({
- **详情:** - **详情:**
删掉当前设置的所有扩展 删掉当前设置的所有扩展

View File

@ -4,4 +4,78 @@
- **详情:** 编辑器右侧组件属性配置加载完毕后触发 - **详情:** 编辑器右侧组件属性配置加载完毕后触发
- **回调函数:** (formState: [FomState](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/form/src/schema.ts#L27-L39)) => void - **事件回调函数:** `(instance: InstanceType<typeof FormPanel>) => void`
> [`FormPanel.vue`](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/layouts/props-panel/FormPanel.vue) 是属性面板组件实例
## props-panel-unmounted
- **详情:** 编辑器右侧组件属性配置卸载时触发
- **事件回调函数:** () => void
## update:modelValue
- **详情:** 当 [modelValue](./props.md#modelvalue-v-model)(DSL) 变化时触发,配合 `v-model` 使用
- **事件回调函数:** `(value: MApp | null) => void`
::: details 查看 MApp 及关联类型定义
<<< @/../packages/schema/src/index.ts#MApp{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#NodeType{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockDSL{ts}
<<< @/../packages/schema/src/index.ts#DataSourceSchema{ts}
<<< @/../packages/schema/src/index.ts#DataSourceDeps{ts}
:::
## props-form-error
- **详情:** 属性表单校验失败时触发
- **事件回调函数:** (e: any) => void
## props-submit-error
- **详情:** 属性表单提交失败时触发
- **事件回调函数:** (e: any) => void
注意:`Editor.vue` 中该 emit 的类型签名为 `[e: any]`,运行时通常为 `Error` 实例(来自 `submitForm` 抛错),但也可能是 element-plus 校验返回的 `invalidFields` 结构,业务侧消费时建议先做类型判断
## layer-node-dblclick
- **详情:** "已选组件"面板中组件树节点被双击时触发
默认行为(切换可展开节点的展开/收起状态)会先于该事件执行;可通过 [`beforeLayerNodeDblclick`](./props.md#beforelayernodedblclick) 钩子拦截,返回 `false` 时该事件不会被触发
- **事件回调函数:** `(event: MouseEvent, data: TreeNodeData) => void`
::: details 查看 TreeNodeData 及关联类型定义
<<< @/../packages/editor/src/type.ts#TreeNodeData{ts}
<<< @/../packages/schema/src/index.ts#Id{ts}
:::
- **示例:**
```html
<template>
<m-editor @layer-node-dblclick="onLayerNodeDblclick"></m-editor>
</template>
<script setup>
const onLayerNodeDblclick = (event, data) => {
console.log('双击节点', data.id, data.type);
};
</script>
```

View File

@ -1,53 +1,14 @@
# eventsService方法 # eventsService方法
## init
- **参数:**
- {Record<string, { events: [EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]; methods: [EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[] }>} eventMethodList 事件方法列表配置
- **返回:**
- `{void}`
- **详情:**
初始化事件服务,设置所有组件的事件和方法列表
:::tip
该方法通常由编辑器内部调用,开发者可以通过 [m-editor 的 eventMethodList prop](./props.md#eventmethodlist) 来配置
:::
- **示例:**
```js
import { eventsService } from '@tmagic/editor';
eventsService.init({
page: {
events: [
{ label: '页面加载', value: 'load' },
{ label: '页面卸载', value: 'unload' },
],
methods: [
{ label: '刷新', value: 'refresh' },
{ label: '返回', value: 'back' },
],
},
button: {
events: [
{ label: '点击', value: 'click' },
],
methods: [],
},
});
```
## setEvents ## setEvents
- **参数:** - **参数:**
- {Record<string, [EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]>} events 事件配置对象 - {Record<string, `EventOption`[]>} events 事件配置对象
::: details 查看 EventOption 类型定义
<<< @/../packages/core/src/utils.ts#EventOption{ts}
:::
- **返回:** - **返回:**
@ -78,7 +39,7 @@ eventsService.setEvents({
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} events 事件列表 - {`EventOption`[]} events 事件列表
- **返回:** - **返回:**
@ -107,7 +68,7 @@ eventsService.setEvent('button', [
- **返回:** - **返回:**
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} 事件列表 - {`EventOption`[]} 事件列表
- **详情:** - **详情:**
@ -126,7 +87,7 @@ console.log(events); // [{ label: '点击', value: 'click' }, ...]
- **参数:** - **参数:**
- {Record<string, [EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]>} methods 方法配置对象 - {Record<string, `EventOption`[]>} methods 方法配置对象
- **返回:** - **返回:**
@ -158,7 +119,7 @@ eventsService.setMethods({
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} methods 方法列表 - {`EventOption`[]} methods 方法列表
- **返回:** - **返回:**
@ -185,10 +146,11 @@ eventsService.setMethod('video', [
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- `{string | number}` _targetId 目标节点id保留参数便于扩展时按节点定制
- **返回:** - **返回:**
- {[EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]} 方法列表 - {`EventOption`[]} 方法列表
- **详情:** - **详情:**
@ -199,7 +161,7 @@ eventsService.setMethod('video', [
```js ```js
import { eventsService } from '@tmagic/editor'; import { eventsService } from '@tmagic/editor';
const methods = eventsService.getMethod('video'); const methods = eventsService.getMethod('video', 'video_123');
console.log(methods); // [{ label: '播放', value: 'play' }, ...] console.log(methods); // [{ label: '播放', value: 'play' }, ...]
``` ```
@ -242,3 +204,4 @@ import { eventsService } from '@tmagic/editor';
eventsService.destroy(); eventsService.destroy();
``` ```

View File

@ -4,11 +4,66 @@
- **详情:** 页面切换 - **详情:** 页面切换
- **回调函数:** (undoRedo: [undoRedo](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/utils/undo-redo.ts)) => void - **事件回调函数:** `(undoRedo: UndoRedo) => void`
::: details 查看 UndoRedo 类定义
<<< @/../packages/editor/src/utils/undo-redo.ts#UndoRedo{ts}
:::
## change ## change
- **详情:** 历史记录发生变化 - **详情:** 历史记录发生变化
- **回调函数:** (state: [StepValue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L400-L404)) => void - **事件回调函数:** `(state: StepValue | null) => void`
::: details 查看 StepValue 及关联类型定义
<<< @/../packages/editor/src/type.ts#StepValue{ts}
<<< @/../packages/editor/src/type.ts#HistoryOpType{ts}
<<< @/../packages/schema/src/index.ts#Id{ts}
<<< @/../packages/schema/src/index.ts#MNode{ts}
:::
:::tip
当游标处于历史栈边界(已经无法继续撤销或重做)时,`UndoRedo.undo()` / `redo()` 返回 `null`,对应 `change` 回调收到的 `state``null`
:::
## code-block-history-change
- **详情:** 代码块历史记录发生变化(`pushCodeBlock` / `undoCodeBlock` / `redoCodeBlock` 成功时触发)
- **事件回调函数:** `(codeBlockId: Id, step: CodeBlockStepValue) => void`
::: details 查看 CodeBlockStepValue 及关联类型定义
<<< @/../packages/editor/src/type.ts#CodeBlockStepValue{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockContent{ts}
<<< @/../packages/schema/src/index.ts#Id{ts}
:::
:::tip
- 新增触发的 step 中 `oldContent``null`
- 删除触发的 step 中 `newContent``null`
- `undo` / `redo` 返回 `null`(边界状态)时不会触发该事件
:::
## data-source-history-change
- **详情:** 数据源历史记录发生变化(`pushDataSource` / `undoDataSource` / `redoDataSource` 成功时触发)
- **事件回调函数:** `(dataSourceId: Id, step: DataSourceStepValue) => void`
::: details 查看 DataSourceStepValue 及关联类型定义
<<< @/../packages/editor/src/type.ts#DataSourceStepValue{ts}
<<< @/../packages/schema/src/index.ts#Id{ts}
:::
:::tip
- 新增触发的 step 中 `oldSchema``null`
- 删除触发的 step 中 `newSchema``null`
- `undo` / `redo` 返回 `null`(边界状态)时不会触发该事件
:::

View File

@ -4,59 +4,247 @@
- **详情:** - **详情:**
重置记录 重置全部历史记录(包括页面节点栈、代码块栈、数据源栈),并重置当前页面 id / canRedo / canUndo
## resetPage
- **详情:**
重置当前页面的历史记录状态清空当前页面id重置 canRedo/canUndo
## resetState
- **详情:**
重置历史记录全部内部状态(清空 pageId、pageSteps、canRedo、canUndo、codeBlockState、dataSourceState
## changePage ## changePage
- **参数:** - **参数:**
- `{MPage | MPageFragment} page`
- {[MPage](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L61)} page ::: details 查看 MPage / MPageFragment 类型定义
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
:::
- **详情:** - **详情:**
按页面切换历史堆栈 按页面切换历史堆栈
## empty
- **详情:**
重置记录,同[reset](#reset)
## push ## push
- **参数:** - **参数:**
- `{StepValue} state`
- {[StepValue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L400-L404)} state ::: details 查看 StepValue 及关联类型定义
<<< @/../packages/editor/src/type.ts#StepValue{ts}
<<< @/../packages/editor/src/type.ts#HistoryOpType{ts}
<<< @/../packages/schema/src/index.ts#Id{ts}
<<< @/../packages/schema/src/index.ts#MNode{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
- **返回:** - **返回:**
- `{StepValue | null}`
- {[StepValue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L400-L404) | null}
- **详情:** - **详情:**
添加一条历史记录 添加一条历史记录
::: tip
`opType: 'update'` 的每个 `updatedItems[i]` 上可携带 `changeRecords`,用于撤销 / 重做时仅按
`propPath` 局部更新对应字段,避免整节点替换冲掉同节点上的其它无关变更;不带
`changeRecords` 时退化为整节点替换(如 `sort` / `moveLayer` / 拖动等纯快照场景)。
:::
## undo ## undo
- **返回:** - **返回:**
- `{StepValue | null}`
- {Promise<[StepValue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L400-L404) | null>}
- **详情:** - **详情:**
撤销当前操作 撤销当前操作。`opType: 'update'` 时,若 `updatedItems[i].changeRecords` 存在,会按
`propPath``oldNode` 取值做局部回滚;否则用 `oldNode` 整节点替换。
## redo ## redo
- **返回:** - **返回:**
- `{StepValue | null}`
- {Promise<[StepValue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L400-L404) | null>}
- **详情:** - **详情:**
恢复到下一步 恢复到下一步。`opType: 'update'` 时,若 `updatedItems[i].changeRecords` 存在,会按
`propPath``newNode` 取值做局部重做;否则用 `newNode` 整节点替换。
## pushCodeBlock
- **参数:**
- `{Id} codeBlockId` 代码块 id
- `{Object} payload`
- `{CodeBlockContent | null} oldContent` 变更前的代码块内容;新增时为 `null`
- `{CodeBlockContent | null} newContent` 变更后的代码块内容;删除时为 `null`
- `{ChangeRecord[]} changeRecords` 可选form 端 propPath/value 变更列表,撤销/重做时若有则按 propPath 局部更新;缺省(或空数组)才退化为整内容替换
::: details 查看 CodeBlockStepValue 及关联类型定义
<<< @/../packages/editor/src/type.ts#CodeBlockStepValue{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockContent{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
- **返回:**
- `{CodeBlockStepValue | null}` 入栈失败(未传 id时返回 `null`
- **详情:**
推入一条代码块变更记录。与页面 / 节点完全无关,按 `codeBlockId` 维度独立一份 `UndoRedo` 栈,
栈实例存放在 `historyService.state.codeBlockState[codeBlockId]`
入栈成功后会触发 `code-block-history-change` 事件。
::: tip
`codeBlockService.setCodeDslByIdSync``codeBlockService.deleteCodeDslByIds` 内部已经
自动调用本方法,业务代码通常无需手动调用。
:::
## undoCodeBlock
- **参数:**
- `{Id} codeBlockId`
- **返回:**
- `{CodeBlockStepValue | null}` 栈不存在或已无可撤销记录时返回 `null`
- **详情:**
撤销指定代码块的最近一次变更。成功时会触发 `code-block-history-change` 事件。
拿到 step 后由调用方根据 `step.oldContent` 写回 `codeBlockService`(本方法不会自动回放)。
## redoCodeBlock
- **参数:**
- `{Id} codeBlockId`
- **返回:**
- `{CodeBlockStepValue | null}` 栈不存在或已无可重做记录时返回 `null`
- **详情:**
重做指定代码块的下一次变更。成功时会触发 `code-block-history-change` 事件。
## canUndoCodeBlock
- **参数:**
- `{Id} codeBlockId`
- **返回:**
- `{boolean}`
- **详情:**
指定代码块当前是否可撤销。栈不存在时返回 `false`
## canRedoCodeBlock
- **参数:**
- `{Id} codeBlockId`
- **返回:**
- `{boolean}`
- **详情:**
指定代码块当前是否可重做。栈不存在时返回 `false`
## pushDataSource
- **参数:**
- `{Id} dataSourceId` 数据源 id
- `{Object} payload`
- `{DataSourceSchema | null} oldSchema` 变更前的数据源 schema新增时为 `null`
- `{DataSourceSchema | null} newSchema` 变更后的数据源 schema删除时为 `null`
- `{ChangeRecord[]} changeRecords` 可选form 端 propPath/value 变更列表,撤销/重做时若有则按 propPath 局部更新;缺省(或空数组)才退化为整 schema 替换
::: details 查看 DataSourceStepValue 及关联类型定义
<<< @/../packages/editor/src/type.ts#DataSourceStepValue{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
:::
- **返回:**
- `{DataSourceStepValue | null}` 入栈失败(未传 id时返回 `null`
- **详情:**
推入一条数据源变更记录。与页面 / 节点完全无关,按 `dataSourceId` 维度独立一份 `UndoRedo` 栈,
栈实例存放在 `historyService.state.dataSourceState[dataSourceId]`
入栈成功后会触发 `data-source-history-change` 事件。
::: tip
`dataSourceService.add` / `update` / `remove` 内部已经自动调用本方法,业务代码通常无需手动调用。
:::
## undoDataSource
- **参数:**
- `{Id} dataSourceId`
- **返回:**
- `{DataSourceStepValue | null}`
- **详情:**
撤销指定数据源的最近一次变更。成功时会触发 `data-source-history-change` 事件。
拿到 step 后由调用方根据 `step.oldSchema` 写回 `dataSourceService`(本方法不会自动回放)。
## redoDataSource
- **参数:**
- `{Id} dataSourceId`
- **返回:**
- `{DataSourceStepValue | null}`
- **详情:**
重做指定数据源的下一次变更。成功时会触发 `data-source-history-change` 事件。
## canUndoDataSource
- **参数:**
- `{Id} dataSourceId`
- **返回:**
- `{boolean}`
- **详情:**
指定数据源当前是否可撤销。栈不存在时返回 `false`
## canRedoDataSource
- **参数:**
- `{Id} dataSourceId`
- **返回:**
- `{boolean}`
- **详情:**
指定数据源当前是否可重做。栈不存在时返回 `false`
## destroy ## destroy
- **详情:** - **详情:**
销毁 销毁

View File

@ -9,7 +9,25 @@
- **默认值:** `{}` - **默认值:** `{}`
- **类型:** [MApp](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/schema/src/index.ts?plain=1#L66-L73)[] - **类型:** `MApp[]`
::: details 查看 MApp 及关联类型定义
<<< @/../packages/schema/src/index.ts#MApp{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#NodeType{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockDSL{ts}
<<< @/../packages/schema/src/index.ts#DataSourceSchema{ts}
<<< @/../packages/schema/src/index.ts#DataSourceDeps{ts}
:::
- **示例:** - **示例:**
@ -49,7 +67,13 @@ const dsl = ref({
- **默认值:** `[]` - **默认值:** `[]`
- **类型:** [ComponentGroup](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/editor/src/type.ts#L355) - **类型:** `ComponentGroup[]`
::: details 查看 ComponentGroup 及关联类型定义
<<< @/../packages/editor/src/type.ts#ComponentGroup{ts}
<<< @/../packages/editor/src/type.ts#ComponentItem{ts}
:::
::: tip ::: tip
icon使用的是[element-plus icon](https://element-plus.org/zh-CN/component/icon.html) icon使用的是[element-plus icon](https://element-plus.org/zh-CN/component/icon.html)
@ -128,7 +152,11 @@ const componentGroupList = ref([
- **默认值:** `[]` - **默认值:** `[]`
- **类型:** [DatasourceTypeOption](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/editor/src/type.ts#L589) - **类型:** `DatasourceTypeOption[]`
::: details 查看 DatasourceTypeOption 类型定义
<<< @/../packages/editor/src/type.ts#DatasourceTypeOption{ts}
:::
- **示例:** - **示例:**
@ -169,7 +197,21 @@ const datasourceTypeList = ref([
} }
``` ```
- **类型:** [SideBarData](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L258-L265) - **类型:** `SideBarData`
::: details 查看 SideBarData 及关联类型定义
<<< @/../packages/editor/src/type.ts#SideBarData{ts}
<<< @/../packages/editor/src/type.ts#SideItem{ts}
<<< @/../packages/editor/src/type.ts#SideItemKey{ts}
<<< @/../packages/editor/src/type.ts#SideComponent{ts}
<<< @/../packages/editor/src/type.ts#MenuComponent{ts}
<<< @/../packages/editor/src/type.ts#Services{ts}
:::
- **示例:** - **示例:**
@ -218,7 +260,7 @@ icon使用的是[element-plus icon](https://element-plus.org/zh-CN/component/ico
顶部工具栏 顶部工具栏
系统提供了几个常用功能: `'/' | 'delete' | 'undo' | 'redo' | 'zoom-in' | 'zoom-out' | 'zoom' | 'guides' | 'rule' | 'scale-to-original' | 'scale-to-fit'` 系统提供了几个常用功能: `'/' | 'delete' | 'undo' | 'redo' | 'zoom-in' | 'zoom-out' | 'zoom' | 'guides' | 'rule' | 'scale-to-original' | 'scale-to-fit' | 'history-list'`
'/': 分隔符 '/': 分隔符
@ -242,13 +284,29 @@ icon使用的是[element-plus icon](https://element-plus.org/zh-CN/component/ico
'scale-to-fit': 缩放以适应 'scale-to-fit': 缩放以适应
'history-list': 历史记录面板(按 页面 / 数据源 / 代码块 三个 tab 展示操作历史,相邻同目标修改自动合并,支持点击跳转、回到初始状态、单步回滚及差异对比,详见[历史记录面板](/guide/advanced/history-list.md)
- **默认值:** - **默认值:**
```js ```js
{ left: [], center: [], right: [] } { left: [], center: [], right: [] }
``` ```
- **类型:** [MenuBarData](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L235-L242) - **类型:** `MenuBarData`
::: details 查看 MenuBarData 及关联类型定义
<<< @/../packages/editor/src/type.ts#MenuBarData{ts}
<<< @/../packages/editor/src/type.ts#ColumnLayout{ts}
<<< @/../packages/editor/src/type.ts#MenuItem{ts}
<<< @/../packages/editor/src/type.ts#MenuButton{ts}
<<< @/../packages/editor/src/type.ts#MenuComponent{ts}
<<< @/../packages/editor/src/type.ts#Services{ts}
:::
- **示例:** - **示例:**
@ -296,7 +354,15 @@ const menu = ref({
- **默认值:** `[]` - **默认值:** `[]`
- **类型:** ([MenuButton](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L168-L195) | [MenuComponent](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L197-L210))[] - **类型:** `(MenuButton | MenuComponent)[]`
::: details 查看 MenuButton / MenuComponent 及关联类型定义
<<< @/../packages/editor/src/type.ts#MenuButton{ts}
<<< @/../packages/editor/src/type.ts#MenuComponent{ts}
<<< @/../packages/editor/src/type.ts#Services{ts}
:::
- **示例:** - **示例:**
@ -330,7 +396,9 @@ const layerContentMenu = ref([
- **默认值:** `[]` - **默认值:** `[]`
- **类型:** ([MenuButton](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L168-L195) | [MenuComponent](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/type.ts#L197-L210))[] - **类型:** `(MenuButton | MenuComponent)[]`
> 已在上面 [layerContentMenu](#layercontentmenu) 段落展开过相同类型,参考即可。
- **示例:** - **示例:**
@ -471,7 +539,19 @@ const renderFunction = async (stage) => {
- **默认值:** `{}` - **默认值:** `{}`
- -
- **类型:** Record<string, [FormConfig](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/form/src/schema.ts#L706)> - **类型:** `Record<string, FormConfig>`
::: details 查看 FormConfig 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FormConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItemConfig{ts}
<<< @/../packages/form-schema/src/base.ts#ChildConfig{ts}
<<< @/../packages/form-schema/src/base.ts#DynamicTypeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
- **示例:** - **示例:**
@ -547,12 +627,16 @@ const propsValues = {
组件属性配置中事件tab中的事件名与动作的下拉选项列表 组件属性配置中事件tab中的事件名与动作的下拉选项列表
:::tip :::tip
该属性最终会设置到[eventsService](./eventsServiceMethods.md)中,所以也可直接调用[eventsService.setEvents()](./eventsServiceMethods.md#setEvents)与[eventsService.setMethods()](./eventsServiceMethods#setMethods)方法来配置 该属性最终会设置到[eventsService](./eventsServiceMethods.md)中,所以也可直接调用[eventsService.setEvents()](./eventsServiceMethods.md#setEvents)与[eventsService.setMethods()](./eventsServiceMethods.md#setMethods)方法来配置
::: :::
- **默认值:** `{}` - **默认值:** `{}`
- **类型:** Record<string, { events: [EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[]; methods: [EventOption](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/core/src/events.ts#L26-L29)[] }> - **类型:** `Record<string, { events: EventOption[]; methods: EventOption[] }>`
::: details 查看 EventOption 类型定义
<<< @/../packages/core/src/utils.ts#EventOption{ts}
:::
- **示例:** - **示例:**
@ -593,7 +677,23 @@ const eventMethodList = {
- **默认值:** `{}` - **默认值:** `{}`
- **类型:** Record<string, Partial<[DataSourceSchema](https://github.com/Tencent/tmagic-editor/blob/5880dfbe15fcead63e9dc7c91900f8c4e7a574d8/packages/schema/src/index.ts#L221)>> - **类型:** `Record<string, Partial<DataSourceSchema>>`
::: details 查看 DataSourceSchema 及关联类型定义
<<< @/../packages/schema/src/index.ts#DataSourceSchema{ts}
<<< @/../packages/schema/src/index.ts#DataSchema{ts}
<<< @/../packages/schema/src/index.ts#MockSchema{ts}
<<< @/../packages/schema/src/index.ts#CodeBlockContent{ts}
<<< @/../packages/schema/src/index.ts#CodeParam{ts}
<<< @/../packages/schema/src/index.ts#EventConfig{ts}
<<< @/../packages/schema/src/index.ts#JsEngine{ts}
:::
- **示例:** - **示例:**
@ -634,7 +734,9 @@ const datasourceValues = {
- **默认值:** `{}` - **默认值:** `{}`
- **类型:** Record<string, [FormConfig](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/form/src/schema.ts#L706)> - **类型:** `Record<string, FormConfig>`
> 已在上面 [propsConfigs](#propsconfigs) 段落展开过 `FormConfig` 类型定义,参考即可。
- **示例:** - **示例:**
@ -675,7 +777,11 @@ const datasourceConfigs = {
- **默认值:** `{}` - **默认值:** `{}`
- **类型:** ((config: [CustomizeMoveableOptionsCallbackConfig](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/stage/src/types.ts#L97-L109)) => MoveableOptions) | [MoveableOptions](https://daybrush.com/moveable/release/latest/doc/) - **类型:** `((config: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions) | `[`MoveableOptions`](https://daybrush.com/moveable/release/latest/doc/)
::: details 查看 CustomizeMoveableOptionsCallbackConfig 类型定义
<<< @/../packages/stage/src/types.ts#CustomizeMoveableOptionsCallbackConfig{ts}
:::
- **示例:** - **示例:**
@ -793,6 +899,87 @@ const isContainer = (el) =>
</script> </script>
``` ```
## canDropIn
- **详情:**
用于自定义判断当前正在拖动的源是否可以拖入目标节点内部。同时覆盖"组件树拖动"和"画布拖入"两类场景,通过第三个参数 `scene` 区分;返回值有 3 种语义。
**scene 取值:**
| scene | 触发场景 | `sourceIds` | `targetId` |
| --- | --- | --- | --- |
| `'layer'` | "已选组件"面板组件树拖动 | 被拖动节点 id单选时长度为 1 | 目标节点 id |
| `'stage-drag'` | 画布上拖动已有组件 | 被拖动组件 id 列表(多选时为多个) | 候选容器节点 id |
| `'stage-add'` | 从左侧组件列表拖入新组件到画布 | 始终为空数组(尚无 id可仅依据 `targetId` 判断) | 候选容器节点 id |
**返回值语义:**
| 返回值 | layer | stage-drag | stage-add |
| --- | --- | --- | --- |
| `false` | 禁用 inner同时禁用所有"target 子节点的 before/after"(这些位置等价于放入 target避免被绕过 | 阻止该容器被高亮命中 | 取消此次拖入 |
| `Id`string \| number | 将 inner 拖入目标重定向为该 id 对应的节点;与 `false` 一致禁用所有"target 子节点的 before/after" | 高亮命中切换到该 id 对应元素,最终拖入到该节点 | 直接将组件添加到该 id 对应节点layout 坐标也基于其 DOM 重新计算) |
| `true` / `void` / `undefined` | 按原 targetId 正常拖入 | 同左 | 同左 |
`scene``'stage-drag'``'stage-add'` 时该函数会被透传给 `StageCore``canDropIn`,因此直接使用 `@tmagic/stage` 时同样生效
:::tip
- 可通过 `editorService.getNodeById(id, false)` 把 id 还原为 `MNode` 以便基于业务字段(`type``name` 等)做判断。
- 该函数为**同步**调用(拖动事件在浏览器中需要立即响应,不接受异步返回)。
- 重定向到一个不存在或非容器的目标 id 时会被忽略layer/stage-add 场景会取消此次拖入stage-drag 场景不会高亮。
:::
- **默认值:** `undefined`
- **类型:** `(sourceIds: Id[], targetId: Id, scene: 'layer' | 'stage-drag' | 'stage-add') => Id | boolean | void`
- **示例 1禁止某些组件拖入特定容器**
```html
<template>
<m-editor :can-drop-in="canDropIn"></m-editor>
</template>
<script setup>
import { editorService } from '@tmagic/editor';
// 禁止 button 类型的组件被拖入 list 容器内部,组件树拖动与画布拖入均生效
const canDropIn = (sourceIds, targetId, scene) => {
const targetNode = editorService.getNodeById(targetId, false);
if (targetNode?.type !== 'list') return true;
// 从组件列表新增组件时直接放行
if (scene === 'stage-add') return true;
return sourceIds.every((id) => {
const node = editorService.getNodeById(id, false);
return node?.type !== 'button';
});
};
</script>
```
- **示例 2将拖入"卡片外壳"重定向到"卡片内容"内层容器**
```html
<template>
<m-editor :can-drop-in="canDropIn"></m-editor>
</template>
<script setup>
import { editorService } from '@tmagic/editor';
// 当用户拖入到 card 节点时,自动改为放入其 card-content 内层容器
const canDropIn = (sourceIds, targetId) => {
const targetNode = editorService.getNodeById(targetId, false);
if (targetNode?.type !== 'card') return true;
const innerContent = targetNode.items?.find((item) => item.type === 'card-content');
return innerContent?.id ?? true;
};
</script>
```
## containerHighlightClassName ## containerHighlightClassName
- **详情:** - **详情:**
@ -963,6 +1150,25 @@ const updateDragEl = (el, target) => {
</template> </template>
``` ```
## alwaysMultiSelect
- **详情:**
始终启用多选模式:开启后无需按住 `Ctrl/Meta` 键,组件树和画布上点击即多选。
当 [`disabledMultiSelect`](#disabledmultiselect) 为 `true` 时本配置失效。
- **类型:** `boolean`
- **默认值:** `false`
- **示例:**
```html
<template>
<m-editor :always-multi-select="true"></m-editor>
</template>
```
## guidesOptions ## guidesOptions
- **详情:** - **详情:**
@ -1171,6 +1377,89 @@ const customContentMenu = (menus, { node }) => {
</script> </script>
``` ```
## layerNodeIsExpandable
- **详情:**
用于自定义判断"已选组件"面板中组件树节点是否可展开(即是否要展示为拥有子节点的形态)
该函数返回 `true` 时,节点会显示展开图标,并在展开后渲染子节点容器;返回 `false` 时,展开图标显示为透明占位,且不渲染子节点容器
默认行为:当节点的 `items` 中至少存在一个 `visible` 状态为 `true` 的子节点时认为可展开(被搜索过滤隐藏的子节点不会让父节点显示为可展开)
- **默认值:** `defaultIsExpandable`
- **类型:** `(data: TreeNodeData, nodeStatusMap: Map<Id, LayerNodeStatus>) => boolean`
- **示例:**
```html
<template>
<m-editor :layer-node-is-expandable="layerNodeIsExpandable"></m-editor>
</template>
<script setup>
import { defaultIsExpandable } from '@tmagic/editor';
// 即使没有可见子节点,特定类型的容器节点也保持展开图标可见
const layerNodeIsExpandable = (data, nodeStatusMap) => {
if (data.type === 'my-special-container') {
return true;
}
return defaultIsExpandable(data, nodeStatusMap);
};
</script>
```
::: tip
该函数仅作用于"已选组件"面板的组件树节点,不影响代码块、数据源等其它面板内的树。
第三方业务可从 `@tmagic/editor` 直接导入 `defaultIsExpandable` 复用默认逻辑作为兜底。
:::
## beforeLayerNodeDblclick
- **详情:**
"已选组件"面板组件树节点双击前的钩子函数
在用户双击组件树节点时,先于默认行为执行;返回 `false` 时阻止默认行为(默认行为是切换可展开节点的展开/收起状态)。返回其他值(包括 `true``undefined``Promise`)则继续执行默认行为,并向上抛出 [`layer-node-dblclick`](./events.md#layer-node-dblclick) 事件。
常见用途:拦截特定类型节点的双击行为,或在双击时执行业务自定义动作(如重命名、打开抽屉等)后阻断默认展开/收起。
- **默认值:** `undefined`
- **类型:** `(event: MouseEvent, data: TreeNodeData) => boolean | void | Promise<boolean | void>`
- **示例:**
```html
<template>
<m-editor
:before-layer-node-dblclick="beforeLayerNodeDblclick"
@layer-node-dblclick="onLayerNodeDblclick"
></m-editor>
</template>
<script setup>
// 双击 page 节点时阻止默认的展开/收起行为
const beforeLayerNodeDblclick = (event, data) => {
if (data.type === 'page') {
return false;
}
};
const onLayerNodeDblclick = (event, data) => {
console.log('双击节点', data.id);
};
</script>
```
::: tip
- 该钩子仅作用于"已选组件"面板的组件树节点,不影响画布上的双击行为(画布双击请使用 [`beforeDblclick`](#beforedblclick))。
- 返回 `false` 时,会同时阻断默认的"展开/收起"行为以及向上抛出的 [`layer-node-dblclick`](./events.md#layer-node-dblclick) 事件;返回其他值则继续触发默认行为并抛出事件。
:::
## extendFormState ## extendFormState
- **详情:** - **详情:**
@ -1219,6 +1508,55 @@ const extendFormState = async (state) => {
``` ```
::: :::
## historyListExtraTabs
- **详情:**
[历史记录面板](/guide/advanced/history-list.md) 的自定义扩展 tab。
业务方可借此在历史记录面板内置的「页面 / 数据源 / 代码块」三个 tab 之后追加自定义模块的历史 tab例如某个自定义模块维护自己的操作历史时可在面板中增加一个独立的 tab 来展示与回滚。
- **默认值:** `[]`
- **类型:** `HistoryListExtraTab[]`
::: details 查看 HistoryListExtraTab 类型定义
<<< @/../packages/editor/src/type.ts#HistoryListExtraTab{ts}
:::
- **示例:**
```html
<template>
<m-editor :menu="menu" :history-list-extra-tabs="historyListExtraTabs"></m-editor>
</template>
<script setup>
import { markRaw } from 'vue';
import MyModuleHistoryTab from './MyModuleHistoryTab.vue';
const historyListExtraTabs = [
{
name: 'my-module',
// label 支持字符串或函数,函数形式便于展示动态数量
label: () => '我的模块',
component: markRaw(MyModuleHistoryTab),
// 传入内容组件的 props
props: { foo: 'bar' },
// 内容组件的事件监听
listeners: {
goto: (cursor) => console.log(cursor),
},
},
];
</script>
```
::: tip
内容组件内部可自行通过 `useServices()` 获取 `historyService` 等服务来读取与回滚自定义模块的历史。
:::
## pageBarSortOptions ## pageBarSortOptions
- **详情:** - **详情:**
@ -1229,7 +1567,11 @@ const extendFormState = async (state) => {
- **默认值:** `undefined` - **默认值:** `undefined`
- **类型:** [PageBarSortOptions](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/type.ts) - **类型:** `PageBarSortOptions`
::: details 查看 PageBarSortOptions 类型定义
<<< @/../packages/editor/src/type.ts#PageBarSortOptions{ts}
:::
- **示例:** - **示例:**

View File

@ -4,4 +4,4 @@
- **详情:** [propsService.setPropsConfigs()](./propsServiceMethods.md#setPropsConfigs)后触发 - **详情:** [propsService.setPropsConfigs()](./propsServiceMethods.md#setPropsConfigs)后触发
- **回调函数:** () => void - **事件回调函数:** () => void

View File

@ -1,16 +1,69 @@
# propsService方法 # propsService方法
## setDisabledDataSource
- **参数:**
- `{boolean}` disabled 是否禁用数据源
- **返回:**
- `{void}`
- **详情:**
设置是否禁用数据源(内部状态),影响 [fillConfig](#fillconfig) 注入的公共配置
## setDisabledCodeBlock
- **参数:**
- `{boolean}` disabled 是否禁用代码块
- **返回:**
- `{void}`
- **详情:**
设置是否禁用代码块(内部状态),影响 [fillConfig](#fillconfig) 注入的公共配置
## getDisabledDataSource
- **返回:**
- `{boolean}` 是否禁用数据源
- **详情:**
获取是否禁用数据源的内部状态
## getDisabledCodeBlock
- **返回:**
- `{boolean}` 是否禁用代码块
- **详情:**
获取是否禁用代码块的内部状态
## fillConfig ## fillConfig
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`FormConfig`} config
- `{string}` labelWidth 表单项 label 宽度,默认 `'80px'`
- {[FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706)} config ::: details 查看 FormConfig 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FormConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItemConfig{ts}
<<< @/../packages/form-schema/src/base.ts#ChildConfig{ts}
<<< @/../packages/form-schema/src/base.ts#DynamicTypeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
- **返回:** - **返回:**
- {Promise<`FormConfig`>}
- {Promise<[FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706)>}
- **详情:** - **详情:**
@ -19,11 +72,13 @@
## setPropsConfigs ## setPropsConfigs
- **参数:** - **参数:**
- {Record<string, `FormConfig` | `PropsFormConfigFunction`>} configs
- {Record<string, [FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706)>} configs ::: details 查看 PropsFormConfigFunction 类型定义
<<< @/../packages/editor/src/type.ts#PropsFormConfigFunction{ts}
:::
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -35,12 +90,10 @@
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- {[FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706)} config 属性表单配置DSL - {`FormConfig`} config 属性表单配置DSL
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
@ -52,12 +105,28 @@
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- `{Object}` data 可选参数
- {`MNode` | null} node 当前节点
::: details 查看 MNode 及关联类型定义
<<< @/../packages/schema/src/index.ts#MNode{ts}
<<< @/../packages/schema/src/index.ts#MComponent{ts}
<<< @/../packages/schema/src/index.ts#MContainer{ts}
<<< @/../packages/schema/src/index.ts#MIteratorContainer{ts}
<<< @/../packages/schema/src/index.ts#MPage{ts}
<<< @/../packages/schema/src/index.ts#MApp{ts}
<<< @/../packages/schema/src/index.ts#MPageFragment{ts}
:::
- **返回:** - **返回:**
- {Promise<`FormConfig`>}
- {Promise<[FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706)>}
- **详情:** - **详情:**
@ -66,11 +135,9 @@
## setPropsValues ## setPropsValues
- **参数:** - **参数:**
- {Record<string, `MNode`>} values
- {Record<string, [MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)>} values
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
@ -80,64 +147,55 @@
## setPropsValue ## setPropsValue
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} value 组件初始值 - {`MNode`} value 组件初始值
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
设置组件与属性表单默认值的对应关系 设置组件与属性表单默认值的对应关系
## getPropsValue ## getPropsValue
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} value 组件默认值,可选 - `{Object}` defaultValue 组件默认值,可选
- **返回:** - **返回:**
- {Promise<`MNode`>} 合并默认配置后的节点对象
- `{Promise<void>}`
- **详情:** - **详情:**
获取指定类型的组件初始值 获取指定类型的组件初始值,会合并 [getDefaultPropsValue](#getdefaultpropsvalue) 与已注册的 propsValue并自动生成 id
## createId ## createId
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string | number}` type 组件类型
- {string} type 组件列席
- **返回:** - **返回:**
- `{string}` 生成的组件id格式为 `type_guid`
- `{Promise<string>}`
- **详情:** - **详情:**
生成组件id 生成组件id
## setNewItemId ## setNewItemId
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- {`MNode`} config
- {[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)} config - `{boolean}` force 是否强制设置新ID默认 `true`
- **返回:** - **返回:**
- {`MNode`} 处理后的节点
- {Promise<[MNode](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L99)>}
- **详情:** - **详情:**
@ -148,22 +206,47 @@
- **[扩展支持](../../guide/editor-expand#行为扩展)** 是 - **[扩展支持](../../guide/editor-expand#行为扩展)** 是
- **参数:** - **参数:**
- `{string}` type 组件类型 - `{string}` type 组件类型
- **返回:** - **返回:**
- `{Object}` 默认属性配置对象(包含 `type``style``name` 等基础字段,`page`/`container` 类型会额外包含 `layout``items`
- `{Promise<void>}`
- **详情:** - **详情:**
获取默认属性配置 获取默认属性配置
## replaceRelateId
- **参数:**
- {`MNode`[]} originConfigs 原始组件配置
- {`MNode`[]} targetConfigs 待替换的组件配置
- `{TargetOptions}` collectorOptions 依赖收集器配置
- **返回:**
- `{void}`
- **详情:**
根据 [setNewItemId](#setnewitemid) 收集到的新旧 id 映射,替换目标配置中关联引用的 id用于复制粘贴时保持组件间的关联依赖
## clearRelateId
- **返回:**
- `{void}`
- **详情:**
清除 [setNewItemId](#setnewitemid) 维护的新旧 id 映射关系
## resetState ## resetState
- **详情:** - **详情:**
情况所有组件的属性配置与初始值 清空所有组件的属性配置 (`propsConfigMap`) 与初始值 (`propsValueMap`)。
::: tip
本方法**不会**重置 `disabledDataSource` / `disabledCodeBlock` 标记,也**不会**清空 `relateIdMap`;如需清理后两者,请分别调用 [setDisabledDataSource](#setdisableddatasource) / [setDisabledCodeBlock](#setdisabledcodeblock) 与 [clearRelateId](#clearrelateid)。
:::
## destroy ## destroy
@ -171,15 +254,11 @@
销毁propsService 销毁propsService
## use
使用中间件的方式扩展方法,上述方法中标记有`扩展支持: 是`的方法都支持使用use扩展
## usePlugin ## usePlugin
- **详情:** - **详情:**
相对于[use](#use), usePlugin支持更加灵活更加细致的扩展, 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展 usePlugin支持灵活细致的扩展, 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展
每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值 每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值
@ -188,3 +267,4 @@
- **详情:** - **详情:**
删掉当前设置的所有扩展 删掉当前设置的所有扩展

View File

@ -22,7 +22,7 @@
- **详情:** 编辑器顶部菜单栏 - **详情:** 编辑器顶部菜单栏
- **默认:** [NavMenu.vue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/layouts/NavMenu.vue) - **默认:** [NavMenu.vue](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/layouts/NavMenu.vue)
- **插槽 Props** - **插槽 Props**
- `editorService`: editorService 实例 - `editorService`: editorService 实例
@ -64,7 +64,7 @@
- **详情:** 左边栏 - **详情:** 左边栏
- **默认:** [Sidebar.vue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/layouts/sidebar/Sidebar.vue) - **默认:** [Sidebar.vue](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/layouts/sidebar/Sidebar.vue)
- **插槽 Props** - **插槽 Props**
- `editorService`: editorService 实例 - `editorService`: editorService 实例
@ -259,7 +259,7 @@
- **详情:** 编辑器中间区域 - **详情:** 编辑器中间区域
- **默认:** [Workspace.vue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/layouts/workspace/Workspace.vue) - **默认:** [Workspace.vue](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/layouts/workspace/Workspace.vue)
- **插槽 Props** - **插槽 Props**
- `editorService`: editorService 实例 - `editorService`: editorService 实例
@ -268,7 +268,29 @@
- **详情:** 画布 - **详情:** 画布
- **默认:** [Stage.vue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/layouts/workspace/Stage.vue) - **默认:** [Stage.vue](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/layouts/workspace/Stage.vue)
## stage-top
- **详情:** 画布上方位置,与画布共享同一个滚动容器,渲染在画布之前,可用于在画布顶部插入自定义元素,例如顶部工具条、提示信息等
- **默认:**
:::warning
如设置了[stage](#stage)插槽,此插槽将失效
:::
- **示例:**
```html
<template>
<m-editor>
<template #stage-top>
<div class="custom-stage-top">画布顶部自定义内容</div>
</template>
</m-editor>
</template>
```
## workspace-content ## workspace-content
@ -334,7 +356,7 @@
- **详情:** 编辑器右侧属性配置 - **详情:** 编辑器右侧属性配置
- **默认:** [PropsPanel.vue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/layouts/PropsPanel.vue) - **默认:** [PropsPanel.vue](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/layouts/props-panel/PropsPanel.vue)
## props-panel-header ## props-panel-header
@ -358,7 +380,7 @@
- **详情:** 当前没有页面时,编辑器中间区域 - **详情:** 当前没有页面时,编辑器中间区域
- **默认:** [AddPageBox.vue](https://github.com/Tencent/tmagic-editor/blob/239b5d3efeae916a8cf3e3566d88063ecccc0553/packages/editor/src/layouts/AddPageBox.vue) - **默认:** [AddPageBox.vue](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/layouts/AddPageBox.vue)
- **插槽 Props** - **插槽 Props**
- `editorService`: editorService 实例 - `editorService`: editorService 实例

View File

@ -231,28 +231,11 @@ import { storageService } from '@tmagic/editor';
storageService.destroy(); storageService.destroy();
``` ```
## use
使用中间件的方式扩展方法,上述方法中标记有`扩展支持: 是`的方法都支持使用use扩展
- **示例:**
```js
import { storageService } from '@tmagic/editor';
storageService.use({
getItem(key, options, next) {
console.log('获取存储项:', key);
return next();
},
});
```
## usePlugin ## usePlugin
- **详情:** - **详情:**
相对于[use](#use), usePlugin支持更加灵活更加细致的扩展, 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展 usePlugin支持灵活细致的扩展 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展
每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值 每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值

View File

@ -24,6 +24,7 @@
- `stageRect`: 画布尺寸 - `stageRect`: 画布尺寸
- `columnWidth`: 列宽度配置 - `columnWidth`: 列宽度配置
- `showGuides`: 是否显示参考线 - `showGuides`: 是否显示参考线
- `hasGuides`: 画布上是否存在参考线
- `showRule`: 是否显示标尺 - `showRule`: 是否显示标尺
- `propsPanelSize`: 属性面板尺寸 - `propsPanelSize`: 属性面板尺寸
- `showAddPageButton`: 是否显示添加页面按钮 - `showAddPageButton`: 是否显示添加页面按钮
@ -178,29 +179,11 @@ import { uiService } from '@tmagic/editor';
uiService.destroy(); uiService.destroy();
``` ```
## use
使用中间件的方式扩展方法,上述方法中标记有`扩展支持: 是`的方法都支持使用use扩展
- **示例:**
```js
import { uiService } from '@tmagic/editor';
uiService.use({
async zoom(value, next) {
console.log('缩放前:', uiService.get('zoom'));
await next();
console.log('缩放后:', uiService.get('zoom'));
},
});
```
## usePlugin ## usePlugin
- **详情:** - **详情:**
相对于[use](#use), usePlugin支持更加灵活更加细致的扩展, 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展 usePlugin支持灵活细致的扩展 上述方法中标记有`扩展支持: 是`的方法都支持使用usePlugin扩展
每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值 每个支持扩展的方法都支持定制before、after两个hook来干预原有方法的行为before可以用于修改传入参数after可以用于修改返回的值

View File

@ -4,24 +4,40 @@
- **详情:** 弹出关闭 - **详情:** 弹出关闭
- **回调函数:** () => void - **事件回调函数:** `() => void`
## submit ## submit
- **详情:** 调用[save()](./form-dialog-methods.md#save) - **详情:** 调用 [save()](./form-dialog-methods.md#save) 校验通过后触发
- **回调函数:** (values: any) => void - **事件回调函数:** `(values: any, eventData: { changeRecords: ChangeRecord[] }) => void`
## error ## error
- **详情:** 表单校验不同 - **详情:** 表单校验**不**通过时触发
- **回调函数:** (error: any) => void - **事件回调函数:** `(invalidFields: Record<string, { message: string; field: string }[]>) => void`
注意:与 `Form``error` 事件一致,回调收到的是 element-plus `validate` 返回的 `invalidFields` 结构,**不是** `Error` 实例。
## change ## change
- **详情:** 表单中任何值发生变化 - **详情:** 表单中任何值发生变化
- **回调函数:** (values: any) => void - **事件回调函数:** `(values: any, eventData: ContainerChangeEventData) => void`
注意:第一个参数是**整张表单**的 `values`,并非单个字段的值。
其中 `ContainerChangeEventData` 定义如下:
```ts
interface ChangeRecord {
propPath?: string;
value: any;
}
interface ContainerChangeEventData {
modifyKey?: string;
changeRecords?: ChangeRecord[];
}
```

View File

@ -6,8 +6,40 @@
## save ## save
- **签名:** `save(): Promise<void>`
- **返回:** - **返回:**
- `{Promise<any>}` - `{Promise<void>}`
- **详情:** 获取表单的值 - **详情:** 调用内部 Form 的 `submitForm` 进行校验,校验通过后触发 `submit` 事件(参数为表单值与 `{ changeRecords }`);若校验失败则触发 `error` 事件
## show
- **签名:** `show(): void`
- **详情:** 打开弹窗,等价于将内部 `dialogVisible` 置为 `true`
## hide
- **签名:** `hide(): void`
- **详情:** 关闭弹窗,等价于将内部 `dialogVisible` 置为 `false`
## form
- **类型:** `Ref<InstanceType<typeof Form> | undefined>`
- **详情:** 内部 Form 组件的实例引用,可通过它访问 Form 上 `defineExpose` 暴露的方法与属性
## saveFetch
- **类型:** `Ref<boolean>`
- **详情:** 保存按钮的 loading 状态
## dialogVisible
- **类型:** `Ref<boolean>`
- **详情:** 弹窗的显示状态

View File

@ -6,7 +6,19 @@
- **默认值:** `[]` - **默认值:** `[]`
- **类型:** [FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706) - **类型:** `FormConfig`
::: details 查看 FormConfig 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FormConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItemConfig{ts}
<<< @/../packages/form-schema/src/base.ts#ChildConfig{ts}
<<< @/../packages/form-schema/src/base.ts#DynamicTypeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
- **示例:** - **示例:**
@ -16,19 +28,19 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'Vue'; import { ref } from "Vue";
const config = ref([ const config = ref([
{ {
name: 'text', name: "text",
text: '文本', text: "文本",
}, },
{ {
name: 'multiple', name: "multiple",
text: '多行文本', text: "多行文本",
type: 'switch', type: "switch",
}, },
]); ]);
</script> </script>
``` ```
@ -48,15 +60,21 @@ const config = ref([
</template> </template>
<script setup> <script setup>
import { ref } from 'Vue'; import { ref } from 'Vue';
const values = ref([ const values = ref([
text: 'text', text: 'text',
multiply: true, multiply: true,
]); ]);
</script> </script>
``` ```
## parentValues
- **详情:** 父级表单值,会透传给内部 Form 组件
- **类型:** `Object`
## width ## width
- **详情:** 弹窗宽度 - **详情:** 弹窗宽度
@ -67,28 +85,45 @@ const values = ref([
- **详情:** - **详情:**
表单域标签的宽度,例如 '50px'。 作为 Form 直接子元素的 form-item 会继承该值。 支持 auto 表单域标签的宽度,例如 '50px'。 作为 Form 直接子元素的 form-item 会继承该值。 支持 auto
- **默认值:** `'200px'` - **默认值:** `'200px'`
- **类型:** `string | number` - **类型:** `string`
## fullscreen ## fullscreen
- **详情:** 弹出是否全屏 - **详情:** 是否全屏。
- **默认值:** false - **默认值:** false
- **类型:** boolean - **类型:** `boolean`
## disabled ## disabled
- **详情:** 是否禁用该表单内的所有组件。 若设置为 true则表单内组件上的 disabled 属性不再生效 - **详情:** 是否禁用该表单内的所有组件。 若设置为 true则表单内组件上的 disabled 属性不再生效
- **默认值:** false - **默认值:** false
- **类型:** `boolean` - **类型:** `boolean`
## inline
- **详情:** 行内表单模式
- **类型:** `boolean`
## labelPosition
- **详情:** 表单域标签的位置, 当设置为 left 或 right 时,则也需要设置 label-width 属性
- **类型:** `string`
## zIndex
- **详情:** 弹窗的 z-index
- **类型:** `number`
## title ## title
- **详情:** 弹出标题 - **详情:** 弹出标题
@ -108,3 +143,49 @@ const values = ref([
- **默认值:** `'确定'` - **默认值:** `'确定'`
- **类型:** `string` - **类型:** `string`
## preventSubmitDefault
- **详情:** 是否阻止内部 Form 原生 submit 事件的默认行为
- **类型:** `boolean`
## closeOnClickModal
- **详情:** 是否可以通过点击 modal 关闭 Dialog
- **默认值:** `false`
- **类型:** `boolean`
## closeOnPressEscape
- **详情:** 是否可以通过按下 ESC 关闭 Dialog
- **默认值:** `false`
- **类型:** `boolean`
## destroyOnClose
- **详情:** 关闭时销毁 Dialog 中的元素
- **默认值:** `false`
- **类型:** `boolean`
## showClose
- **详情:** 是否显示关闭按钮
- **默认值:** `true`
- **类型:** `boolean`
## showCancel
- **详情:** 是否显示底部取消按钮
- **默认值:** `true`
- **类型:** `boolean`

View File

@ -4,4 +4,46 @@
- **详情:** 表单中任何值发生变化 - **详情:** 表单中任何值发生变化
- **回调函数:** (values: any) => void - **事件回调函数:** `(values: any, eventData: ContainerChangeEventData) => void`
其中 `ContainerChangeEventData` 定义如下:
```ts
interface ChangeRecord {
propPath?: string;
value: any;
}
interface ContainerChangeEventData {
modifyKey?: string;
changeRecords?: ChangeRecord[];
}
```
## error
- **详情:** 表单校验失败时触发。回调收到的是 element-plus `validate` 返回的 `invalidFields` 结构(按字段名分组的校验失败项),而**不是** `Error` 实例
- **事件回调函数:** `(invalidFields: Record<string, { message: string; field: string }[]>) => void`
## field-input
- **详情:** 表单项 input 事件触发时由内部表单项向上派发,用于监听单个字段的输入
- **事件回调函数:** `(prop: string, value: any) => void`
## field-change
- **详情:** 表单项 change 事件触发时由内部表单项向上派发,用于监听单个字段的变更
- **事件回调函数:** 存在两种派发形式,监听时需注意区分:
- 大多数表单项(如 `Tabs``useImport` 等)派发的是 `(prop: string, value: any) => void`
- 表格类容器(`useSortable``useTableColumns` 等)会**只派发整行/整批数据**`(newData: any) => void`
如果只关心字段维度,可在回调里通过 `arguments.length === 1` 区分,或在表格类场景额外监听上层的 `change` 事件。
## update:stepActive
- **详情:** 当内部 step 容器切换步骤时触发。`Step.vue` 在点击步骤时派发的是 `index + 1``number`),文档类型保留 `string | number` 兼容父级初始传入
- **事件回调函数:** `(active: string | number) => void`

View File

@ -6,8 +6,66 @@
## submitForm ## submitForm
- **签名:** `async (native?: boolean) => Promise<any>`
- **参数:**
- `native?: boolean` - 是否返回原始表单值。当 `native``true` 时返回内部 `values.value`(响应式原值);否则返回 `cloneDeep(toRaw(values.value))`(深拷贝后的纯对象)
- **返回:** - **返回:**
- `{Promise<any>}` - `{Promise<any>}` - 校验通过后返回当前表单值;校验失败时会触发 `error` 事件并 throw 一个包含错误信息的 `Error`
- **详情:** 提交表单,获取表单的值 - **详情:** 提交表单,先执行校验,校验通过后清空 `changeRecords` 并返回当前表单值
- **相关:** 如果你想脱离组件树以函数方式完成一次表单提交,参见 [`submitForm` 函数](./submit-form.md)
## changeHandler
- **签名:** `(prop: string, value: any, eventData?: ContainerChangeEventData) => void`
- **详情:** 表单项值变更处理函数,会根据传入的 `propPath` 更新内部表单值,并向上 emit `change` 事件
## getTextByName
- **签名:** `(name: string) => string | undefined`
- **参数:**
- `name: string` - 字段名,支持点分隔的路径格式,如 `'a.b.c'`
- **返回:**
- `{string | undefined}` - 找到的 `text` 值,如果未找到则返回 `undefined`
- **详情:** 通过 `name` 从表单 `config` 中查找对应表单项的 `text`
## values
- **类型:** `Ref<FormValue>`
- **详情:** 当前表单值的响应式引用
## lastValuesProcessed
- **类型:** `Ref<FormValue>`
- **详情:** 对比模式下,处理后的待对比表单值
## formState
- **类型:** `FormState`
- **详情:** 内部使用的 formState 对象(`reactive`),通过 `provide('mForm')` 注入给子组件
## initialized
- **类型:** `Ref<boolean>`
- **详情:** 表单是否已经完成初始化
## changeRecords
- **类型:** `ShallowRef<ChangeRecord[]>`
- **详情:** 表单变更记录列表,提交成功或重置后会被清空

View File

@ -6,7 +6,19 @@
- **默认值:** `[]` - **默认值:** `[]`
- **类型:** [FormConfig](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/form/src/schema.ts#L706) - **类型:** `FormConfig`
::: details 查看 FormConfig 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FormConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItemConfig{ts}
<<< @/../packages/form-schema/src/base.ts#ChildConfig{ts}
<<< @/../packages/form-schema/src/base.ts#DynamicTypeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
- **示例:** - **示例:**
@ -16,19 +28,19 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'Vue'; import { ref } from "Vue";
const config = ref([ const config = ref([
{ {
name: 'text', name: "text",
text: '文本', text: "文本",
}, },
{ {
name: 'multiple', name: "multiple",
text: '多行文本', text: "多行文本",
type: 'switch', type: "switch",
}, },
]); ]);
</script> </script>
``` ```
@ -48,15 +60,77 @@ const config = ref([
</template> </template>
<script setup> <script setup>
import { ref } from 'Vue'; import { ref } from 'Vue';
const initValues = ref([ const initValues = ref([
text: 'text', text: 'text',
multiply: true, multiply: true,
]); ]);
</script> </script>
``` ```
## lastValues
- **详情:** 需对比的值(开启对比模式时传入)
- **默认值:** `{}`
- **类型:** `Object`
## isCompare
- **详情:** 是否开启对比模式
- **默认值:** `false`
- **类型:** `boolean`
## showDiff
- **详情:**
自定义“是否展示对比内容”的判断函数(仅在 `isCompare === true` 时生效)。
- 不传:使用默认逻辑 `!isEqual(curValue, lastValue)`(基于 lodash `isEqual`
- 传函数:完全以函数返回值为准,返回 `true` 才展示前后两份对比内容。
该 prop 通过 `formState` 透传到所有层级的 Container 中,调用方只需在 MForm 这一层传一次即可对整棵表单生效。
典型场景:某些字段语义上相等但结构不同(例如 `code-select` 字段中 `''``{ hookType: 'code', hookData: [] }` 应视为相等),调用方在此处显式声明,避免被 `isEqual` 误判为差异。
- **类型:** `(data: { curValue: any; lastValue: any; config: FormItemConfig }) => boolean`
- **示例:**
```html
<template>
<m-form :config="config" :is-compare="true" :last-values="lastValues" :show-diff="showDiff"></m-form>
</template>
<script setup>
import { isEqual } from 'lodash-es';
const showDiff = ({ curValue, lastValue, config }) => {
if (config?.type === 'code-select') {
// 业务侧自定义:双方都是“空形态”视为相等,不展示对比
const isEmpty = (v) =>
v === '' || v === undefined || v === null ||
(typeof v === 'object' && v.hookType === 'code' && Array.isArray(v.hookData) && v.hookData.length === 0);
if (isEmpty(curValue) && isEmpty(lastValue)) return false;
}
return !isEqual(curValue, lastValue);
};
</script>
```
## parentValues
- **详情:** 父级表单值
- **默认值:** `{}`
- **类型:** `Object`
## labelWidth ## labelWidth
- **详情:** - **详情:**
@ -65,7 +139,7 @@ const initValues = ref([
- **默认值:** `'200px'` - **默认值:** `'200px'`
- **类型:** `string | number` - **类型:** `string`
## disabled ## disabled
@ -77,27 +151,19 @@ const initValues = ref([
## height ## height
- **详情:** - **详情:** 表单容器的高度,会作为内联样式 `height` 应用到表单根元素上
- **默认值:** `'auto'`
- **类型:** `string`
- **默认值:**
- **类型:**
## stepActive ## stepActive
- **详情:** - **详情:** 当表单包含 step 容器时,控制当前激活的步骤
- **默认值:** `1`
- **类型:** `string | number`
- **默认值:**
- **类型:**
## size ## size
@ -105,7 +171,6 @@ const initValues = ref([
- **类型:** `'small' | 'default' | 'large'` - **类型:** `'small' | 'default' | 'large'`
## inline ## inline
- **详情:** 行内表单模式 - **详情:** 行内表单模式
@ -117,10 +182,9 @@ const initValues = ref([
## labelPosition ## labelPosition
- **详情:** 表单域标签的位置, 当设置为 left 或 right 时,则也需要设置 label-width 属性 - **详情:** 表单域标签的位置, 当设置为 left 或 right 时,则也需要设置 label-width 属性
- **默认值:** `'right'`
- **默认值:** right' - **类型:** `string`
- **类型:** `'left' | 'right' | 'top`
## keyProp ## keyProp
@ -135,3 +199,15 @@ const initValues = ref([
- **详情:** tooltip弹出层的class - **详情:** tooltip弹出层的class
- **类型:** `string` - **类型:** `string`
## preventSubmitDefault
- **详情:** 是否阻止表单原生 submit 事件的默认行为
- **类型:** `boolean`
## extendState
- **详情:** 扩展 formState 的钩子函数,返回的对象会被合并到 formState 上
- **类型:** `(state: FormState) => Record<string, any> | Promise<Record<string, any>>`

View File

@ -0,0 +1,218 @@
# submitForm 函数
以命令式方式调用 `MForm` 组件完成一次表单校验/提交,类似 `ElMessage` 的用法。
调用时函数内部会临时挂载一个不可见的 `MForm` 实例,把入参作为 props 透传给它,等待初始化完成后调用其 `submitForm` 方法。校验通过则 `resolve` 表单值,校验失败则 `reject` 错误信息,最后自动卸载实例并清理 DOM。
适用于一些没有合适的容器、但又需要复用 `MForm` 校验逻辑的场景,例如:
- 通过快捷菜单/命令面板触发一次性表单
- 在脚本/服务层完成一次表单值校验后再发请求
- 把 `config` 配置当作"可执行的校验规则"使用
## 签名
```ts
function submitForm(options: SubmitFormOptions): Promise<any>;
```
## 参数
`options``MForm` 组件的 props 基本对齐,额外提供了 `native``returnChangeRecords``appContext``timeout` 等参数。
| 名称 | 类型 | 默认值 | 说明 |
| ---------------------- | ------------------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| `config` | `FormConfig` | — | 必填,表单配置 |
| `initValues` | `Record<string, any>` | `{}` | 表单初始值 |
| `lastValues` | `Record<string, any>` | `{}` | 需对比的值(开启对比模式时传入) |
| `isCompare` | `boolean` | `false` | 是否开启对比模式 |
| `parentValues` | `Record<string, any>` | `{}` | 父级 values透传给字段的回调 |
| `labelWidth` | `string` | `'200px'` | label 宽度 |
| `disabled` | `boolean` | `false` | 是否禁用 |
| `height` | `string` | `'auto'` | 表单高度 |
| `stepActive` | `string \| number` | `1` | 步骤表单当前激活步骤 |
| `size` | `'small' \| 'default' \| 'large'` | — | 组件尺寸 |
| `inline` | `boolean` | `false` | 是否行内表单 |
| `labelPosition` | `string` | `'right'` | label 对齐方式 |
| `keyProp` | `string` | `'__key'` | 配置项的唯一 key |
| `popperClass` | `string` | — | 弹层 className |
| `preventSubmitDefault` | `boolean` | — | 是否阻止表单原生 submit |
| `extendState` | `(state: FormState) => Record<string, any> \| Promise<Record<string, any>>` | — | 扩展 `formState` |
| `native` | `boolean` | `false` | 透传给 `Form.submitForm``true` 时返回内部响应式 `values`,否则返回 `cloneDeep(toRaw(values))` |
| `returnChangeRecords` | `boolean` | `false` | `true` 时 resolve 结果为 `{ values, changeRecords }`,携带表单变更记录;否则仅 resolve `values` |
| `appContext` | `AppContext \| null` | `null` | 父级 Vue 应用上下文。需要继承全局组件、指令、provide 等时传入,常通过 `app._context``getCurrentInstance()?.appContext` 获取 |
| `timeout` | `number` | `10000` | 等待表单初始化的最长时间(毫秒)。超时将以错误 reject。设为 `<= 0` 时关闭超时兜底 |
## 返回值
- `校验通过``Promise<any>` resolve 当前表单值(`native` 决定是否克隆);当 `returnChangeRecords``true`resolve `{ values, changeRecords }`
- `校验失败``Promise<any>` reject 一个 `Error``message` 中包含逐条字段错误信息(格式 `${text} -> ${message}`,多条用 `<br>` 分隔)
- `初始化超时``Promise<any>` reject `Error('submitForm timeout after ${timeout}ms: form is not initialized.')`
无论成功或失败,函数都会在最后自动 `unmount` 内部 app 并移除挂载用的 DOM 容器,无需调用方手动清理。
::: tip 关于 changeRecords
`changeRecords` 记录的是表单挂载后发生的字段变更(由各字段的 `change` 事件累积而来)。在 `submitForm` 这种命令式、无用户交互的场景下,通常为空数组;只有在 `extendState` 或字段联动等逻辑中触发了变更时才会有内容。`MForm` 内部的 `submitForm` 在校验通过后会清空变更记录,因此本函数会在调用前先对其做快照再返回。
:::
## 基础用法
```ts
import { submitForm } from '@tmagic/form';
try {
const values = await submitForm({
config: [
{
type: 'text',
name: 'username',
text: '用户名',
rules: [{ required: true, message: '请输入用户名' }],
},
],
initValues: { username: '' },
});
console.log('提交成功', values);
} catch (e) {
console.error('校验失败', e);
}
```
## 同时获取变更记录changeRecords
设置 `returnChangeRecords: true`resolve 的结果会从单纯的 `values` 变为 `{ values, changeRecords }`
```ts
import { submitForm } from '@tmagic/form';
const { values, changeRecords } = await submitForm({
config: [{ type: 'text', name: 'username', text: '用户名' }],
initValues: { username: 'foo' },
returnChangeRecords: true,
});
console.log(values); // { username: 'foo' }
console.log(changeRecords); // ChangeRecord[]
```
## 在组件中继承父级应用上下文
`MForm` 内部使用 `@tmagic/design` 的组件(背后可能是 `element-plus``tdesign`),需要宿主应用先完成相应的 `app.use(...)` 安装。在 `submitForm` 这种脱离常规组件树的命令式调用中,可通过 `appContext` 把父级应用上下文带过去:
```vue
<script setup lang="ts">
import { getCurrentInstance } from 'vue';
import { submitForm } from '@tmagic/form';
const { appContext } = getCurrentInstance()!;
const onClick = async () => {
const values = await submitForm({
config: [{ type: 'text', name: 'text', text: '文本' }],
initValues: { text: 'hello' },
appContext,
});
console.log(values);
};
</script>
```
也可以在初始化 app 时把上下文缓存下来,再在任意位置复用:
```ts
import { createApp } from 'vue';
import ElementPlus from 'element-plus';
import MagicForm, { type SubmitFormOptions, submitForm as rawSubmitForm } from '@tmagic/form';
import App from './App.vue';
const app = createApp(App);
app.use(ElementPlus);
app.use(MagicForm);
app.mount('#app');
export const submitForm = (options: Omit<SubmitFormOptions, 'appContext'>) =>
rawSubmitForm({ ...options, appContext: app._context });
```
## 处理校验错误
校验失败时 reject 的 `Error.message` 已经把出错字段拼好,可以直接展示到用户:
```ts
import { tMagicMessage } from '@tmagic/design';
try {
const values = await submitForm({ config, initValues });
await save(values);
} catch (e: any) {
tMagicMessage.error({
dangerouslyUseHTMLString: true,
message: e.message,
});
}
```
## 运行环境
`submitForm` 内部依赖 `document` / `window` 来挂载临时 Vue 实例,因此**只能在浏览器或具备 DOM 环境的运行时中使用**。
| 环境 | 是否可用 | 说明 |
| ----------------------------------------------- | -------- | --------------------------------------------------------------------------------- |
| 浏览器 / Electron 渲染进程 / 浏览器扩展 | ✅ | 直接可用 |
| Vitest / Jest + `happy-dom` / `jsdom` | ✅ | 项目自身的单测就跑在这种环境下 |
| 纯 Node.js / Bun / Deno无 DOM polyfill | ❌ | 模块顶层就会读 `document`,会抛 `document is not defined` |
| Node.js + 手动注入 `happy-dom` / `jsdom` | ⚠️ | 可用,需要在 import `@tmagic/form` **之前**完成全局变量注入;校验行为不一定与浏览器完全一致 |
### 在 Node.js 中使用(需要先准备 DOM
下面是一个在 Node 脚本里调用 `submitForm` 的完整例子,使用 [`happy-dom`](https://github.com/capricorn86/happy-dom) 作为 DOM polyfill
```ts
// scripts/check-form.ts
import { Window } from 'happy-dom';
const window = new Window();
Object.assign(globalThis, {
window,
document: window.document,
navigator: window.navigator,
HTMLElement: window.HTMLElement,
});
// 注意DOM polyfill 必须先注入到 globalThis再用动态 import
// 加载业务模块,否则 @tmagic/design 等模块顶层执行时就会读 document
const { createApp } = await import('vue');
const ElementPlus = (await import('element-plus')).default;
const MagicForm = (await import('@tmagic/form')).default;
const { submitForm } = await import('@tmagic/form');
const parentApp = createApp({ render: () => null });
parentApp.use(ElementPlus);
parentApp.use(MagicForm);
const values = await submitForm({
config: [{ type: 'text', name: 'username', text: '用户名' }],
initValues: { username: 'foo' },
appContext: parentApp._context,
});
console.log(values);
```
::: warning 注意
- DOM polyfill 必须在 **import 业务模块之前** 注入到 `globalThis`,否则模块顶层执行时仍会失败
- 在 `happy-dom` / `jsdom` 中,`element-plus` 的部分 `validate()` 行为不一定能 1:1 复现真实浏览器(例如某些场景下必填规则可能不触发),建议关键校验使用自定义 `validator` 函数确保稳定
- 如果只是想在 Node 端做一次纯校验,更稳妥的做法是直接复用 [`async-validator`](https://github.com/yiminghe/async-validator)element-plus 内部用的就是它),绕开整个 Vue 渲染层
:::
## 类型定义
::: details 查看 `SubmitFormOptions` 类型定义
<<< @/../packages/form/src/submitForm.ts#SubmitFormOptions{ts}
:::
::: details 查看 `SubmitFormResult` 类型定义
<<< @/../packages/form/src/submitForm.ts#SubmitFormResult{ts}
:::

View File

@ -1,21 +1,96 @@
# stage事件 # stage事件
## runtime-ready
## mounted ## mounted
## highlight - **参数**:(无)
- **详情**stage 挂载完成后触发
## update ## runtime-ready
- **参数**
- `runtime: Runtime`runtime 实例
- **详情**runtime 准备就绪时触发
## page-el-update
- **参数**
- `el: HTMLElement`:当前页面的根节点元素
- **详情**当前页面的根节点变化时触发stage 会同步根节点和画布的大小
## change-guides
- **参数**
- `data: GuidesEventData`:参考线数据,包含 `type`(参考线方向)和 `guides`(参考线位置数组)
- **详情**:参考线变化时触发
## select ## select
- **参数**
- `el: HTMLElement`:被选中的元素
- `event: MouseEvent`:触发选中的鼠标事件
- **详情**:单选选中元素时触发
## multi-select ## multi-select
## select-parent - **参数**
- `els: HTMLElement[]`:被选中的元素列表
- `event: MouseEvent`:触发选中的鼠标事件
- **详情**:多选选中元素时触发
## sort ## dblclick
- **参数**
- `event: MouseEvent`:鼠标双击事件
- **详情**:画布元素被双击时触发
## update ## update
## change-guides - **参数**
- `data: UpdateEventData`:更新事件数据,包含被更新的元素及其样式信息(`width``height``left``top``transform` 等)和 `parentEl`
- **详情**:拖拽/缩放等操作更新组件时触发
## sort
- **参数**
- `data: SortEventData`:排序数据,包含 `src`(源节点 id`dist`(目标节点 id以及 `root`
- **详情**:组件排序变化时触发
## select-parent
- **参数**:(无)
- **详情**:触发选中父级节点时抛出
## rerender
- **参数**:(无)
- **详情**:需要重新渲染画布时触发
## remove
- **参数**
- `data: RemoveEventData`:被移除元素的数据
- **详情**:从画布删除组件时触发
## highlight
- **参数**
- `el: HTMLElement`:被高亮的元素
- **详情**:高亮元素时触发
## mousemove
- **参数**
- `event: MouseEvent`:鼠标移动事件
- **详情**:鼠标在画布上移动**且命中带 magic id 的节点元素**时触发;若 `getElementFromPoint` 拿不到带 id 的节点(例如悬空在画布空白处),则不会派发该事件
## mouseleave
- **参数**
- `event: MouseEvent`:鼠标离开事件
- **详情**:鼠标离开画布时触发
## drag-start
- **参数**
- `event: OnDragStart`moveable 的拖拽开始事件
- **详情**:开始拖拽元素时触发

View File

@ -2,47 +2,78 @@
## select ## select
- **详情:** 单选选中元素 - **类型**`(id: Id, event?: MouseEvent) => Promise<void>`
- **参数**
- `id`:选中节点的 id
- `event`:触发选中的鼠标事件(可选)
- **详情**:单选选中元素
## multiSelect ## multiSelect
- **详情:** 多选选中多个元素 - **类型**`(ids: Id[]) => Promise<void>`
- **参数**
- `ids`:选中元素的 id 列表
- **详情**:多选选中多个元素
## highlight ## highlight
- **详情:** 高亮选中元素 - **类型**`(id: Id) => void`
- **参数**
- `id`:要高亮的节点 id
- **详情**:按 id 高亮节点
## clearHighlight
- **类型**`() => void`
- **详情**:清除高亮
## update ## update
- **详情:** 更新组件 - **类型**`(data: UpdateData) => Promise<void>`
- **参数**
- `data`:更新组件所需的数据,包含 `config``parent``parentId``root` 等字段
- **详情**:更新组件
## add ## add
- **详情:** 往画布增加一个组件 - **类型**`(data: UpdateData) => Promise<void>`
- **参数**
- `data`:组件信息数据,包含要新增组件的 `config``parent``parentId``root` 等字段
- **详情**:往画布增加一个组件
## remove ## remove
- **详情:** 从画布删除一个组件 - **类型**`(data: RemoveData) => Promise<void>`
- **参数**
- `data`:组件信息数据,包含要删除组件的 `id``parentId``root` 等字段
- **详情**:从画布删除一个组件
## setZoom ## setZoom
- **详情:** - **类型**`(zoom?: number) => void`
- **参数**
- `zoom`:缩放比例,缺省时使用 `DEFAULT_ZOOM`
- **详情**:设置画布缩放比例
## mount ## mount
- **详情:** 挂载Dom节点 - **类型**`(el: HTMLDivElement) => Promise<void>`
- **参数**
- `el`:将 stage 挂载到该 Dom 节点上
- **详情**:挂载 Dom 节点
## clearGuides ## clearGuides
- **详情:** 清空所有参考线 - **类型**`() => void`
- **详情**:清空所有参考线
## clearGuides
- **详情:** 清空所有参考线
## delayedMarkContainer ## delayedMarkContainer
- **详情:** - **类型**`(event: MouseEvent, excludeElList?: Element[]) => NodeJS.Timeout | undefined`
- **参数**
- `event`:鼠标事件
- `excludeElList`:计算鼠标所在容器时要排除的元素列表
- **详情**
鼠标拖拽着元素在容器上方悬停延迟一段时间后对容器进行标记如果悬停时间够长将标记成功悬停时间短调用方通过返回的timeoutId取消标记 鼠标拖拽着元素在容器上方悬停延迟一段时间后对容器进行标记如果悬停时间够长将标记成功悬停时间短调用方通过返回的timeoutId取消标记
@ -52,7 +83,61 @@
2、释放鼠标后通过标记的标志找到要加入的容器 2、释放鼠标后通过标记的标志找到要加入的容器
## getAddContainerHighlightClassNameTimeout
- **类型**`(event: MouseEvent, excludeElList?: Element[]) => NodeJS.Timeout | undefined`
- **参数**
- `event`:鼠标事件
- `excludeElList`:计算鼠标所在容器时要排除的元素列表
- **详情**@deprecated 废弃接口,建议用 [delayedMarkContainer](#delayedmarkcontainer) 代替
## getMoveableOption
- **类型**`<K extends keyof MoveableOptions>(key: K) => MoveableOptions[K] | undefined`
- **参数**:
- `key`:要获取的 moveable 配置项名称
- **详情**:获取 moveable 配置项的当前值
## getDragStatus
- **类型**`() => StageDragStatus | undefined`
- **详情**:获取当前画布的拖拽状态
## disableMultiSelect
- **类型**`() => void`
- **详情**:禁用多选能力
## enableMultiSelect
- **类型**`() => void`
- **详情**:启用多选能力
## setAlwaysMultiSelect
- **类型**`(value: boolean) => void`
- **参数**
- `value`:是否始终启用多选模式(无需按住 `Ctrl/Meta` 键)
- **详情**:设置是否始终启用多选模式。当多选被 `disableMultiSelect` 禁用时,本方法不会启用多选
## reloadIframe
- **类型**`(url: string) => void`
- **参数**
- `url`:重新加载的 runtime 地址
- **详情**:重新加载 runtime iframe
## getElementImage
- **类型**`(id: Id, type?: 'download' | 'raw' | 'svg' | 'canvas' | 'png' | 'jpeg' | 'webp' | 'blob', options?: SnapdomOptions) => Promise<any>`
- **参数**
- `id`:要截图的节点 id
- `type`:导出类型,默认为 `'png'`
- `options`[snapdom](https://github.com/zumerlab/snapdom) 选项
- **详情**:将指定 id 的 dom 元素生成为图片
## destroy ## destroy
- **详情:** 销毁实例 - **类型**`() => void`
- **详情**:销毁实例

View File

@ -20,15 +20,30 @@
## after-action ## after-action
- **参数:** - **参数:**
- `action: string` - 操作类型 - `payload: { index: number }` - 触发动作所在行的索引
- `data: any` - 操作相关数据
- **说明:** 表格操作完成后触发 - **说明:** 表格行的编辑型动作(如 actions 中 `type: 'edit'` 的保存)执行结束后触发。
注意:`ActionsColumn` 在 handler 返回值为「假值」(如 `undefined`/`null`/未返回)时同样会派发该事件;**仅当**返回值为对象且 `res.ret !== 0` 时才视为失败、不派发。如果业务需要严格在「业务接口成功」后再处理,应在 handler 内显式 `return { ret: 0 }` 并在监听处自行判断 `res.ret`
- **示例:** - **示例:**
```js ```js
const handleAfterAction = (action, data) => { const handleAfterAction = ({ index }) => {
console.log('操作完成:', action, data); console.log('操作完成,行索引:', index);
};
```
## after-action-cancel
- **参数:**
- `payload: { index: number }` - 触发动作所在行的索引
- **说明:** 表格行的编辑型动作被取消后触发
- **示例:**
```js
const handleAfterActionCancel = ({ index }) => {
console.log('操作取消,行索引:', index);
}; };
``` ```

View File

@ -4,22 +4,21 @@
- **详情:** 表格数据,数组格式 - **详情:** 表格数据,数组格式
- **默认值:** `[]` - **必填:** 是
- **类型:** `Array<any>` - **类型:** `Array<any>`
- **示例:** - **示例:**
```js ```js
[ [
{ id: 1, name: '张三', age: 20 }, { id: 1, name: "张三", age: 20 },
{ id: 2, name: '李四', age: 25 } { id: 2, name: "李四", age: 25 },
] ];
``` ```
## columns ## columns
- **详情:** 表格列配置 - **详情:** 表格列配置
- **默认值:** `[]` - **默认值:** `[]`
- **类型:** `Array<ColumnConfig>` - **类型:** `Array<ColumnConfig>`
@ -27,22 +26,20 @@
- **示例:** - **示例:**
```js ```js
[ [
{ prop: 'name', label: '姓名', width: 120 }, { prop: "name", label: "姓名", width: 120 },
{ prop: 'age', label: '年龄', width: 80 } { prop: "age", label: "年龄", width: 80 },
] ];
``` ```
## spanMethod ## spanMethod
- **详情:** 合并行或列的计算方法 - **详情:** 合并行或列的计算方法
- **默认值:** `undefined` - **默认值:** `undefined`
- **类型:** `Function` - **类型:** `Function`
- **参数:** - **参数:**
- `{ row, column, rowIndex, columnIndex }` - `{ row, column, rowIndex, columnIndex }`
- **返回值:** `[rowspan, colspan]``{ rowspan, colspan }` - **返回值:** `[rowspan, colspan]``{ rowspan, colspan }`
- **示例:** - **示例:**
@ -55,13 +52,12 @@
return [0, 0]; return [0, 0];
} }
} }
} };
``` ```
## loading ## loading
- **详情:** 是否显示加载状态 - **详情:** 是否显示加载状态
- **默认值:** `false` - **默认值:** `false`
- **类型:** `boolean` - **类型:** `boolean`
@ -69,7 +65,6 @@
## showHeader ## showHeader
- **详情:** 是否显示表头 - **详情:** 是否显示表头
- **默认值:** `true` - **默认值:** `true`
- **类型:** `boolean` - **类型:** `boolean`
@ -77,21 +72,19 @@
## bodyHeight ## bodyHeight
- **详情:** Table 的最大高度。合法的值为数字或者单位为 px 的高度 - **详情:** Table 的最大高度。合法的值为数字或者单位为 px 的高度
- **默认值:** `undefined` - **默认值:** `undefined`
- **类型:** `string | number` - **类型:** `string | number`
- **示例:** - **示例:**
```js ```js
bodyHeight: 400 bodyHeight: 400;
bodyHeight: '400px' bodyHeight: "400px";
``` ```
## emptyText ## emptyText
- **详情:** 空数据时显示的文本内容 - **详情:** 空数据时显示的文本内容
- **默认值:** `'暂无数据'` - **默认值:** `'暂无数据'`
- **类型:** `string` - **类型:** `string`
@ -99,7 +92,6 @@
## defaultExpandAll ## defaultExpandAll
- **详情:** 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 - **详情:** 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效
- **默认值:** `false` - **默认值:** `false`
- **类型:** `boolean` - **类型:** `boolean`
@ -107,7 +99,6 @@
## rowkeyName ## rowkeyName
- **详情:** 行数据的 Key用来优化 Table 的渲染 - **详情:** 行数据的 Key用来优化 Table 的渲染
- **默认值:** `'id'` - **默认值:** `'id'`
- **类型:** `string` - **类型:** `string`
@ -117,7 +108,6 @@
## border ## border
- **详情:** 是否显示边框 - **详情:** 是否显示边框
- **默认值:** `false` - **默认值:** `false`
- **类型:** `boolean` - **类型:** `boolean`

View File

@ -1,7 +1,30 @@
# 表单对比 # 表单对比
tmagic-form可以支持两个版本的表单值对比如果有容器嵌套将在tab标签页展示对应tab下存在的差异数便于在复杂嵌套表单场景下直观的看到差异情况 tmagic-form可以支持两个版本的表单值对比如果有容器嵌套将在tab标签页展示对应tab下存在的差异数便于在复杂嵌套表单场景下直观的看到差异情况
## 使用方法 ## 使用方法
在初始化表单时,需要传入当前版本的表单值,上一版本的表单值,以及表单配置,具体可参见[Form Playground](https://tencent.github.io/tmagic-editor/playground/index.html#/form)的demo演示 在初始化表单时,开启对比模式 `is-compare`,并传入当前版本的表单值(`init-values`)、上一版本的表单值(`last-values`)以及表单配置,具体可参见[Form Playground](https://tencent.github.io/tmagic-editor/playground/index.html#/form)的demo演示。
```html
<m-form
:config="config"
:is-compare="true"
:init-values="curValues"
:last-values="lastValues"
></m-form>
```
相关属性详见 Form 组件 props
- [`isCompare`](/api/form/form-props.html#iscompare):是否开启对比模式;
- [`lastValues`](/api/form/form-props.html#lastvalues):需对比的上一版本表单值;
- [`showDiff`](/api/form/form-props.html#showdiff):自定义「是否展示对比内容」的判断函数,用于规避语义相等但结构不同导致的误判。
## 对比模式下的字段行为
对比模式下,表单仅做只读展示:增删、复制、排序、导入、编辑等写操作按钮会被隐藏。对于由列表或嵌套子表单组成的复合字段(如 `event-select``code-select``code-select-col`),表单会按索引对齐前后值,逐项展示新增 / 删除 / 修改的高亮差异,而不会渲染出两套独立组件。
## 应用场景
编辑器的[历史记录面板](/guide/advanced/history-list.md)即基于该能力,对历史步骤的前后值做表单形式的差异对比。
## 效果展示 ## 效果展示
<img src="https://vip.image.video.qpic.cn/vupload/20230301/c626071677661813135.png" alt="表单对比"/> <img src="https://vip.image.video.qpic.cn/vupload/20230301/c626071677661813135.png" alt="表单对比"/>

View File

@ -28,11 +28,34 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ----------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| formTitle | 弹窗标题 | string | — | — | | formTitle | 弹窗标题 | string | — | — |
| codeOptions | 代码编辑器配置项 | object | — | — | | codeOptions | 代码编辑器配置项 | object | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 CodeLinkConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#CodeLinkConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -28,10 +28,33 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ----------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| notEditable | 是否不可编辑代码块disable控制是否可选择 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | notEditable | 是否不可编辑代码块disable控制是否可选择 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 CodeSelectColConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#CodeSelectColConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -19,15 +19,39 @@
## 功能说明 ## 功能说明
CodeSelect 组件支持: CodeSelect 组件支持:
- 选择代码块 - 选择代码块
- 选择数据源方法 - 选择数据源方法
- 配置代码块参数 - 配置代码块参数
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | --------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| className | 自定义类名 | string | — | — | | className | 自定义类名 | string | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 CodeSelectConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#CodeSelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -10,7 +10,7 @@
```js ```js
{ {
type: 'code', type: 'vs-code',
name: 'code', name: 'code',
text: '代码' text: '代码'
} }
@ -20,7 +20,7 @@
```js ```js
{ {
type: 'code', type: 'vs-code',
name: 'code', name: 'code',
text: '代码', text: '代码',
language: 'javascript' language: 'javascript'
@ -31,7 +31,7 @@
```js ```js
{ {
type: 'code', type: 'vs-code',
name: 'code', name: 'code',
text: '代码', text: '代码',
autosize: { autosize: {
@ -42,20 +42,45 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| language | 代码语言 | string | javascript/typescript/json等 | — | | language | 代码语言 | string | javascript/typescript/json等 | — |
| height | 编辑器高度 | string | — | — | | height | 编辑器高度 | string | — | — |
| parse | 是否解析代码 | boolean | — | false | | parse | 是否解析代码 | boolean | — | false |
| options | 编辑器配置项 | object | — | — | | options | 编辑器配置项 | object | — | — |
| autosize | 自动调整大小配置 | object | — | — | | autosize | 自动调整大小配置 | object | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | mFormItemType | 传入代码编辑器的自定义类型 | string | — | — |
| onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 CodeConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#CodeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## autosize Attributes ## autosize Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ------- | -------- | ------ | ------ | ------ |
| minRows | 最小行数 | number | — | — | | minRows | 最小行数 | number | — | — |
| maxRows | 最大行数 | number | — | — | | maxRows | 最大行数 | number | — | — |

View File

@ -10,7 +10,7 @@
```js ```js
{ {
type: 'cond-op', type: 'cond-op-select',
name: 'op', name: 'op',
text: '操作符' text: '操作符'
} }
@ -20,7 +20,7 @@
```js ```js
{ {
type: 'cond-op', type: 'cond-op-select',
name: 'op', name: 'op',
text: '操作符', text: '操作符',
parentFields: ['field1', 'field2'] parentFields: ['field1', 'field2']
@ -28,10 +28,33 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ------------ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| parentFields | 父级字段 | string[] | — | — | | parentFields | 父级字段 | string[] | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 CondOpSelectConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#CondOpSelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -50,18 +50,42 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| value | 返回值类型 | string | key/value | — | | value | 返回值类型 | string | key/value | — |
| checkStrictly | 是否严格遵守父子节点不互相关联 | boolean / Function | — | — | | checkStrictly | 是否严格遵守父子节点不互相关联 | boolean / Function | — | — |
| dataSourceFieldType | 允许选择的字段类型 | DataSourceFieldType[] | — | — | | dataSourceFieldType | 允许选择的字段类型 | DataSourceFieldType[] | — | — |
| fieldConfig | 自定义字段配置 | ChildConfig | — | — | | fieldConfig | 自定义字段配置 | ChildConfig | — | — |
| notEditable | 是否不可编辑数据源disable控制是否可选择 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | notEditable | 是否不可编辑数据源disable控制是否可选择 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DataSourceFieldSelectConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DataSourceFieldSelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## value说明 ## value说明
- `key`: 不编译返回数据源id和字段name - `key`: 不编译返回数据源id和字段name
- `value`: 编译后返回数据源data[field] - `value`: 编译后返回数据源data[field]

View File

@ -17,9 +17,32 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DataSourceFieldsConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DataSourceFieldsConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -17,9 +17,32 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DataSourceInputConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DataSourceInputConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -28,10 +28,33 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ----------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| notEditable | 是否不可编辑数据源disable控制是否可选择 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | notEditable | 是否不可编辑数据源disable控制是否可选择 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DataSourceMethodSelectConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DataSourceMethodSelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -17,9 +17,32 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DataSourceMethodsConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DataSourceMethodsConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -17,9 +17,32 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DataSourceMocksConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DataSourceMocksConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -39,17 +39,43 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| dataSourceType | 数据源类型过滤 | string | base/http等 | — | | dataSourceType | 数据源类型过滤 | string | base/http等 | — |
| value | 返回值类型 | string | id/value | — | | value | 返回值类型 | string | id/value | — |
| notEditable | 是否不可编辑数据源disable控制是否可选择 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | notEditable | 是否不可编辑数据源disable控制是否可选择 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DataSourceSelect 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DataSourceSelect{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#Input{ts}
:::
## value说明 ## value说明
- `id`: 不编译返回数据源id - `id`: 不编译返回数据源id
- `value`: 编译后返回数据源data - `value`: 编译后返回数据源data

View File

@ -28,11 +28,34 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ------------ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| titlePrefix | 标题前缀 | string | — | — | | titlePrefix | 标题前缀 | string | — | — |
| parentFields | 父级字段 | string[] / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | — | | parentFields | 父级字段 | string[] / `FilterFunction` | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DisplayCondsConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#DisplayCondsConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -29,11 +29,12 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ---------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| src | 事件来源 | string | datasource/component | — | | src | 事件来源 | string | datasource/component | — |
| labelWidth | 标签宽度 | string | — | — | | labelWidth | 标签宽度 | string | — | — |
| eventNameConfig | 事件名称表单配置 | FormItem | — | — | | eventNameConfig | 事件名称表单配置 | FormItem | — | — |
@ -42,8 +43,31 @@
| compActionConfig | 联动组件动作配置 | FormItem | — | — | | compActionConfig | 联动组件动作配置 | FormItem | — | — |
| codeActionConfig | 联动代码配置 | FormItem | — | — | | codeActionConfig | 联动代码配置 | FormItem | — | — |
| dataSourceActionConfig | 联动数据源配置 | FormItem | — | — | | dataSourceActionConfig | 联动数据源配置 | FormItem | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 EventSelectConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#EventSelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## src说明 ## src说明
- `component`: 组件事件 - `component`: 组件事件
- `datasource`: 数据源事件 - `datasource`: 数据源事件

View File

@ -30,10 +30,33 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| advanced | 是否支持高级模式(代码编辑) | boolean | — | false | | advanced | 是否支持高级模式(代码编辑) | boolean | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 KeyValueConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#KeyValueConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -17,12 +17,35 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 PageFragmentSelectConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#PageFragmentSelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## 使用说明 ## 使用说明

View File

@ -17,12 +17,35 @@
``` ```
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 UISelectConfig 配置类型定义
<<< @/../packages/form-schema/src/editor.ts#UISelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## 使用说明 ## 使用说明

View File

@ -423,16 +423,40 @@ options 支持传入函数,可根据表单其他字段动态生成选项列表
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| multiple | 是否多选 | boolean | — | false | | multiple | 是否多选 | boolean | — | false |
| emitPath | 在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false则只返回该节点的值 | boolean | — | true | | emitPath | 在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false则只返回该节点的值 | boolean | — | true |
| checkStrictly | 是否严格的遵守父子节点不互相关联 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | false | | checkStrictly | 是否严格的遵守父子节点不互相关联 | boolean / `FilterFunction` | — | false |
| valueSeparator | 合并成字符串时的分隔符 | string / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | — | | valueSeparator | 合并成字符串时的分隔符 | string / `FilterFunction` | — | — |
| popperClass | 弹出内容的自定义类名 | string | — | — | | popperClass | 弹出内容的自定义类名 | string | — | — |
| remote | 是否为远程搜索 | boolean | — | false | | remote | 是否为远程搜索 | boolean | — | false |
| options | 选项数据源 | Array / Function | — | — | | options | 选项数据源 | Array / Function | — | — |
| option | 远程选项配置 | Object | — | — | | option | 远程选项配置 | Object | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | — | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | — |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 CascaderConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#CascaderConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#Input{ts}
:::
## options item ## options item

View File

@ -154,12 +154,36 @@ options 支持函数形式,可根据表单状态动态生成选项。
|------|------|------|--------|--------| |------|------|------|--------|--------|
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| activeValue | 选中时的值 | string / number | — | truefilter 为 'number' 时默认 1 | | activeValue | 选中时的值 | string / number | — | truefilter 为 'number' 时默认 1 |
| inactiveValue | 未选中时的值 | string / number | — | falsefilter 为 'number' 时默认 0 | | inactiveValue | 未选中时的值 | string / number | — | falsefilter 为 'number' 时默认 0 |
| useLabel | 是否使用外部 label 显示 | boolean | — | false | | useLabel | 是否使用外部 label 显示 | boolean | — | false |
| filter | 值过滤器 | 'number' / Function | — | — | | filter | 值过滤器 | 'number' / Function | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | — | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | — |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 CheckboxConfig / CheckboxGroupConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#CheckboxConfig{ts}
<<< @/../packages/form-schema/src/base.ts#CheckboxGroupConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## CheckboxGroup Attributes ## CheckboxGroup Attributes
@ -167,9 +191,9 @@ options 支持函数形式,可根据表单状态动态生成选项。
|------|------|------|--------|--------| |------|------|------|--------|--------|
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| options | 选项列表 | Array / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | — | | options | 选项列表 | Array / `FilterFunction` | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | — | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | — |
## options item ## options item

View File

@ -69,9 +69,31 @@
|------|------|------|--------|--------| |------|------|------|--------|--------|
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| defaultValue | 默认颜色值 | string | — | — | | defaultValue | 默认颜色值 | string | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form-schema/src/base.ts) | — | — | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | — |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 ColorPickConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#ColorPickConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## 颜色格式说明 ## 颜色格式说明

View File

@ -9,11 +9,12 @@
name: 'date', name: 'date',
text: '日期选择器' text: '日期选择器'
}]"> }]">
<template #source> <template #source>
<p>
以日期为基本单位,基础的日期选择控件 <p>
</p> 以日期为基本单位,基础的日期选择控件
</template> </p>
</template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -24,11 +25,12 @@
text: '日期选择器', text: '日期选择器',
disabled: () => true disabled: () => true
}]"> }]">
<template #source> <template #source>
<p>
通过 <code>disabled</code> 属性禁用日期选择器 <p>
</p> 通过 <code>disabled</code> 属性禁用日期选择器
</template> </p>
</template>
</demo-block> </demo-block>
## 占位符 ## 占位符
@ -39,11 +41,12 @@
text: '日期选择器', text: '日期选择器',
placeholder: '请选择日期' placeholder: '请选择日期'
}]"> }]">
<template #source> <template #source>
<p>
通过 <code>placeholder</code> 属性设置输入框占位文本 <p>
</p> 通过 <code>placeholder</code> 属性设置输入框占位文本
</template> </p>
</template>
</demo-block> </demo-block>
## 日期格式 ## 日期格式
@ -57,7 +60,7 @@
::: :::
| 格式 | 含义 | 备注 | 举例 | | 格式 | 含义 | 备注 | 举例 |
|------|------|------|------| | ------ | ---------------- | ---------------------------------------------- | ------------- |
| `YYYY` | 年 | | 2017 | | `YYYY` | 年 | | 2017 |
| `M` | 月 | 不补0 | 1 | | `M` | 月 | 不补0 | 1 |
| `MM` | 月 | | 01 | | `MM` | 月 | | 01 |
@ -81,32 +84,56 @@
format: 'YYYY-MM-DD', format: 'YYYY-MM-DD',
valueFormat: 'x' valueFormat: 'x'
}]"> }]">
<template #source> <template #source>
<p>
设置 <code>valueFormat</code><code>timestamp</code>,绑定值将返回时间戳格式 <p>
</p> 设置 <code>valueFormat</code><code>timestamp</code>,绑定值将返回时间戳格式
</template> </p>
</template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | ----------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ---------- |
| name | 绑定值的字段名 | string | — | — | | name | 绑定值的字段名 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| format | 显示在输入框中的格式 | string | 见[日期格式](#日期格式) | YYYY/MM/DD | | format | 显示在输入框中的格式 | string | 见[日期格式](#日期格式) | YYYY/MM/DD |
| valueFormat | 绑定值的格式。不指定则绑定值为 Date 对象 | string | 见[日期格式](#日期格式) | YYYY/MM/DD | | valueFormat | 绑定值的格式。不指定则绑定值为 Date 对象 | string | 见[日期格式](#日期格式) | YYYY/MM/DD |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | — | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | — |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DateConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#DateConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#Input{ts}
:::
## TypeScript 定义 ## TypeScript 定义
```typescript ```typescript
interface DateConfig extends FormItem, Input { interface DateConfig extends FormItem, Input {
type: 'date'; type: "date";
format?: 'YYYY-MM-dd HH:mm:ss' | string; format?: "YYYY-MM-dd HH:mm:ss" | string;
valueFormat?: 'YYYY-MM-dd HH:mm:ss' | string; valueFormat?: "YYYY-MM-dd HH:mm:ss" | string;
} }
``` ```

View File

@ -9,11 +9,12 @@
name: 'daterange', name: 'daterange',
text: '日期范围' text: '日期范围'
}]"> }]">
<template #source> <template #source>
<p>
type为'daterange' <p>
</p> type为'daterange'
</template> </p>
</template>
</demo-block> </demo-block>
## 绑定多个字段 ## 绑定多个字段
@ -25,22 +26,46 @@
names: ['startTime', 'endTime'], names: ['startTime', 'endTime'],
text: '日期范围' text: '日期范围'
}]"> }]">
<template #source> <template #source>
<p>
配置 names 属性,将开始时间和结束时间分别绑定到 startTime 和 endTime 字段。 <p>
</p> 配置 names 属性,将开始时间和结束时间分别绑定到 startTime 和 endTime 字段。
</template> </p>
</template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | ----------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------------- |
| name | 绑定值(数组形式) | string | — | — | | name | 绑定值(数组形式) | string | — | — |
| names | 绑定值(拆分为两个字段) | string[] | — | — | | names | 绑定值(拆分为两个字段) | string[] | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| dateFormat | 日期格式 | string | — | YYYY/MM/DD | | dateFormat | 日期格式 | string | — | YYYY/MM/DD |
| timeFormat | 时间格式 | string | — | HH:mm:ss | | timeFormat | 时间格式 | string | — | HH:mm:ss |
| valueFormat | 绑定值的格式 | string | — | YYYY/MM/DD HH:mm:ss | | valueFormat | 绑定值的格式 | string | — | YYYY/MM/DD HH:mm:ss |
| defaultTime | 默认时间 | Date[] | — | — | | defaultTime | 默认时间 | Date[] | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DaterangeConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#DaterangeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -9,11 +9,12 @@
name: 'dateTime', name: 'dateTime',
text: '日期时间选择器' text: '日期时间选择器'
}]"> }]">
<template #source> <template #source>
<p>
通过设置 <code>type: 'datetime'</code> 使用日期时间选择器,可以同时选择日期和时间。 <p>
</p> 通过设置 <code>type: 'datetime'</code> 使用日期时间选择器,可以同时选择日期和时间。
</template> </p>
</template>
</demo-block> </demo-block>
## 带占位符 ## 带占位符
@ -24,11 +25,12 @@
text: '日期时间选择器', text: '日期时间选择器',
placeholder: '请选择日期时间' placeholder: '请选择日期时间'
}]"> }]">
<template #source> <template #source>
<p>
通过 <code>placeholder</code> 属性设置输入框的占位文本。 <p>
</p> 通过 <code>placeholder</code> 属性设置输入框的占位文本。
</template> </p>
</template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -39,11 +41,12 @@
text: '日期时间选择器', text: '日期时间选择器',
disabled: () => true disabled: () => true
}]"> }]">
<template #source> <template #source>
<p>
通过 <code>disabled</code> 属性禁用日期时间选择器,支持布尔值或函数。 <p>
</p> 通过 <code>disabled</code> 属性禁用日期时间选择器,支持布尔值或函数。
</template> </p>
</template>
</demo-block> </demo-block>
## 日期格式 ## 日期格式
@ -57,7 +60,7 @@
::: :::
| 格式 | 含义 | 备注 | 举例 | | 格式 | 含义 | 备注 | 举例 |
|------|------|------|------| | ------ | ---------------- | ------------------------------------- | ------------- |
| `YYYY` | 年 | | 2017 | | `YYYY` | 年 | | 2017 |
| `M` | 月 | 不补0 | 1 | | `M` | 月 | 不补0 | 1 |
| `MM` | 月 | | 01 | | `MM` | 月 | | 01 |
@ -83,22 +86,47 @@
format: 'YYYY-MM-DD HH:mm', format: 'YYYY-MM-DD HH:mm',
valueFormat: 'x' valueFormat: 'x'
}]"> }]">
<template #source> <template #source>
<p>
自定义格式化:显示格式为 <code>YYYY-MM-DD HH:mm</code>,绑定值格式为时间戳。 <p>
</p> 自定义格式化:显示格式为 <code>YYYY-MM-DD HH:mm</code>,绑定值格式为时间戳。
</template> </p>
</template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | ----------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------------- |
| name | 绑定值的字段名 | string | — | — | | name | 绑定值的字段名 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| format | 显示在输入框中的格式 | string | 见[日期格式](#日期格式) | YYYY/MM/DD HH:mm:ss | | format | 显示在输入框中的格式 | string | 见[日期格式](#日期格式) | YYYY/MM/DD HH:mm:ss |
| valueFormat | 绑定值的格式 | string | 见[日期格式](#日期格式) | YYYY/MM/DD HH:mm:ss | | valueFormat | 绑定值的格式 | string | 见[日期格式](#日期格式) | YYYY/MM/DD HH:mm:ss |
| defaultTime | 选择日期后的默认时间值 | Date | — | — | | defaultTime | 选择日期后的默认时间值 | Date | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | — | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | — |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 DateTimeConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#DateTimeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#Input{ts}
:::

View File

@ -1,18 +1,7 @@
# Display 只读文本 # Display 只读文本
用于显示,不可编辑 用于显示,不可编辑
## TS 定义
```typescript
interface Display extends FormItem {
type: 'display';
}
```
点击查看[FormItem](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts)的定义
## 基础用法 ## 基础用法
<demo-block type="form" :config="[{ <demo-block type="form" :config="[{
@ -21,16 +10,25 @@ interface Display extends FormItem {
text: '只读文本', text: '只读文本',
defaultValue: 'display' defaultValue: 'display'
}]"> }]">
<template #source> <template #source>
<p> <p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag 在开启多选模式后默认情况下会展示所有已选中的选项的Tag
</p> </p>
</template> </template>
</demo-block> </demo-block>
## Input Attributes ## Input Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ---- | -------- | ------ | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
## 配置类型
::: details 查看 DisplayConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#DisplayConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -9,8 +9,8 @@
name: 'type', name: 'type',
text: '类型', text: '类型',
options: [ options: [
{ label: '类型A', value: 'a' }, { text: '类型A', value: 'a' },
{ label: '类型B', value: 'b' } { text: '类型B', value: 'b' }
] ]
}, { }, {
type: 'dynamic-field', type: 'dynamic-field',
@ -50,3 +50,12 @@
| name | 字段名 | string | — | | name | 字段名 | string | — |
| label | 标签名 | string | — | | label | 标签名 | string | — |
| defaultValue | 默认值 | any | — | | defaultValue | 默认值 | any | — |
## 配置类型
::: details 查看 DynamicFieldConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#DynamicFieldConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -2,31 +2,30 @@
改值体现于最终提交的表单中用于例如编辑记录的id这种场景中 改值体现于最终提交的表单中用于例如编辑记录的id这种场景中
## TS 定义
```typescript
interface Hidden extends FormItem {
type: 'hidden';
}
```
点击查看[FormItem](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts)的定义
## 基础用法 ## 基础用法
<demo-block type="form" :config="[{ <demo-block type="form" :config="[{
type: 'hidden', type: 'hidden',
name: 'hidden' name: 'hidden'
}]"> }]">
<template #source> <template #source>
<p> <p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag 在开启多选模式后默认情况下会展示所有已选中的选项的Tag
</p> </p>
</template> </template>
</demo-block> </demo-block>
## Input Attributes ## Input Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ---- | ------ | ------ | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
## 配置类型
::: details 查看 HiddenConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#HiddenConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -2,27 +2,6 @@
用于显示,不可编辑 用于显示,不可编辑
## TS 定义
```typescript
interface Link extends FormItem {
type: 'link';
href?: string | typeof LinkHrefFunction;
css?: {
[key: string]: string | number;
};
disabledCss?: {
[key: string]: string | number;
};
formTitle?: string;
formWidth?: number | string;
displayText?: string | typeof LinkDisplayTextFunction;
form: FormConfig | typeof LinkFormFunction;
}
```
点击查看[FormItem](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts)的定义
## 基础用法 ## 基础用法
<demo-block type="form" :config="[{ <demo-block type="form" :config="[{
@ -31,11 +10,11 @@ interface Link extends FormItem {
text: '链接', text: '链接',
href: 'https://tencent.github.io/tmagic-editor/playground/index.html#/' href: 'https://tencent.github.io/tmagic-editor/playground/index.html#/'
}]"> }]">
<template #source> <template #source>
<p> <p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag 通过配置 href点击链接可跳转到指定地址。
</p> </p>
</template> </template>
</demo-block> </demo-block>
## 打开表单 ## 打开表单
@ -49,16 +28,25 @@ interface Link extends FormItem {
text: 'input' text: 'input'
}] }]
}]"> }]">
<template #source> <template #source>
<p> <p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag 通过配置 form点击链接打开一个弹窗表单进行编辑。
</p> </p>
</template> </template>
</demo-block> </demo-block>
## Input Attributes ## Input Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ---- | -------- | ------ | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
## 配置类型
::: details 查看 LinkConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#LinkConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -9,18 +9,42 @@
name: 'numberRange', name: 'numberRange',
text: '数字范围' text: '数字范围'
}]"> }]">
<template #source> <template #source>
<p>
type为'number-range' <p>
</p> type为'number-range'
</template> </p>
</template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | --------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值(数组形式 [min, max] | string | — | — | | name | 绑定值(数组形式 [min, max] | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| clearable | 是否可清空 | boolean | — | true | | clearable | 是否可清空 | boolean | — | true |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 NumberRangeConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#NumberRangeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -9,11 +9,12 @@
name: 'number', name: 'number',
text: '计数器' text: '计数器'
}]"> }]">
<template #source> <template #source>
<p>
type为'number' <p>
</p> type为'number'
</template> </p>
</template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -24,11 +25,12 @@
text: '计数器', text: '计数器',
disabled: () => true disabled: () => true
}]"> }]">
<template #source> <template #source>
<p>
disabled 属性接受一个 Boolean设置为 true 即可禁用整个组件,也可以接受一个返回 Boolean 的函数,如果你只需要控制数值在某一范围内,可以设置 min 属性和 max 属性,不设置 min 和 max 时,最小值为 0。 <p>
</p> disabled 属性接受一个 Boolean设置为 true 即可禁用整个组件,也可以接受一个返回 Boolean 的函数,如果你只需要控制数值在某一范围内,可以设置 min 属性和 max 属性,不设置 min 和 max 时,最小值为 0。
</template> </p>
</template>
</demo-block> </demo-block>
## 步数 ## 步数
@ -41,23 +43,46 @@
text: '计数器', text: '计数器',
step: 10 step: 10
}]"> }]">
<template #source> <template #source>
<p>
设置 step 属性可以控制步长,接受一个 Number 。 <p>
</p> 设置 step 属性可以控制步长,接受一个 Number 。
</template> </p>
</template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|----------|-------------- |----------|-------------------------------- |-------- | | ----------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | --------- |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| min | 设置计数器允许的最小值 | number | — | -Infinity | | min | 设置计数器允许的最小值 | number | — | -Infinity |
| max | 设置计数器允许的最大值 | number | — | Infinity | | max | 设置计数器允许的最大值 | number | — | Infinity |
| step | 计数器步长 | number | — | 1 | | step | 计数器步长 | number | — | 1 |
| tooltip | 输入框提示信息 | string | — | — | | tooltip | 输入框提示信息 | string | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 NumberConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#NumberConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -2,20 +2,6 @@
在一组备选项中进行单选 在一组备选项中进行单选
## TS 定义
```typescript
interface RadioGroup extends FormItem {
type: 'radio-group';
options: {
value: any;
text: string;
}[];
}
```
点击查看[FormItem](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts)的定义
## 基础用法 ## 基础用法
由于选项默认可见,不宜过多,若选项过多,建议使用 Select 选择器。 由于选项默认可见,不宜过多,若选项过多,建议使用 Select 选择器。
@ -29,11 +15,12 @@ interface RadioGroup extends FormItem {
{ text: '选项2', value: 2 } { text: '选项2', value: 2 }
] ]
}]"> }]">
<template #source> <template #source>
<p>
要使用 Radio 组件只需要配置type: 'radio-group'。 <p>
</p> 要使用 Radio 组件只需要配置type: 'radio-group'。
</template> </p>
</template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -50,18 +37,54 @@ interface RadioGroup extends FormItem {
], ],
disabled: () => true disabled: () => true
}]"> }]">
<template #source> <template #source>
<p>
只要在配置中设置 disabled 属性即可,它接受一个 Boolean true 为禁用,也可以接受一个返回 Boolean 的函数。 <p>
</p> 只要在配置中设置 disabled 属性即可,它接受一个 Boolean true 为禁用,也可以接受一个返回 Boolean 的函数。
</template> </p>
</template>
</demo-block> </demo-block>
## RadioGroup Attributes ## RadioGroup Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | --------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------- |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| childType | 子项展示形式 | string | default / button | default |
| options | 选项 | Array | — | - | | options | 选项 | Array | — | - |
| onChange | 值变化时触发的函数 | [OnChangeHandler ](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FormItem / FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 RadioGroupConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#RadioGroupConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## options item
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------- | ------------------------ | ------------------------- | ------ | ------ |
| value | 选项的值 | string / number / boolean | — | — |
| text | 选项的标签 | string | — | — |
| icon | 选项的图标组件 | any | — | — |
| tooltip | 鼠标悬停时显示的提示内容 | string | — | — |

View File

@ -16,11 +16,12 @@
{ text: '选项2', value: 2 } { text: '选项2', value: 2 }
] ]
}]"> }]">
<template #source> <template #source>
<p>
type为'select' <p>
</p> type为'select'
</template> </p>
</template>
</demo-block> </demo-block>
## 有禁用选项 ## 有禁用选项
@ -35,11 +36,12 @@
{ text: '选项2', value: 2, disabled: true } { text: '选项2', value: 2, disabled: true }
] ]
}]"> }]">
<template #source> <template #source>
<p>
在 opitons 选项配置中,设定 disabled 值为 true即可禁用该选项 <p>
</p> 在 options 选项配置中,设定 disabled 值为 true即可禁用该选项
</template> </p>
</template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -57,11 +59,12 @@
{ text: '选项2', value: 2 } { text: '选项2', value: 2 }
] ]
}]"> }]">
<template #source> <template #source>
<p>
为 el-select 设置 disabled 属性,则整个选择器不可用 <p>
</p> 为 el-select 设置 disabled 属性,则整个选择器不可用
</template> </p>
</template>
</demo-block> </demo-block>
## 基础多选 ## 基础多选
@ -110,11 +113,12 @@
} }
] ]
}]"> }]">
<template #source> <template #source>
<p>
配置group为true <p>
</p> 配置group为true
</template> </p>
</template>
</demo-block> </demo-block>
## 创建条目 ## 创建条目
@ -155,14 +159,16 @@
value: option => `${option.id}`, value: option => `${option.id}`,
} }
}]"> }]">
<template #source> <template #source>
<p>
配置remote为true然后配置option而不是options <p>
</p> 配置remote为true然后配置option而不是options
</template> </p>
</template>
</demo-block> </demo-block>
同时在 `src/main.ts` 中需要自定义实现请求 同时在 `src/main.ts` 中需要自定义实现请求
```typescript ```typescript
app.use(MagicForm, { app.use(MagicForm, {
request: async (options: any) => { request: async (options: any) => {
@ -176,24 +182,50 @@ app.use(MagicForm, {
::: :::
## Select Attributes ## Select Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | ----------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| multiple | 是否多选 | boolean | — | false | | multiple | 是否多选 | boolean | — | false |
| valueKey | 作为 value 唯一标识的键名,绑定值为对象类型时必填 | string | — | value | | valueKey | 作为 value 唯一标识的键名,绑定值为对象类型时必填 | string | — | value |
| allowCreate | 是否允许用户创建新条目 | boolean | — | false | | allowCreate | 是否允许用户创建新条目 | boolean | — | false |
| remote | 是否为远程搜索 | boolean | — | false | | remote | 是否为远程搜索 | boolean | — | false |
| group | 是否选择分组 | boolean | — | false | | group | 是否选择分组 | boolean | — | false |
| onChange | 值变化时触发的函数 | [OnChangeHandler ](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
| options | 选项 | Array | — | - | | options | 选项 | Array | — | - |
| option | 选项 | Object | — | - | | option | 选项 | Object | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 SelectConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#SelectConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#Input{ts}
:::
## options item ## options item
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | -------- | -------- | ---------- | -------------------- | ------ | --- |
| text | | 选项的标签 | string/number/object | — | — | | text | | 选项的标签 | string/number/object | — | — |
| value | 选项的值 | string | — | — | | value | 选项的值 | string | — | — |
| disabled | 是否禁用 | boolean | — | false | | disabled | 是否禁用 | boolean | — | false |
@ -201,8 +233,9 @@ app.use(MagicForm, {
| options | Array | — | — | — | | options | Array | — | — | — |
## option ## option
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | ----- | ----------------- | ---- | ------ | ------ |
| url | string | — | — | — | | url | string | — | — | — |
| root | string | — | — | — | | root | string | — | — | — |
| text | string / Function | — | — | — | | text | string / Function | — | — | — |

View File

@ -19,11 +19,11 @@
activeValue: 'on', activeValue: 'on',
inactiveValue: 'off' inactiveValue: 'off'
}]"> }]">
<template #source> <template #source>
<p> <p>
设置 activeValue 和 inactiveValue 属性,接受 Boolean , String 或 Number 类型的值。 设置 activeValue 和 inactiveValue 属性,接受 Boolean , String 或 Number 类型的值。
</p> </p>
</template> </template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -34,19 +34,32 @@
text: '开关', text: '开关',
disabled: true disabled: true
}]"> }]">
<template #source> <template #source>
<p> <p>
设置 disabled 属性,接受一个 Boolean设置 true 即可禁用。 设置 disabled 属性,接受一个 Boolean设置 true 即可禁用。
</p> </p>
</template> </template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | -------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| disabled | 是否禁用 | boolean / [Function](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| active-value | switch 打开时的值 | boolean / string / number | — | true | | active-value | switch 打开时的值 | boolean / string / number | — | true |
| inactive-value | switch 关闭时的值 | boolean / string / number | — | false | | inactive-value | switch 关闭时的值 | boolean / string / number | — | false |
::: details 查看 FilterFunction 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
:::
## 配置类型
::: details 查看 SwitchConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#SwitchConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -8,13 +8,13 @@
name: 'text', name: 'text',
text: '输入框' text: '输入框'
}]"> }]">
<template #source> <template #source>
<p>
Input输入框的type为'text', 是type的默认值所以可以不配置
</p>
</template>
</demo-block>
<p>
Input输入框的type为'text', 是type的默认值所以可以不配置
</p>
</template>
</demo-block>
## 禁用状态 ## 禁用状态
@ -23,11 +23,12 @@
text: '输入框', text: '输入框',
disabled: () => true disabled: () => true
}]"> }]">
<template #source> <template #source>
<p>
通过 disabled 属性指定是否禁用 input 组件 <p>
</p> 通过 disabled 属性指定是否禁用 input 组件
</template> </p>
</template>
</demo-block> </demo-block>
## 复合型输入框 ## 复合型输入框
@ -39,11 +40,12 @@
text: '重量', text: '重量',
append: '公斤' append: '公斤'
}]"> }]">
<template #source> <template #source>
<p>
可以通过配置append来增加一个后置内容。 <p>
</p> 可以通过配置append来增加一个后置内容。
</template> </p>
</template>
</demo-block> </demo-block>
<demo-block type="form" :config="[{ <demo-block type="form" :config="[{
@ -52,16 +54,17 @@
append: { append: {
type: 'button', type: 'button',
text: '操作', text: '操作',
handler: (vm) => { handler: (mForm, { model, values, formValue, setModel, setFormValue }) => {
vm.$message(vm.mForm.values.text); // 处理逻辑
} }
} }
}]"> }]">
<template #source> <template #source>
<p>
可以通过配置append来增加一个后置按钮。 <p>
</p> 可以通过配置append来增加一个后置按钮。
</template> </p>
</template>
</demo-block> </demo-block>
## 过滤内容 ## 过滤内容
@ -71,11 +74,12 @@
text: '输入框', text: '输入框',
filter: 'number' filter: 'number'
}]"> }]">
<template #source> <template #source>
<p>
设置filter为'number',可以将值转换成数值,也可以配置一个函数来自由转换。 <p>
</p> 设置filter为'number',可以将值转换成数值,也可以配置一个函数来自由转换。
</template> </p>
</template>
</demo-block> </demo-block>
## 去掉首尾空格 ## 去掉首尾空格
@ -85,11 +89,12 @@
text: '输入框', text: '输入框',
trim: true trim: true
}]"> }]">
<template #source> <template #source>
<p>
设置trim为true',可以去掉首尾空格。 <p>
</p> 设置trim为true',可以去掉首尾空格。
</template> </p>
</template>
</demo-block> </demo-block>
## 显示详情 ## 显示详情
@ -99,31 +104,60 @@
text: '输入框', text: '输入框',
tooltip: true tooltip: true
}]"> }]">
<template #source> <template #source>
<p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag <p>
</p> 通过配置 tooltip在输入时显示提示内容。
</template> </p>
</template>
</demo-block> </demo-block>
## Input Attributes ## Input Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ----------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| clearable | 是否可清空 | boolean | — | true | | clearable | 是否可清空 | boolean | — | true |
| tooltip | 输入时显示内容 | string | — | — | | tooltip | 输入时显示内容 | string / `ToolTipConfigType` | — | — |
| trim | 是否去掉首尾空格 | boolean | — | false | | trim | 是否去掉首尾空格 | boolean | — | false |
| filter | 过滤值 | string / Function | number | - | | filter | 过滤值 | string / Function | number | - |
| prepend | 前置内容 | string | — | - | | prepend | 前置内容 | string | — | - |
| append | 后置内容 | string / Object | — | - | | append | 后置内容 | string / Object | — | - |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler / ToolTipConfigType 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
<<< @/../packages/form-schema/src/base.ts#ToolTipConfigType{ts}
:::
## 配置类型
::: details 查看 TextConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#TextConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#Input{ts}
:::
## append Attributes ## append Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ------- | -------- | -------- | ------ | ------ |
| type | 内容类型 | string | button | — | | type | 内容类型 | string | button | — |
| text | 文本内容 | string | — | — | | text | 文本内容 | string | — | — |
| handler | 点击操作 | Function | — | - | | handler | 点击操作 | Function | — | - |

View File

@ -7,11 +7,12 @@
name: 'textarea', name: 'textarea',
text: '文本域' text: '文本域'
}]"> }]">
<template #source> <template #source>
<p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag <p>
</p> 在开启多选模式后默认情况下会展示所有已选中的选项的Tag
</template> </p>
</template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -22,21 +23,45 @@
text: '文本域', text: '文本域',
disabled: () => true disabled: () => true
}]"> }]">
<template #source> <template #source>
<p>
通过 disabled 属性指定是否禁用 input 组件 <p>
</p> 通过 disabled 属性指定是否禁用 input 组件
</template> </p>
</template>
</demo-block> </demo-block>
## Input Attributes ## Input Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | | ----------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| trim | 是否去掉首尾空格 | boolean | — | false | | trim | 是否去掉首尾空格 | boolean | — | false |
| filter | 过滤值 | string / Function | number | - | | filter | 过滤值 | string / Function | number | - |
| onChange | 值变化时触发的函数 | [OnChangeHandler ](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 TextareaConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#TextareaConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -1,6 +1,6 @@
# TimePicker 时间选择器 # TimePicker 时间选择器
用于选择或输入日期 用于选择或输入日期
## 基础用法 ## 基础用法
@ -9,11 +9,11 @@
name: 'time', name: 'time',
text: '时间选择器' text: '时间选择器'
}]"> }]">
<template #source> <template #source>
<p> <p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag 在开启多选模式后默认情况下会展示所有已选中的选项的Tag
</p> </p>
</template> </template>
</demo-block> </demo-block>
## 禁用状态 ## 禁用状态
@ -24,18 +24,34 @@
text: '时间选择器', text: '时间选择器',
disabled: () => true disabled: () => true
}]"> }]">
<template #source> <template #source>
<p> <p>
在开启多选模式后默认情况下会展示所有已选中的选项的Tag 在开启多选模式后默认情况下会展示所有已选中的选项的Tag
</p> </p>
</template> </template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | ----------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |
| name | 绑定值 | string | — | — | | name | 绑定值 | string | — | — |
| placeholder | 输入框占位文本 | string | — | — | | placeholder | 输入框占位文本 | string | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [Function](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
::: details 查看 FilterFunction 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
:::
## 配置类型
::: details 查看 TimeConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#TimeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
<<< @/../packages/form-schema/src/base.ts#Input{ts}
:::

View File

@ -9,11 +9,12 @@
name: 'timerange', name: 'timerange',
text: '时间范围' text: '时间范围'
}]"> }]">
<template #source> <template #source>
<p>
type为'timerange' <p>
</p> type为'timerange'
</template> </p>
</template>
</demo-block> </demo-block>
## 绑定多个字段 ## 绑定多个字段
@ -25,21 +26,45 @@
names: ['startTime', 'endTime'], names: ['startTime', 'endTime'],
text: '时间范围' text: '时间范围'
}]"> }]">
<template #source> <template #source>
<p>
配置 names 属性,将开始时间和结束时间分别绑定到 startTime 和 endTime 字段。 <p>
</p> 配置 names 属性,将开始时间和结束时间分别绑定到 startTime 和 endTime 字段。
</template> </p>
</template>
</demo-block> </demo-block>
## Attributes ## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- | | ----------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -------- |
| name | 绑定值(数组形式) | string | — | — | | name | 绑定值(数组形式) | string | — | — |
| names | 绑定值(拆分为两个字段) | string[] | — | — | | names | 绑定值(拆分为两个字段) | string[] | — | — |
| text | 表单标签 | string | — | — | | text | 表单标签 | string | — | — |
| disabled | 是否禁用 | boolean / [FilterFunction](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | false | | disabled | 是否禁用 | boolean / `FilterFunction` | — | false |
| format | 显示格式 | string | — | HH:mm:ss | | format | 显示格式 | string | — | HH:mm:ss |
| valueFormat | 绑定值的格式 | string | — | HH:mm:ss | | valueFormat | 绑定值的格式 | string | — | HH:mm:ss |
| defaultTime | 默认时间 | Date[] | — | — | | defaultTime | 默认时间 | Date[] | — | — |
| onChange | 值变化时触发的函数 | [OnChangeHandler](https://github.com/Tencent/tmagic-editor/blob/master/packages/form/src/schema.ts) | — | - | | onChange | 值变化时触发的函数 | `OnChangeHandler` | — | - |
::: details 查看 FilterFunction / OnChangeHandler 及关联类型定义
<<< @/../packages/form-schema/src/base.ts#FilterFunction{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandler{ts}
<<< @/../packages/form-schema/src/base.ts#OnChangeHandlerData{ts}
<<< @/../packages/form-schema/src/base.ts#ChangeRecord{ts}
<<< @/../packages/form-schema/src/base.ts#FormValue{ts}
:::
## 配置类型
::: details 查看 TimerangeConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#TimerangeConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::

View File

@ -1,5 +1,36 @@
# 布局 # 布局
## 配置类型
::: details 查看 ContainerCommonConfig / RowConfig / TabConfig / TabPaneConfig / FieldsetConfig / PanelConfig / StepConfig / FlexLayoutConfig / GroupListConfig / TableConfig / TableColumnConfig / TableGroupListCommonConfig 配置类型定义
<<< @/../packages/form-schema/src/base.ts#ContainerCommonConfig{ts}
<<< @/../packages/form-schema/src/base.ts#RowConfig{ts}
<<< @/../packages/form-schema/src/base.ts#TabConfig{ts}
<<< @/../packages/form-schema/src/base.ts#TabPaneConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FieldsetConfig{ts}
<<< @/../packages/form-schema/src/base.ts#PanelConfig{ts}
<<< @/../packages/form-schema/src/base.ts#StepConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FlexLayoutConfig{ts}
<<< @/../packages/form-schema/src/base.ts#GroupListConfig{ts}
<<< @/../packages/form-schema/src/base.ts#TableConfig{ts}
<<< @/../packages/form-schema/src/base.ts#TableColumnConfig{ts}
<<< @/../packages/form-schema/src/base.ts#TableGroupListCommonConfig{ts}
<<< @/../packages/form-schema/src/base.ts#FormItem{ts}
:::
## 基础用法 ## 基础用法
<demo-block type="form" :config="[{ <demo-block type="form" :config="[{
@ -104,6 +135,18 @@
}] }]
}]"></demo-block> }]"></demo-block>
`legend` 除了支持字符串,也支持函数,函数返回值作为标题展示,可根据表单数据动态生成:
<demo-block type="form" :config="[{
type: 'fieldset',
labelWidth: '100px',
legend: (mForm, { formValue }) => `当前值:${formValue.text || '空'}`,
items: [{
name: 'text',
text: '配置1',
}]
}]"></demo-block>
### panel ### panel
<demo-block type="form" :config="[{ <demo-block type="form" :config="[{

View File

@ -9,7 +9,7 @@
}, { }, {
name: 'text2', name: 'text2',
text: '配置2', text: '配置2',
display: (state, { model }) => model.switch display: (mForm, { model }) => model.switch
}]"></demo-block> }]"></demo-block>
## 输入关联 ## 输入关联
@ -17,14 +17,14 @@
<demo-block type="form" :config="[{ <demo-block type="form" :config="[{
name: 'firstName', name: 'firstName',
text: '名', text: '名',
onChange: (state, v, { model }) => { onChange: (mForm, v, { model }) => {
model.fullName = `${model.lastName}${model.firstName}` model.fullName = `${model.lastName}${model.firstName}`
}, },
defaultValue: '三' defaultValue: '三'
}, { }, {
name: 'lastName', name: 'lastName',
text: '姓', text: '姓',
onChange: (state, v, { model }) => { onChange: (mForm, v, { model }) => {
model.fullName = `${model.lastName}${model.firstName}` model.fullName = `${model.lastName}${model.firstName}`
}, },
defaultValue: '张' defaultValue: '张'

View File

@ -10,7 +10,7 @@
下面将主要介绍代码块的实现原理包含dsl结构定义以及代码块挂载执行时机等 下面将主要介绍代码块的实现原理包含dsl结构定义以及代码块挂载执行时机等
## 协议描述 ## 协议描述
我们将在线编写的代码内容保存在[DSL](../advanced/js-schema.md)中与app同一层级这样的好处是代码块可以在同一活动不同页面中实现灵活编排。 我们将在线编写的代码内容保存在[DSL](../advanced/js-schema.md)中与app同一层级这样的好处是代码块可以在同一活动不同页面中实现灵活编排。
类型定义参见[CodeBlockDsl](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/schema/src/index.ts#L75)。 类型定义参见[CodeBlockDSL](https://github.com/Tencent/tmagic-editor/blob/master/packages/schema/src/index.ts)。
```javascript ```javascript
[{ [{
@ -36,14 +36,14 @@
}] }]
``` ```
在页面中创建代码块也就是会将新的代码内容添加到DSL中的codeBlocks数组并保存下来这里涉及的逻辑可以参见CodeBlock类中的[setCodeDslById](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/editor/src/services/codeBlock.ts#L107)方法。 在页面中创建代码块也就是会将新的代码内容添加到DSL中的codeBlocks对象并保存下来这里涉及的逻辑可以参见CodeBlock类中的[setCodeDslById](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/editor/src/services/codeBlock.ts#L107)方法。
并且可以在编辑器左侧的“代码块”tab下看到当前活动的代码块列表 并且可以在编辑器左侧的“代码块”tab下看到当前活动的代码块列表
<img src="/code-block.png" alt="代码块列表"> <img src="/code-block.png" alt="代码块列表">
## 组件绑定 ## 组件绑定
代码块的初衷是为了实现对组件逻辑的在线干预代码执行的时机平台提供了组件created, mounted两个钩子因此我们需要将创建的代码与组件进行关联。 代码块的初衷是为了实现对组件逻辑的在线干预代码执行的时机平台提供了组件created, mounted两个钩子因此我们需要将创建的代码与组件进行关联。
<img src="https://vip.image.video.qpic.cn/vupload/20230228/4a34a11677585505930.png" alt="组件绑定代码块"> <img src="https://vip.image.video.qpic.cn/vupload/20230228/4a34a11677585505930.png" alt="组件绑定代码块">
选中组件之后,在组件配置-高级tab下需要支持下拉选择代码块以及代码参数的输入。由于每一个组件绑定代码块的需求都是相同的因此这一部分我们可以抽出为公共的表单配置相关的逻辑处理在[prop文件](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/editor/src/utils/props.ts#L223)中我们在高级tab下统一添加了名为created和mounted两个配置项表单组件使用了自定义的'code-select'。前面已经提过表单组件会按照type字段来进行渲染即 :is="${type}"[CodeSelect](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/editor/src/fields/CodeSelect.vue)组件是在editor中自定义的 选中组件之后,在组件配置-高级tab下需要支持下拉选择代码块以及代码参数的输入。由于每一个组件绑定代码块的需求都是相同的因此这一部分我们可以抽出为公共的表单配置相关的逻辑处理在[prop文件](https://github.com/Tencent/tmagic-editor/blob/master/packages/editor/src/utils/props.ts)中我们在高级tab下统一添加了名为created和mounted两个配置项表单组件使用了自定义的'code-select'。前面已经提过表单组件会按照type字段来进行渲染即 :is="${type}"[CodeSelect](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/editor/src/fields/CodeSelect.vue)组件是在editor中自定义的
完成绑定的动作实质就是在组件配置中增加与代码块的映射关系 完成绑定的动作实质就是在组件配置中增加与代码块的映射关系
```javascript ```javascript
@ -70,9 +70,9 @@
## 代码内容注入与执行 ## 代码内容注入与执行
在实现代码块创建和绑定操作之后DSL已经包含了代码块执行所需的所有信息接下来我们在页面加载时对代码块进行解析并在适当的时机运行。 在实现代码块创建和绑定操作之后DSL已经包含了代码块执行所需的所有信息接下来我们在页面加载时对代码块进行解析并在适当的时机运行。
由于代码块的执行时机为组件createdmounted因此触发执行的动作需要在runtime中完成对于VUE3来说我们在组件对应的生命周期去触发就可以了react则需要在类似的时间点去触发详细请参见[ui](https://github.com/Tencent/tmagic-editor/blob/master/packages/ui/src/useApp.ts#L29) 由于代码块的执行时机为组件createdmounted因此触发执行的动作需要在runtime中完成对于VUE3来说我们在组件对应的生命周期去触发就可以了react则需要在类似的时间点去触发详细请参见 runtime 相关源码(参考 [runtime 目录](https://github.com/Tencent/tmagic-editor/tree/master/runtime)下的 `vue-runtime-help``react-runtime-help`
接收事件的动作是在[Core](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/core/src/Node.ts)中完成的请记得前面提到过Core主要负责对组件进行跨框架管理与一些通用复杂逻辑的实现触发时机各个框架不同但接收事件并执行代码块的逻辑与框架无关。[Core/Node](https://github.com/Tencent/tmagic-editor/blob/master/packages/core/src/Node.ts#L56)会对生命周期事件进行监听并根据组件绑定的代码块ID拿到具体的代码内容然后执行。在执行调用时我们以{ app, params }的形式传入了两个参数其中app包含了全局的变量params为组件绑定时针对代码块传入的参数。 接收事件的动作是在[Core](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/core/src/Node.ts)中完成的请记得前面提到过Core主要负责对组件进行跨框架管理与一些通用复杂逻辑的实现触发时机各个框架不同但接收事件并执行代码块的逻辑与框架无关。[Core/Node 中的 `listenLifeSafe`](https://github.com/Tencent/tmagic-editor/blob/c143a5f7670ae61d80c1a2cfcc780cfb5259849d/packages/core/src/Node.ts#L159)会对生命周期事件进行监听并根据组件绑定的代码块ID拿到具体的代码内容然后执行。在执行调用时我们以 `{ app, params }` 的形式传入了两个参数,其中 `app` 包含了全局的变量,`params` 为组件绑定时针对代码块传入的参数。
至此,我们就完成了代码块创建-绑定-注入-运行。与代码块功能相关的UI界面中我们也提供了丰富的插槽供开发者扩展相关源码请见[sidebar/codeBlock](https://github.com/Tencent/tmagic-editor/tree/master/packages/editor/src/layouts/sidebar/code-block)。 至此,我们就完成了代码块创建-绑定-注入-运行。与代码块功能相关的UI界面中我们也提供了丰富的插槽供开发者扩展相关源码请见[sidebar/codeBlock](https://github.com/Tencent/tmagic-editor/tree/master/packages/editor/src/layouts/sidebar/code-block)。

View File

@ -25,12 +25,12 @@ tmagic-editor的联动指这两种情况
}]`"> }]`">
</demo-block> </demo-block>
在经过表单渲染器时,所有指出函数 API 都会传入当前渲染的**表单组件实例(vm)****当前项目(value)****当前表单model****表单值formValue**model 即 vue 的[表单输入绑定](https://v3.cn.vuejs.org/guide/forms.html#%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95),可以通过修改他来实现值联动。 在经过表单渲染器时,所有注入的函数 API 都会传入当前渲染的**表单组件实例(vm)****当前项目(value)****当前表单model****表单值formValue**model 即 vue 的[表单输入绑定](https://v3.cn.vuejs.org/guide/forms.html#%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95),可以通过修改他来实现值联动。
当然我们也可以通过上述的参数传入,以及其他函数 API 实现更多灵活的表单联动,具体参考[表单 API](../../form-config/relate)。 当然我们也可以通过上述的参数传入,以及其他函数 API 实现更多灵活的表单联动,具体参考[表单 API](../../form-config/relate)。
## 组件联动 ## 组件联动
tmagic-editor在 @tmagic/core 中,实现了组件的事件绑定/分发机制。在组件渲染时,每个组件在 @tmagic/ui 中经过基础组件渲染时,会被基础组件注入公共方法的实现。如下对按钮配置了**点击使文本隐藏**的联动事件,那么在对应按钮被点击时,将会触发对应绑定文本的隐藏。 tmagic-editor在 `@tmagic/core` 中,实现了组件的事件绑定/分发机制。在组件渲染时,每个组件在经过 `@tmagic/vue-container`vue 端)或 `@tmagic/react-container`react 端)等基础渲染组件渲染时,会被基础组件注入公共方法的实现。如下对按钮配置了**点击使文本隐藏**的联动事件,那么在对应按钮被点击时,将会触发对应绑定文本的隐藏。
<img src="https://image.video.qpic.cn/oa_88b7d-10_2117738923_1637238863127559"> <img src="https://image.video.qpic.cn/oa_88b7d-10_2117738923_1637238863127559">
@ -95,28 +95,31 @@ const onClick = () => {
}; };
// 此处实现事件动作 // 此处实现事件动作
const toast = () => { // 注意:示例中的 ElMessage 仅作演示,业务可替换为自己的弹窗工具
toast('测试 vue3') import { ElMessage } from 'element-plus';
const showToast = () => {
ElMessage('测试 vue3');
}; };
// 实际触发时是调用node上的方法所以需要将改方法暴露到node上 // 实际触发时是调用node上的方法所以需要将方法暴露到node上
registerNodeHooks(node, { registerNodeHooks(node, {
toast, toast: showToast,
}); });
defineExpose({ defineExpose({
toast, toast: showToast,
}); });
</script> </script>
``` ```
#### react 版本实现 #### react 版本实现
在 react 的实现中由于tmagic-editor提供的 @tmagic/ui-react 版本是用 hook 实现的。所以组件开发我们也相应的需要使用 hook 方式。 在 react 的实现中由于tmagic-editor提供的 @tmagic/react-runtime-help 版本是用 hook 实现的。所以组件开发我们也相应的需要使用 hook 方式。
```jsx ```jsx
import React from 'react'; import React from 'react';
import { useApp } from '@tmagic/ui-react'; import { useApp } from '@tmagic/react-runtime-help';
function Test({ config }) { function Test({ config }) {
// react 和 vue 实现不同,我们通过 useApp 这个 hook 来提供 app 等核心内容 // react 和 vue 实现不同,我们通过 useApp 这个 hook 来提供 app 等核心内容

View File

@ -59,7 +59,7 @@ formConfig.js
```js ```js
[ [
{ {
type: 'data-source-filed-select' type: 'data-source-field-select'
} }
] ]
``` ```

View File

@ -0,0 +1,128 @@
# 历史记录面板
编辑器内置了一个可视化的「历史记录面板」,用于查看与回溯编辑过程中产生的所有操作。相比顶部菜单栏只能「撤销 / 重做」相邻一步,历史记录面板提供了对整条历史栈的全局视角:可以按页面、数据源、代码块分类浏览,点击任意一步直接跳转,查看每一步的前后差异,甚至像 `git revert` 一样单独回滚某一步而不破坏后续操作。
## 开启面板
历史记录面板以一个内置菜单项 `'history-list'` 的形式提供,将它加入 [`menu`](/api/editor/props.html#menu) 配置即可在顶部工具栏出现一个时钟图标,点击展开面板:
```html
<template>
<m-editor :menu="menu"></m-editor>
</template>
<script setup>
import { ref } from 'vue';
const menu = ref({
left: [],
center: ['delete', 'undo', 'redo', '/', 'history-list'],
right: [],
});
</script>
```
## 面板结构
面板分为三个 tab分别对应三类可被历史记录追踪的对象tab 标题后的数字为各自的分组数量:
| Tab | 内容 | 跳转 API |
| --- | --- | --- |
| 页面 | 当前活动页面的节点操作历史 | `editorService.gotoPageStep(cursor)` |
| 数据源 | 按 `dataSource.id` 分组的数据源变更历史 | `dataSourceService.goto(id, cursor)` |
| 代码块 | 按 `codeBlock.id` 分组的代码块变更历史 | `codeBlockService.goto(id, cursor)` |
### 相邻同目标自动合并
为了避免「连续微调同一个节点 / 数据源 / 代码块」时产生大量碎片化记录,面板会把**相邻的、针对同一目标的连续 `update`** 自动合并成一个分组:
- 页面 tab连续修改同一节点按节点 id 判定)的多步合并为一组,点击组头部可展开查看每一子步;
- 数据源 / 代码块 tab相邻的连续 `update` 按目标 id 合并;`add` / `remove` 始终独立成组(语义上是一次性事件)。
> 合并仅作用于展示与交互,不改变底层 undo/redo 栈的真实结构。
## 交互能力
每个分组 / 步骤支持以下操作:
### 1. 点击跳转
点击任意一条记录编辑器会跳转到「应用至该步完成」的状态。其本质是把对应栈的游标cursor移动到 `step.index + 1`,由 service 层的 undo/redo 链路完成中间步骤的批量正向 / 反向应用。
### 2. 回到初始状态
每个 tab 列表底部提供「回到初始状态」入口,等价于把对应栈游标移到 `0`(所有真实步骤全部撤销)。
### 3. 单步回滚(类 git revert
对于历史中间的某一步,可以单独「回滚」它,而保留它之后的所有操作。该行为不会倒带游标,而是把目标步骤的修改**反向应用为一次全新的操作**并压入栈顶,因此不会破坏既有历史结构:
- 页面:`editorService.revertPageStep(index)`
- 数据源:`dataSourceService.revert(id, index)`
- 代码块:`codeBlockService.revert(id, index)`
### 4. 差异对比
在前后值都存在的 `update` 步骤上提供「查看差异」入口,点击后弹出差异对话框。对话框支持两个维度的切换:
- **对比对象**
- `与修改前对比`:该步骤修改前 vs 修改后(默认,体现这一步带来的变化);
- `与当前对比`:该步骤修改后 vs 编辑器中的最新值(用于确认「这一步之后是否又被改动过」,当前值缺失时禁用)。
- **展示形态**
- `表单对比`:以属性表单形式逐字段对比,可读性更好(基于 [表单对比](/form-config/compare.md) 能力);
- `源码对比`:以 JSON 源码做整体 diff基于 monaco diff 编辑器),可以看到表单未覆盖到的字段。
::: tip
表单对比依赖 `@tmagic/form` 的对比模式(`isCompare` / `lastValues`)。对于 `event-select``code-select``code-select-col` 等由列表或嵌套子表单组成的复合字段,表单会逐项展示新增 / 删除 / 修改的高亮差异,并在对比模式下隐藏「添加 / 删除 / 编辑」等写操作按钮,仅保留只读展示。
:::
## 扩展自定义 tab
内置的三个 tab 之外,业务方可以通过 Editor 的 [`historyListExtraTabs`](/api/editor/props.html#historylistextratabs) 在面板中追加自定义的历史 tab追加在「页面 / 数据源 / 代码块」之后。适用于某个自定义模块维护自己的操作历史,需要在历史记录面板中独立展示与回滚的场景。
```html
<template>
<m-editor :menu="menu" :history-list-extra-tabs="historyListExtraTabs"></m-editor>
</template>
<script setup>
import { markRaw } from 'vue';
import MyModuleHistoryTab from './MyModuleHistoryTab.vue';
const historyListExtraTabs = [
{
name: 'my-module',
// label 支持字符串或函数,函数形式便于展示动态数量
label: () => `我的模块 (${getMyModuleHistory().length})`,
component: markRaw(MyModuleHistoryTab),
props: { foo: 'bar' },
listeners: {
goto: (cursor) => console.log(cursor),
},
},
];
</script>
```
每个扩展 tab 的字段说明:
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `name` | 是 | tab 唯一标识,作为内部 `TMagicTabs``name` |
| `label` | 是 | tab 显示文案,支持字符串或返回字符串的函数(便于展示动态数量) |
| `component` | 是 | tab 内容区渲染的组件 |
| `props` | 否 | 传入内容组件的 props |
| `listeners` | 否 | 内容组件的事件监听 |
> 内容组件内部可自行通过 `useServices()` 拿到 `historyService` 等服务,读取并回滚自定义模块自己维护的历史。
## 自定义对比判断
差异对话框中的「表单对比」最终透传到 `MForm`,你可以通过 Editor 顶层注入的 `extendFormState` 让对比表单拿到完整业务上下文,从而让依赖上下文的 `display` / `disabled``filterFunction` 正常工作。
若某些字段语义上相等但结构不同(例如 `code-select` 字段中 `''``{ hookType: 'code', hookData: [] }` 应视为相等),可借助 `@tmagic/form` 的 [`showDiff`](/api/form/form-props.html#showdiff) 自定义判断函数避免被误判为差异。
## 相关 API
历史面板的数据均来自 `historyService` 暴露的聚合方法,详见 [historyService 方法](/api/editor/historyServiceMethods.md)。

View File

@ -1,5 +1,5 @@
# 页面渲染 # 页面渲染
tmagic-editor的页面渲染是通过在载入编辑器中保存的 DSL 配置,通过 ui 渲染器渲染页面。在容器布局原理里我们提到过,容器和组件在配置中呈树状结构,所以渲染页面的时候,渲染器会递归配置内容,从而渲染出页面所有组件。 tmagic-editor的页面渲染是通过在载入编辑器中保存的 DSL 配置,通过基础渲染组件vue 下为 `@tmagic/vue-container`react 下为 `@tmagic/react-container`渲染页面。在容器布局原理里我们提到过,容器和组件在配置中呈树状结构,所以渲染页面的时候,渲染器会递归配置内容,从而渲染出页面所有组件。
<img src="https://vfiles.gtimg.cn/vupload/20211009/f4d3031633778551251.png"> <img src="https://vfiles.gtimg.cn/vupload/20211009/f4d3031633778551251.png">
@ -25,7 +25,7 @@ export default {
``` ```
## 组件渲染 ## 组件渲染
所有tmagic-editor组件都通过一个tmagic-editor基础组件来渲染。这个基础组件会识别当前渲染组件的类型。如果当前渲染组件是普通组件包括ui中提供的基础组件和业务开发的业务组件),则直接渲染;如果当前渲染组件是容器,则回到[容器渲染](#容器渲染)逻辑中。 所有tmagic-editor组件都通过一个tmagic-editor基础组件来渲染。这个基础组件会识别当前渲染组件的类型。如果当前渲染组件是普通组件包括 `vue-components` / `react-components` 中提供的基础组件和业务开发的业务组件),则直接渲染;如果当前渲染组件是容器,则回到[容器渲染](#容器渲染)逻辑中。
基础组件的具体形式为: 基础组件的具体形式为:
```vue ```vue
@ -59,6 +59,6 @@ export default defineComponent({
``` ```
## 渲染器示例 ## 渲染器示例
在tmagic-editor的示例项目中我们提供了三个版本的 @tmagic/ui可以参考对应前端框架的渲染器实现。 在tmagic-editor的示例项目中我们针对 vue 和 react 分别提供了基础渲染组件的实现,可以参考对应前端框架的渲染器实现。
- [vue 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/vue-components/container/src/Container.vue) - [vue 渲染器`@tmagic/vue-container`](https://github.com/Tencent/tmagic-editor/blob/master/vue-components/container/src/Container.vue)
- [react 渲染器](https://github.com/Tencent/tmagic-editor/blob/master/react-components/container/src/Container.tsx) - [react 渲染器`@tmagic/react-container`](https://github.com/Tencent/tmagic-editor/blob/master/react-components/container/src/Container.tsx)

View File

@ -21,7 +21,7 @@ $ npm install @tmagic/element-plus-adapter @tmagic/design element-plus -S
### 引入 @tmagic/form ### 引入 @tmagic/form
MagicForm 使用了 element-ui MagicForm 使用了 element-plus 组件
在 main.js 中写入以下内容: 在 main.js 中写入以下内容:
@ -46,9 +46,9 @@ app.mount("#app");
``` ```
以上代码便完成了 @tmagic/form 的引入。需要注意的是ElementUI 的样式文件需要单独引入。 以上代码便完成了 @tmagic/form 的引入。需要注意的是Element Plus 的样式文件需要单独引入。
在 App.Vue 中写入以下内容: 在 App.vue 中写入以下内容:
```html ```html
<m-form :config="config" :init-values="initValue"></m-form> <m-form :config="config" :init-values="initValue"></m-form>

View File

@ -1,23 +0,0 @@
# @tmagic/ui
在前面[页面渲染](../advanced/page)中提到的 UI 渲染器,就是包含在 @tmagic/ui 中的渲染器组件。
tmagic-editor的设计是希望发布的页面支持多个前端框架即各个业务方可以根据自己熟悉的语言来开发组件、发布页面。也可以通过 [实现一个 runtime](../runtime.html) 的方式,来实现一个自己的 @tmagic/ui
所以tmagic-editor的设计中针对每个前端框架都需要有一个对应的 @tmagic/ui 来承担渲染器职责。同时,也需要一个使用和 @tmagic/ui 相同前端框架的 runtime 来 @tmagic/ui 和业务组件的,具体 runtime 概念,可以参考[页面发布](../publish)。
我们以项目代码中提供的 vue 版本的 [vue-components](https://tencent.github.io/tmagic-editor/vue-components) 作为示例介绍其中包含的内容。
## 渲染器
在 vue 中,实现渲染器的具体形式参考[页面渲染](../advanced/page)中描述的[容器渲染](../advanced/page.html#容器渲染)和[组件渲染](../advanced/page.html#容器渲染)。
## 基础组件
在 [vue-components](https://tencent.github.io/tmagic-editor/vue-components) 中,我们提供了几个基础组件,可以在项目源码中找到对应内容。
- page tmagic-editor的页面基础
- container tmagic-editor的容器渲染器
- Component.vue tmagic-editor的组件渲染器
- button/text 基础组件示例
其中 page/container/Component 是 UI 的基础,是每个框架的 UI 都应该实现的。
button/text 其实就是一个组件开发的示例,具体组件开发相关规范可以参考[组件开发](../component)。

View File

@ -152,7 +152,7 @@ react 版本组件代码示例
import React, { useContext } from 'react'; import React, { useContext } from 'react';
import Core from '@tmagic/core'; import Core from '@tmagic/core';
import { AppContent } from '@tmagic/ui-react'; import { AppContent } from '@tmagic/react-runtime-help';
function Test({ config }: { config: any }) { function Test({ config }: { config: any }) {
const app = useContext<Core | undefined>(AppContent); const app = useContext<Core | undefined>(AppContent);

View File

@ -8,7 +8,7 @@
### 一、顶部菜单栏定制 ### 一、顶部菜单栏定制
通常使用 `m-editor` 组件的 [menu](/api/editor/props.html#menu) `prop` 来对进行设置; 通常使用 `m-editor` 组件的 [menu](/api/editor/props.html#menu) `prop` 来对进行设置;
顶部菜单栏分为`左` `中` `右`三个部分组成,所以 [menu](/api/editor/props.html#menu) `prop`的数据格式如下: 顶部菜单栏分为`左` `中` `右`三个部分组成,所以 [menu](/api/editor/props.html#menu) `prop`的数据格式如下:
@ -16,7 +16,7 @@
{ left: [], center: [], right: [] } { left: [], center: [], right: [] }
``` ```
数组的内容可以有三种形式:`内部定义好的字符串``其他字符串``MenuButton 或者 MenuComponent 对象` 数组的内容可以有三种形式:`内部定义好的字符串``其他字符串``MenuButton 或者 MenuComponent 对象`
#### 1. 内部定义好的字符串: #### 1. 内部定义好的字符串:
```ts ```ts
@ -38,7 +38,7 @@ MenuButton 的[定义](https://github.com/Tencent/tmagic-editor/blob/239b5d3efea
```js ```js
{ {
type: 'buuton', type: 'button',
text: '返回', text: '返回',
handler: () => window.history.back(), handler: () => window.history.back(),
} }
@ -122,7 +122,7 @@ editorService.on('select', (node) => {
默认的属性读取流程如下: 默认的属性读取流程如下:
组件中定义`formConfig` -> 通过`tamgic-cli`构建成 `runtime``/config/index.umd.cjs` -> `m-editor`中加载然后配置到[propsConfig](/api/editor/props.html#propsconfigs) prop中 -> `m-editor`保存到`propsService`中 -> 选中组件时`editorService`会去`propsService`调用`getPropsConfig`中读取 组件中定义`formConfig` -> 通过`tmagic-cli`构建成 `runtime``/config/index.umd.cjs` -> `m-editor`中加载然后配置到[propsConfig](/api/editor/props.html#propsconfigs) prop中 -> `m-editor`保存到`propsService`中 -> 选中组件时`editorService`会去`propsService`调用`getPropsConfig`中读取
`propsService.getPropsConfig`会调取`propsService.fillConfig`添加样式、事件、高级3个tab分页 `propsService.getPropsConfig`会调取`propsService.fillConfig`添加样式、事件、高级3个tab分页

View File

@ -1,6 +1,15 @@
# 快速开始 # 快速开始
tmagic-editor的编辑器我们已经封装成一个 npm 包,可以直接安装使用。编辑器是使用 vue3 开发的(仅支持vue3),但使用编辑器的业务(runtime)可以不限框架,可以用 vue2、react 等开发业务组件。 tmagic-editor 的编辑器已经封装成 npm 包,可以直接安装使用。编辑器使用 Vue 3 开发(**仅支持 Vue 3**),但承载真实业务的 runtime 不限框架,可以使用 Vue 2、Vue 3、React 等开发业务组件。
整个项目结构由两部分组成:
- **admin-client**(编辑器 / 管理端):基于 `@tmagic/editor`,加载 runtime iframe、提供拖拽/属性配置/发布等能力。
- **runtime**(运行时):负责解析 DSL 并渲染页面,分为编辑器内嵌的 `playground` 和线上发布使用的 `page` 两个产物。
> 仓库 [`playground/`](https://github.com/Tencent/tmagic-editor/tree/master/playground) 与 [`runtime/vue/`](https://github.com/Tencent/tmagic-editor/tree/master/runtime/vue) 就是一份完整可运行的最小实践,本节内容均与之对齐,可以对照阅读源码。
## 使用脚手架创建(推荐)
::: code-group ::: code-group
@ -11,221 +20,423 @@ $ npm create tmagic@latest
```bash [pnpm] ```bash [pnpm]
$ pnpm create tmagic $ pnpm create tmagic
``` ```
::: :::
按照提示操作可以创建`6`项目: 按照交互式提示,可以创建以下 `6`项目:
* runtime:运行时DSL渲染 | 类型 | 说明 |
* admin-client:管理端(编辑器) | -------------- | ------------------------------ |
* components:组件库(组件/插件/数据源) | `runtime` | 运行时DSL 渲染) |
* component:组件 | `admin-client` | 管理端(编辑器) |
* data-source:数据源 | `components` | 组件库(组件 / 插件 / 数据源) |
* plugin:插件 | `component` | 单个组件 |
| `data-source` | 单个数据源 |
| `plugin` | 单个插件 |
至少需要一个runtime与admin-client后就可以运行起一个最简单的项目了。 最少需要一个 `runtime` 加一个 `admin-client`,就能跑起一个完整的可视化搭建流程。后续可以再陆续创建组件、插件、数据源;新建好后到 `runtime/tmagic.config.ts``packages` 中注册即可,参考[组件开发](./component.md) 与[页面发布 § @tmagic/cli](./publish.md#tmagic-cli)。
后续还需要新增组件、插件、数据源等,可以继续添加后面几种类型的项目。
新增好一个组件/插件/数据源后可以到runtime/tmagic.config.ts中配置到packages中
## 手动安装 ## 手动安装
node.js >= 18 ::: tip 环境要求
可以通过[Vite](https://cn.vitejs.dev/) 或 [Vue CLI](https://cli.vuejs.org/zh/)快速创建项目。 - Node.js `^20.19.0 || >=22.12.0`
- 推荐使用 [Vite](https://cn.vitejs.dev/);如果使用 [Vue CLI](https://cli.vuejs.org/zh/) 需要在 `vue.config.js` 中加上 `transpileDependencies: [/@tmagic/]`
:::
> 使用Vue CLI生成的项目需要在vue.config.js中加上配置transpileDependencies: [/@tmagic/] ### 1. 安装编辑器依赖
`@tmagic/editor` 把内部使用到的 UI 组件抽象到了 `@tmagic/design`,通过 **adapter** 的形式接入具体的 UI 组件库。我们提供了:
- [`@tmagic/element-plus-adapter`](https://github.com/Tencent/tmagic-editor/tree/master/packages/element-plus-adapter):接入 [Element Plus](https://element-plus.org/)
- [`@tmagic/tdesign-vue-next-adapter`](https://github.com/Tencent/tmagic-editor/tree/master/packages/tdesign-vue-next-adapter):接入 [TDesign Vue Next](https://tdesign.tencent.com/vue-next/overview)
任选其一即可,下面以 Element Plus 为例:
```bash ```bash
$ npm install @tmagic/editor -S $ npm install @tmagic/editor @tmagic/core @tmagic/element-plus-adapter element-plus -S
``` ```
由于在实际应用中项目常常会用到例如[element-plus](https://element-plus.org/)、[tdesign-vue-next](https://tdesign.tencent.com/vue-next/overview)等UI组件库。为了能让使用者能够选择不同UI库[@tmagic/editor](https://github.com/Tencent/tmagic-editor/tree/master/packages/editor)将其中使用到的UI组件封装到[@tmagic/design](https://github.com/Tencent/tmagic-editor/tree/master/packages/design)中然后通过不同的adapter来指定使用具体的对应的UI库我们提供了[@tmagic/element-plus-adapter](https://github.com/Tencent/tmagic-editor/tree/master/packages/element-plus-adapter)来支持[element-plus](https://element-plus.org/),所以还需要安装相关的依赖。 `@tmagic/editor` 内部使用了 [monaco-editor](https://microsoft.github.io/monaco-editor/) 作为代码编辑器,需要额外安装并按照官方[配置指引](https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-esm.md)注入 worker
```bash
$ npm install @tmagic/element-plus-adapter element-plus -S
```
editor 中还包含了[monaco-editor](https://microsoft.github.io/monaco-editor/)所以还需安装monaco-editor可以参考 monaco-editor 的[配置指引](https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-esm.md)。
```bash ```bash
$ npm install monaco-editor -S $ npm install monaco-editor -S
``` ```
## 快速上手 ### 2. 引入 @tmagic/editor
## 引入 @tmagic/editor 参考 [`playground/src/main.ts`](https://github.com/Tencent/tmagic-editor/blob/master/playground/src/main.ts),在入口文件中按以下顺序完成 Monaco worker、UI 库样式、editor 样式与 adapter 的注入:
在 main.js 中写入以下内容: ```ts
import { createApp } from "vue";
import EditorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import CssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
import HtmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
import JsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
import TsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
```js import editorPlugin from "@tmagic/editor";
import { createApp } from 'vue'; import MagicElementPlusAdapter from "@tmagic/element-plus-adapter";
import ElementPlus from 'element-plus';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
import editorPlugin from '@tmagic/editor'; import App from "./App.vue";
import MagicElementPlusAdapter from '@tmagic/element-plus-adapter';
import App from './App.vue'; import "element-plus/dist/index.css";
import "@tmagic/editor/dist/style.css";
import 'element-plus/dist/index.css'; // @ts-ignore
import '@tmagic/editor/dist/style.css'; globalThis.MonacoEnvironment = {
getWorker(_: any, label: string) {
if (label === "json") return new JsonWorker();
if (["css", "scss", "less"].includes(label)) return new CssWorker();
if (["html", "handlebars", "razor"].includes(label))
return new HtmlWorker();
if (["typescript", "javascript"].includes(label)) return new TsWorker();
return new EditorWorker();
},
};
const app = createApp(App); createApp(App).use(editorPlugin, MagicElementPlusAdapter).mount("#app");
app.use(ElementPlus, {
locale: zhCn,
});
app.use(router);
app.use(editorPlugin, MagicElementPlusAdapter);
app.mount('#app');
``` ```
以上代码便完成了 @tmagic/editor 的引入。需要注意的是,样式文件需要单独引入。 ::: tip 切换 UI 适配器
playground 通过 `sessionStorage` 来切换 adapter参考实现
可以参考我们提供的[Playground](https://github.com/Tencent/tmagic-editor/blob/master/playground/src/main.ts)示例实现代码 ```ts
const adapter =
sessionStorage.getItem("tmagic-playground-ui-adapter") || "element-plus";
const adapterModule =
adapter === "tdesign-vue-next"
? import("@tmagic/tdesign-vue-next-adapter")
: import("@tmagic/element-plus-adapter");
```
## 使用 m-editor 组件 :::
在 App.vue 中写入以下内容: ::: tip 常见报错
```html 1. `Preprocessor dependency "sass" not found.` —— 安装 sass`npm i sass -D`
2. `Uncaught ReferenceError: global is not defined` —— Vite 项目需要在 `vite.config.ts` 中加上:
```ts
// vite 8以下版本
optimizeDeps: {
esbuildOptions: {
define: { global: 'globalThis' },
},
}
```
```ts
// vite 8及以上
define: {
global: 'globalThis',
},
```
:::
### 3. 渲染 m-editor
`App.vue` 中渲染 `<TMagicEditor />`(即 `m-editor` 组件),最少需要传入 `v-model``runtime-url``component-group-list``props-configs``props-values` 五个核心属性:
```vue
<template> <template>
<m-editor <div class="editor-app">
v-model="dsl" <TMagicEditor
v-model="value"
ref="editor"
:menu="menu" :menu="menu"
:runtime-url="runtimeUrl" :runtime-url="runtimeUrl"
:props-configs="propsConfigs" :props-configs="propsConfigs"
:props-values="propsValues" :props-values="propsValues"
:event-method-list="eventMethodList"
:datasource-configs="datasourceConfigs"
:datasource-values="datasourceValues"
:datasource-event-method-list="datasourceEventMethodList"
:component-group-list="componentGroupList" :component-group-list="componentGroupList"
> :default-selected="defaultSelected"
</m-editor> :stage-rect="stageRect"
:auto-scroll-into-view="true"
/>
</div>
</template> </template>
<script> <script lang="ts" setup>
import { defineComponent, ref } from "vue"; import { ref, shallowRef } from "vue";
import type { MApp } from "@tmagic/core";
import { TMagicEditor } from "@tmagic/editor";
export default defineComponent({ import componentGroupList from "./configs/componentGroupList";
name: "App", import dsl from "./configs/dsl";
import { useEditorRes } from "./composables/use-editor-res";
setup() { const editor = shallowRef<InstanceType<typeof TMagicEditor>>();
return { const value = ref<MApp>(dsl);
menu: ref({ const defaultSelected = ref(dsl.items[0].id);
left: [ const stageRect = ref({ width: 375, height: 817 });
// 顶部左侧菜单按钮
], const { VITE_RUNTIME_PATH } = import.meta.env;
center: [ const runtimeUrl = `${VITE_RUNTIME_PATH}/playground/index.html`;
// 顶部中间菜单按钮
], const {
propsValues,
propsConfigs,
eventMethodList,
datasourceConfigs,
datasourceValues,
datasourceEventMethodList,
} = useEditorRes();
const menu = {
left: [{ type: "text", text: "魔方" }],
center: ["delete", "undo", "redo", "guides", "rule", "zoom"],
right: [ right: [
// 顶部右侧菜单按钮 {
], type: "button",
}), text: "保存",
handler: () =>
dsl: ref({ localStorage.setItem("magicDSL", JSON.stringify(value.value)),
// 初始化页面数据
}),
runtimeUrl: "/runtime/vue/playground/index.html",
propsConfigs: [
// 组件属性列表
],
propsValues: [
// 组件默认值
],
componentGroupList: ref([
// 组件列表
]),
};
}, },
}); ],
};
</script> </script>
<style lang="scss"> <style lang="scss">
html, body { html,
body,
#app {
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
overflow: hidden; }
} .editor-app {
#app {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; }
} .editor-app .m-editor {
.m-editor {
flex: 1; flex: 1;
height: 100%; height: 100%;
} }
</style> </style>
``` ```
关于 [@tmagic/editor](https://github.com/Tencent/tmagic-editor/tree/master/packages/editor) 组件,更多的属性配置详情请参考[编辑器 API](../api/editor/props.md)。 完整的菜单/预览/键盘快捷键实现可以参考 [`playground/src/pages/Editor.vue`](https://github.com/Tencent/tmagic-editor/blob/master/playground/src/pages/Editor.vue)。
其中,**有四个需要注意的属性配置项**`runtimeUrl` `values` `configs` `componentGroupList`。这是能让我们的编辑器正常运行的关键。 更多 prop 详见[编辑器 API](../api/editor/props.md),下文重点介绍最关键的 4 个:`runtimeUrl``componentGroupList``propsConfigs/propsValues`、初始 DSL`v-model`)。
:::tip
如果出现```Preprocessor dependency "sass" not found. Did you install it?```那么需要install sass
```bash
npm install sass -D
```
:::
:::tip
如果是使用vite构建工具如果出现 ```Uncaught ReferenceError: global is not defined```那么需要再vite.config.js中添加如下配置
```js
{
optimizeDeps: {
esbuildOptions: {
define: {
global: 'globalThis',
},
},
},
}
```
:::
## runtimeUrl ## runtimeUrl
该配置涉及到 [runtime 概念](runtime.md)tmagic-editor编辑器中心的模拟器画布是一个 iframe这里的 `runtimeUrl` 配置的,就是你提供的 iframe 的 url其中渲染了一个 runtime用来响应编辑器中的组件增删改等操作。 编辑器中央的模拟器画布是一个 `iframe``runtimeUrl` 就是这个 iframe 加载的地址,里面运行着一份 **playground runtime**,负责响应编辑器中组件的增删改查。
:::tip
可以使用`npm create tmagic` 来快速创建一个runtime项目。
:::
## componentGroupList playground 中通过 Vite proxy 把 runtime 服务(默认端口 `8078`)代理到了同一个域:
`componentGroupList` 是指定左侧组件库内容的配置。此处定义了在编辑器组件库中有什么组件。在添加的时候通过组件 `type` 来确定 runtime 中要渲染什么组件。可以参考 [componentGroupList 配置](../api/editor/props.html#componentgrouplist)。 ```ts
server: {
## propsConfigs/propsValues port: 8098,
proxy: {
`propsConfigs` `propsValues``componentGroupList` 中声明的组件是一一对应的,通过 `type` 来识别属于哪个组件,该配置涉及的内容,就是组件的表单配置描述,在[组件开发中](./component.md)会通过 formConfig 配置来声明这份内容。 '^/tmagic-editor/playground/runtime': {
target: 'http://127.0.0.1:8078',
`configs` 既可以通过 hardcode 方式写上每个组件的表单配置,也可以通过组件打包方式得到对应内容,然后通过异步加载来载入。比如: changeOrigin: true,
prependPath: false,
```javascript },
setup() { },
asyncLoadJs(`/runtime/vue/assets/config.js`).then(() => {
propsConfigs.value = window.magicPresetConfigs;
});
asyncLoadJs(`/runtime/vue/assets/value.js`).then(() => {
propsValues.value = window.magicPresetValues;
});
} }
``` ```
::: tip 如何快速得到一个 configs/values 实际项目中可以使用 `npm create tmagic` 快速生成一个 runtime 项目,详见[RUNTIME](./runtime.md)。
上述的 runtime 产物中dist 目录中即包含一个 entry 文件夹在你的项目组件初始化之后分别异步加载里面的config/index.umd.js、value/index.umd.js。并如上面代码中赋值给 configs/values 即可。
## componentGroupList
`componentGroupList` 决定左侧组件库展示哪些组件分组。每个 item 通过 `type` 与 runtime 中注册的组件类型一一对应,添加到画布时编辑器会基于 `type` 通知 runtime 渲染对应组件。
```ts
import {
Files,
FolderOpened,
PictureFilled,
SwitchButton,
Tickets,
} from "@element-plus/icons-vue";
import type { ComponentGroup } from "@tmagic/editor";
export default [
{
title: "示例容器",
items: [
{ icon: FolderOpened, text: "组", type: "container" },
{ icon: FolderOpened, text: "蒙层", type: "overlay" },
{ icon: Files, text: "迭代器容器", type: "iterator-container" },
],
},
{
title: "示例组件",
items: [
{ icon: Tickets, text: "文本", type: "text" },
{ icon: SwitchButton, text: "按钮", type: "button" },
{ icon: PictureFilled, text: "图片", type: "img" },
],
},
// 也可以提供完整 schema 作为「组合」,添加时直接落入完整子树
{
title: "组合",
items: [
{
icon: Tickets,
text: "弹窗",
data: {
type: "overlay",
name: "弹窗",
style: {
position: "fixed",
width: "100%",
height: "100%",
top: 0,
left: 0,
},
items: [
/* ... */
],
},
},
],
},
] as ComponentGroup[];
```
完整字段参考 [`componentGroupList`](../api/editor/props.md#componentgrouplist)。
## propsConfigs / propsValues
`propsConfigs` `propsValues``componentGroupList` 中声明的组件通过 `type` 一一对应:
- `propsConfigs[type]`:组件**右侧表单**的配置描述(在组件中 `formConfig` 字段提供)。
- `propsValues[type]`:组件被添加到画布时的**初始默认值**(在组件中 `initValue` 字段提供)。
这些内容会通过 `@tmagic/cli` 在 runtime 构建时打包出对应的 UMD 文件编辑器异步加载即可。playground 中的真实做法([`use-editor-res.ts`](https://github.com/Tencent/tmagic-editor/blob/master/playground/src/pages/composables/use-editor-res.ts)
```ts
import { ref } from "vue";
import { asyncLoadJs } from "@tmagic/editor";
const { VITE_ENTRY_PATH } = import.meta.env;
export const useEditorRes = () => {
const propsValues = ref<Record<string, any>>({});
const propsConfigs = ref<Record<string, any>>({});
const eventMethodList = ref<Record<string, any>>({});
const datasourceConfigs = ref<Record<string, any>>({});
const datasourceValues = ref<Record<string, any>>({});
const datasourceEventMethodList = ref<Record<string, any>>({
base: { events: [], methods: [] },
});
asyncLoadJs(`${VITE_ENTRY_PATH}/config/index.umd.cjs`).then(() => {
propsConfigs.value = (globalThis as any).magicPresetConfigs;
});
asyncLoadJs(`${VITE_ENTRY_PATH}/value/index.umd.cjs`).then(() => {
propsValues.value = (globalThis as any).magicPresetValues;
});
asyncLoadJs(`${VITE_ENTRY_PATH}/event/index.umd.cjs`).then(() => {
eventMethodList.value = (globalThis as any).magicPresetEvents;
});
asyncLoadJs(`${VITE_ENTRY_PATH}/ds-config/index.umd.cjs`).then(() => {
datasourceConfigs.value = (globalThis as any).magicPresetDsConfigs;
});
asyncLoadJs(`${VITE_ENTRY_PATH}/ds-value/index.umd.cjs`).then(() => {
datasourceValues.value = (globalThis as any).magicPresetDsValues;
});
return {
propsValues,
propsConfigs,
eventMethodList,
datasourceConfigs,
datasourceValues,
datasourceEventMethodList,
};
};
```
::: tip 怎样得到这些 UMD 文件?
在 runtime 项目中执行 `npm run build:libs`(参考 [`runtime/vue/package.json`](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/package.json)),会在 `dist/entry/` 下生成 `config/value/event/ds-config/ds-value` 五个目录的 UMD 文件,全局变量分别为 `magicPresetConfigs` `magicPresetValues` `magicPresetEvents` `magicPresetDsConfigs` `magicPresetDsValues`
::: :::
## 更多 如果是在调试期,也可以直接 hardcode 一份 `propsConfigs` / `propsValues`,比如:
通过上述步骤,可以快速得到一个初始化的简单编辑器。 ```ts
const propsConfigs = ref({
text: [{ name: "text", text: "文案" }],
button: [{ name: "text", text: "按钮文案" }],
});
除了上述内容外文档的其他章节中也会更深入的描述整个tmagic-editor的设计理念和实现细节。同时你也可以查看我们的[项目源码](https://github.com/Tencent/tmagic-editor),从源码提供的 playground 和 runtime 示例来开发和理解tmagic-editor。 const propsValues = ref({
text: { text: "一段文字" },
button: { text: "按钮" },
});
```
## v-modelDSL 初始值
`v-model` 绑定的是整个页面的 [DSL](./advanced/js-schema.md),最简的初始 DSL 长这样:
```ts
import { type MApp, NodeType } from "@tmagic/core";
const dsl: MApp = {
id: "1",
name: "demo",
type: NodeType.ROOT,
items: [
{
type: NodeType.PAGE,
id: "page_1",
name: "index",
layout: "absolute",
style: { position: "relative", width: "100%", height: "100%" },
items: [],
},
],
};
```
完整含数据源、代码块、事件联动的 DSL 示例见 [`playground/src/configs/dsl.ts`](https://github.com/Tencent/tmagic-editor/blob/master/playground/src/configs/dsl.ts)。
::: tip 持久化与历史记录
playground 用 `localStorage` + `serialize-javascript` 做了一个本地持久化方案,并在保存后调用 `editor.editorService.resetModifiedNodeId()` 重置修改状态,可以直接复用。
:::
## 进阶:编辑器服务与插件
`@tmagic/editor` 提供了多组 **service**`editorService` / `propsService` / `historyService` / `uiService` …)和 **插件机制**,可以非侵入式扩展行为。例如 playground 中:
```ts
import { editorService, propsService } from "@tmagic/editor";
editorService.usePlugin({
beforeDoAdd: (config, parent) => {
if (config.type === "overlay") {
// 蒙层始终插入到当前 page 下,并钉到 (0, 0)
config.style = { ...config.style, left: 0, top: 0 };
return [config, editorService.get("page")];
}
return [config, parent];
},
});
propsService.usePlugin({
beforeFillConfig: (config) => [config, "100px"],
});
```
更多扩展能力见[编辑器扩展](./editor-expand.md)与各 service 的 [API 文档](../api/editor/props.md)。
## 下一步
- [基础概念](./conception.md):编辑器 / 模拟器 / runtime / DSL 的关系
- [RUNTIME](./runtime.md):实现并打包一个 runtime
- [组件开发](./component.md):自定义业务组件
- [页面发布](./publish.md):基于 `@tmagic/cli` 的产物结构与发布流程
- [Playground 源码](https://github.com/Tencent/tmagic-editor/tree/master/playground):与本节示例完全对应
通过 `pnpm bootstrap && pnpm pg` 即可在仓库本地启动这份 playground自由调试。

View File

@ -22,7 +22,7 @@ tmagic-editor可视化开源项目是从魔方平台演化而来的开源项目
- **模拟器**,居中位置渲染了当前页面配置的组件内容,模拟真实页面的展示内容。 - **模拟器**,居中位置渲染了当前页面配置的组件内容,模拟真实页面的展示内容。
- **组件库**左侧展示当前业务下的相关组件内容包含tmagic-editor提供的基础组件和业务自定义组件。 - **组件库**左侧展示当前业务下的相关组件内容包含tmagic-editor提供的基础组件和业务自定义组件。
- **组件树**,左侧展示当前页面添加的组件内容,以树状结构展示。 - **组件树**,左侧展示当前页面添加的组件内容,以树状结构展示。
- **[代码块](./advanced/code-block.md)**,左侧展示添加的函数,可供组件事件中联动所用,或者组件声明周期中调用。 - **[代码块](./advanced/code-block.md)**,左侧展示添加的函数,可供组件事件中联动所用,或者组件生命周期中调用。
- **[数据源](./advanced/data-source.md)**,左侧展示添加的数据源,用于组件中的各项配置。 - **[数据源](./advanced/data-source.md)**,左侧展示添加的数据源,用于组件中的各项配置。
- **表单配置**,右侧表单项目,展示由组件内提供的配置描述,提供修改组件行为的配置项。 - **表单配置**,右侧表单项目,展示由组件内提供的配置描述,提供修改组件行为的配置项。
- **DSL 源码**,右上角的 📄 图标可以展示当前页面,各个组件配置,页面基础配置组合而成的配置源码。 - **DSL 源码**,右上角的 📄 图标可以展示当前页面,各个组件配置,页面基础配置组合而成的配置源码。

View File

@ -9,7 +9,7 @@ ui中包含的组件被移除这些组件由单独的npm包提供。1.5.0以
```js ```js
{ {
packages: [ packages: [
{ button: '@tmagic/vue-button', { button: '@tmagic/vue-button' },
{ container: '@tmagic/vue-container' }, { container: '@tmagic/vue-container' },
{ img: '@tmagic/vue-img' }, { img: '@tmagic/vue-img' },
{ 'iterator-container': '@tmagic/vue-iterator-container' }, { 'iterator-container': '@tmagic/vue-iterator-container' },

View File

@ -18,7 +18,7 @@ runtime 的概念是理解tmagic-editor项目页运行的重要概念runti
各个 runtime 的作用除了作为不同场景下的渲染环境同时也是不同环境的打包构建载体。tmagic-editor示例代码中的打包就是基于 runtime 进行的。 各个 runtime 的作用除了作为不同场景下的渲染环境同时也是不同环境的打包构建载体。tmagic-editor示例代码中的打包就是基于 runtime 进行的。
### 业务相关 ### 业务相关
由于 runtime 是页面渲染的承载环境,其中会加载 @tmagic/ui 以及各个业务组件,业务发布项目页也是基于 runtime所以在 runtime 中实现业务方的自定义逻辑是最合适的。runtime 可以提供一些全局 API供业务组件调用。我们可以把下面的模拟器中的 runtime 视为一个业务方runtime。 由于 runtime 是页面渲染的承载环境,其中会加载 `@tmagic/vue-container`(或 `@tmagic/react-container`)等基础渲染组件以及各个业务组件,业务发布项目页也是基于 runtime所以在 runtime 中实现业务方的自定义逻辑是最合适的。runtime 可以提供一些全局 API供业务组件调用。我们可以把下面的模拟器中的 runtime 视为一个业务方runtime。
tmagic-editor提供了三个版本的 runtime 示例,可以参考: tmagic-editor提供了三个版本的 runtime 示例,可以参考:
- [vue runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue) - [vue runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue)
@ -65,7 +65,7 @@ import { defineConfig } from '@tmagic/cli';
export default defineConfig({ export default defineConfig({
/** 组件目录或者npm包名 */ /** 组件目录或者npm包名 */
packages: [path.join(__dirname, '../../packages/ui')], packages: [path.join(__dirname, '../../vue-components')],
/** 组件文件后缀名例如vue文件为.vuetsx文件为.tsx普通js文件则为.js */ /** 组件文件后缀名例如vue文件为.vuetsx文件为.tsx普通js文件则为.js */
componentFileAffix: '.vue', componentFileAffix: '.vue',
/** npm 配置用于当packages配置有npm包名时可以自动安装npm包 */ /** npm 配置用于当packages配置有npm包名时可以自动安装npm包 */
@ -113,7 +113,7 @@ tmagic-editor的页面发布目前使用的是静态资源发布。而所有
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Magic App</title> <title>Magic App</title>
<script src="https://unpkg.com/vue@next/dist/vue.runtime.global.js"></script> <script src="https://unpkg.com/vue@3/dist/vue.runtime.global.js"></script>
<script type="module" crossorigin src="assets/page.js"></script> <script type="module" crossorigin src="assets/page.js"></script>
<link rel="modulepreload" href="assets/App.10f9c9e1.js"> <link rel="modulepreload" href="assets/App.10f9c9e1.js">
<link rel="modulepreload" href="assets/vendor.1dc07625.js"> <link rel="modulepreload" href="assets/vendor.1dc07625.js">
@ -139,7 +139,7 @@ tmagic-editor的页面发布目前使用的是静态资源发布。而所有
<title>Publish Page</title> <title>Publish Page</title>
<!-- 这里插入了项目相关的 DSL.js --> <!-- 这里插入了项目相关的 DSL.js -->
<script type="module" src="./DSL.js"></script> <script type="module" src="./DSL.js"></script>
<script src="https://unpkg.com/vue@next/dist/vue.runtime.global.js"></script> <script src="https://unpkg.com/vue@3/dist/vue.runtime.global.js"></script>
<script type="module" crossorigin src="assets/page.js"></script> <script type="module" crossorigin src="assets/page.js"></script>
<link rel="modulepreload" href="assets/App.10f9c9e1.js"> <link rel="modulepreload" href="assets/App.10f9c9e1.js">
<link rel="modulepreload" href="assets/vendor.1dc07625.js"> <link rel="modulepreload" href="assets/vendor.1dc07625.js">

View File

@ -1,29 +1,328 @@
# RUNTIME # RUNTIME
本章详细介绍如何深入理解tmagic-editor的打包以及如何根据需求定制修改tmagic-editor的页面打包发布方案。页面发布、打包相关的定制化开发需要使用tmagic-editor的业务方搭建好基于开源tmagic-editor的管理平台、存储服务等配套设施。
本章详细介绍 tmagic-editor 中 runtime 的概念、目录结构与实现方式。所有内容均与开源仓库 [`runtime/vue/`](https://github.com/Tencent/tmagic-editor/tree/master/runtime/vue) 一一对应,可以对照阅读。
## runtime 是什么 ## runtime 是什么
runtime是用来解析DSL的执行环境用于渲染 DSL 呈现页面 **runtime 是用来解析 DSL 的执行环境**。编辑器只负责生成 DSL最终把它**渲染成可见页面**的工作交给 runtime
编辑器生成出来的DSL需要通过 runtime 来渲染。 在一份完整的 tmagic-editor 项目中runtime 同时承担两个角色:
## 实现一个 runtime | 角色 | 入口 | 用途 |
| --- | --- | --- |
| **page** | `runtime/vue/page/` | 线上发布产物,加载 `window.magicDSL` 渲染真实页面 |
| **playground** | `runtime/vue/playground/` | 编辑器中央 iframe 加载的画布,响应增删改并渲染所见即所得 |
:::tip 两者共用同一份组件、插件、数据源代码,只在入口(`main.ts` / `App.vue`)上有差异。
可以使用`npm create tmagic` 来快速创建一个runtime项目。
::: tip
DSL、playground 与 editor 之间的通信原理可以前往[教程](/guide/tutorial/)继续了解。
::: :::
创建出来的项目会包含page、playground两个目录。 ## 创建 runtime 项目
::: tip
推荐用 `npm create tmagic@latest` / `pnpm create tmagic` 快速生成 runtime 模板,按提示选择 `runtime` 即可。
:::
生成的项目结构如下(与 [`runtime/vue/`](https://github.com/Tencent/tmagic-editor/tree/master/runtime/vue) 完全一致):
```bash ```bash
. runtime/vue
├── page ├── page/ # 线上 page 入口
├── playground │ ├── App.vue
│ ├── index.html
│ ├── main.ts
│ └── utils/
├── playground/ # 编辑器内 iframe 入口
│ ├── App.vue
│ ├── index.html
│ └── main.ts
├── public/
├── scripts/ # build 脚本res / page / playground / all
├── tmagic.config.ts # @tmagic/cli 配置:声明组件、插件、数据源
├── tmagic.config.local.ts# 本地覆盖配置(可选)
└── vite.config.ts # 多入口构建page + playground
``` ```
page用于生产环境 ## tmagic.config.ts声明组件 / 插件 / 数据源
playground用于编辑器中 `tmagic.config.ts` 是 [@tmagic/cli](./publish.md#tmagic-cli) 的入口,它会扫描 `packages` 列表,生成 `.tmagic/comp-entry.ts` 等 5 个入口文件runtime 只需要从这些入口里 `import` 即可:
:::tip ```ts
想要了解DSL的解析以及runtime与编辑器的通信可以前往[教程](/guide/tutorial/index.md) import { defineConfig } from '@tmagic/cli';
export default defineConfig({
componentFileAffix: '.vue',
// 是否使用 vite + 异步组件,详见 page/main.ts 中的 defineAsyncComponent
dynamicImport: true,
npmConfig: {
client: 'pnpm',
keepPackageJsonClean: true,
},
packages: [
{
// key 为组件 type需要与编辑器中 componentGroupList 的 type 对应
button: '@tmagic/vue-button',
container: '@tmagic/vue-container',
img: '@tmagic/vue-img',
'iterator-container': '@tmagic/vue-iterator-container',
overlay: '@tmagic/vue-overlay',
page: '@tmagic/vue-page',
'page-fragment': '@tmagic/vue-page-fragment',
'page-fragment-container': '@tmagic/vue-page-fragment-container',
qrcode: '@tmagic/vue-qrcode',
text: '@tmagic/vue-text',
},
],
});
```
`tmagic.config.local.ts` 用于本地覆盖(不会被提交),常见用法是把线上 npm 包临时替换为本地组件目录调试。
执行 `npm run tmagic`(即 `tmagic entry`runtime 根目录下会生成:
```bash
.tmagic/
├── comp-entry.ts # page 同步组件入口
├── async-comp-entry.ts # page 异步组件入口dynamicImport 时使用)
├── config-entry.ts # 编辑器右侧表单配置
├── value-entry.ts # 组件初始值
├── event-entry.ts # 组件事件 / 方法列表
├── plugin-entry.ts # 插件入口
├── datasource-entry.ts # 同步数据源入口
└── async-datasource-entry.ts # 异步数据源入口
```
> 详细产物说明见[页面发布 § @tmagic/cli](./publish.md#tmagic-cli)。
## playground runtime 实现
playground 是编辑器中央 iframe 加载的画布,最关键的逻辑就是把编辑器派发的 DSL 变更同步到本地 Vue 状态并触发重新渲染。
`@tmagic/vue-runtime-help` 提供的 `useEditorDsl` Hook 已经帮我们实现了与编辑器的通信(`onRuntimeReady` / `updateRootConfig` / `updatePageId` / `add` / `update` / `remove` 等);只需要在入口里:
1. 创建 `TMagicApp` 实例,注册组件、数据源、插件;
2. 通过 `provide('app', app)` 把实例注入子组件;
3. 在 `App.vue` 里使用 `useEditorDsl()` + `useComponent('page')` 渲染页面。
完整的 [`runtime/vue/playground/main.ts`](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/playground/main.ts)
```ts
import { createApp } from 'vue';
import TMagicApp, { DataSourceManager, DeepObservedData } from '@tmagic/core';
import App from './App.vue';
import '@tmagic/core/resetcss.css';
DataSourceManager.registerObservedData(DeepObservedData);
Promise.all([
import('../.tmagic/comp-entry'),
import('../.tmagic/plugin-entry'),
import('../.tmagic/datasource-entry'),
]).then(([components, plugins, dataSources]) => {
const vueApp = createApp(App);
const app = new TMagicApp({
ua: window.navigator.userAgent,
platform: 'editor',
});
if (app.env.isWeb) {
app.setDesignWidth(window.document.documentElement.getBoundingClientRect().width);
}
Object.entries(components.default).forEach(([type, component]: [string, any]) => {
app.registerComponent(type, component);
});
Object.entries(dataSources.default).forEach(([type, ds]: [string, any]) => {
DataSourceManager.register(type, ds);
});
Object.values(plugins.default).forEach((plugin: any) => {
vueApp.use(plugin, { app });
});
window.appInstance = app;
vueApp.config.globalProperties.app = app;
vueApp.provide('app', app);
vueApp.mount('#app');
});
```
[`playground/App.vue`](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/playground/App.vue) 出乎意料地短:
```vue
<template>
<component v-if="pageConfig" :is="pageComponent" :key="pageConfig.id" :config="pageConfig"></component>
</template>
<script lang="ts" setup>
import { useComponent, useEditorDsl } from '@tmagic/vue-runtime-help';
const { pageConfig } = useEditorDsl();
const pageComponent = useComponent('page');
</script>
```
::: tip 关键点
- `platform: 'editor'` 告知 `@tmagic/core` 进入编辑模式;
- `useEditorDsl()` 内部已经调用 `window.magic?.onRuntimeReady({...})`,把 add/update/remove 等回调挂载到全局,编辑器通过 `iframe.contentWindow.magic` 触发;
- 当 DSL 变化时,`pageConfig` 自动更新;当页面 DOM 渲染完成,`useEditorDsl` 会调用 `magic.onPageElUpdate(...)` 把页面元素同步给编辑器,让选中框能够吸附。
::: :::
## page runtime 实现(线上发布)
[`runtime/vue/page/main.ts`](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/page/main.ts) 与 playground 的差别在于:
1. 不需要响应编辑器消息,直接读取 `window.magicDSL`(或 `localPreview` 模式下从 `localStorage` 读取);
2. 使用 `defineAsyncComponent` + 异步入口,按需加载组件,**减小首屏体积**
3. 数据源走 `registerDataSourceOnDemand`,只注册当前 DSL 用到的;
4. 注入 `request``userRender` 等业务侧 API 给组件复用。
```ts
import { createApp, defineAsyncComponent, resolveDirective, withDirectives } from 'vue';
import TMagicApp, { DataSourceManager, DeepObservedData, getUrlParam, registerDataSourceOnDemand } from '@tmagic/core';
import components from '../.tmagic/async-comp-entry';
import asyncDataSources from '../.tmagic/async-datasource-entry';
import plugins from '../.tmagic/plugin-entry';
import request, { service } from './utils/request';
import AppComponent from './App.vue';
import { getLocalConfig } from './utils';
import '@tmagic/core/resetcss.css';
DataSourceManager.registerObservedData(DeepObservedData);
const vueApp = createApp(AppComponent);
vueApp.use(request);
const dsl = ((getUrlParam('localPreview') ? getLocalConfig() : window.magicDSL) || [])[0] || {};
const app = new TMagicApp({
ua: window.navigator.userAgent,
config: dsl,
request: service,
curPage: getUrlParam('page'),
useMock: Boolean(getUrlParam('useMock')),
});
app.setDesignWidth(app.env.isWeb ? window.document.documentElement.getBoundingClientRect().width : 375);
Object.entries(components).forEach(([type, component]: [string, any]) => {
app.registerComponent(type, defineAsyncComponent(component));
});
Object.values(plugins).forEach((plugin: any) => {
vueApp.use(plugin, { app });
});
registerDataSourceOnDemand(dsl, asyncDataSources).then((dataSources) => {
Object.entries(dataSources).forEach(([type, ds]: [string, any]) => {
DataSourceManager.register(type, ds);
});
vueApp.config.globalProperties.app = app;
vueApp.provide('app', app);
vueApp.mount('#app');
});
```
[`page/App.vue`](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/page/App.vue) 用 `useDsl()`(注意不是 `useEditorDsl`
```vue
<template>
<component :is="pageComponent" :config="pageConfig as MPage"></component>
</template>
<script lang="ts" setup>
import type { MPage } from '@tmagic/core';
import { useComponent, useDsl } from '@tmagic/vue-runtime-help';
const { pageConfig, app } = useDsl();
const pageComponent = useComponent('page');
</script>
```
## vite 多入口构建
`runtime/vue` 通过单个 vite 工程构建出两份产物([`vite.config.ts`](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/vite.config.ts)
```ts
build: {
rolldownOptions: {
input: {
page: path.resolve(__dirname, './page/index.html'),
playground: path.resolve(__dirname, './playground/index.html'),
},
},
}
```
加上 `package.json` 中提供的 build 脚本:
```json
{
"scripts": {
"tmagic": "tmagic entry",
"dev": "vite --force",
"build": "rimraf ./dist && node scripts/build.mjs --type=all",
"build:libs": "node scripts/build.mjs --type=res",
"build:page": "node scripts/build.mjs --type=page",
"build:playground": "node scripts/build.mjs --type=playground"
}
}
```
最常用的两个:
- `npm run build:libs`:构建 **编辑器侧**用到的 `config / value / event / ds-config / ds-value` 五份 UMD 资源(输出到 `dist/entry/`),编辑器通过 `asyncLoadJs` 异步加载(参考[快速开始 § propsConfigs / propsValues](./index.md#propsconfigs-propsvalues))。
- `npm run build`:同时产出 `playground/index.html``page/index.html``entry/`,可以一份产物覆盖编辑器、预览、线上三种场景。
## @tmagic/vue-runtime-help 常用 Hook
| Hook | 作用 |
| --- | --- |
| `useEditorDsl()` | playground 入口使用,建立与编辑器通信、维护当前页面 `pageConfig` |
| `useDsl()` | page 入口使用,从 `window.magicDSL` 中读取并维护 `pageConfig` |
| `useComponent(type)` | 通过组件 type 解析出已注册的 Vue 组件(找不到时会回退到 `magic-ui-${type}` |
| `useApp()` | 取出注入的 `TMagicApp` 实例 |
| `useComponentStatus()` | 获取组件在编辑器中的展示/禁用状态 |
::: tip
React runtime 的实现思路完全一致,对应包是 [`@tmagic/react-runtime-help`](https://github.com/Tencent/tmagic-editor/tree/master/runtime/react-runtime-help),可以参照本节自行迁移。
:::
## 跨域
playground 是被编辑器以 iframe 形式加载的,开发期需要保证 runtime 服务允许跨域。仓库里的做法是用 Vite 的 proxy 把 runtime 反代到 playground 同域:
```ts
// playground/vite.config.ts
server: {
port: 8098,
proxy: {
'^/tmagic-editor/playground/runtime': {
target: 'http://127.0.0.1:8078',
changeOrigin: true,
prependPath: false,
},
},
}
```
如果编辑器和 runtime 跨域部署,需要在 runtime 服务侧返回 `Access-Control-Allow-Origin`,并保证 iframe 的 `postMessage` 同源策略允许双方通信。
## 进一步阅读
- [基础概念](./conception.md)编辑器、模拟器、runtime 的关系
- [组件开发](./component.md)组件四件套component / form-config / init-value / event
- [页面发布](./publish.md)page.html 注入 DSL 的发布流程
- [教程](./tutorial/index.md):从零实现一份 runtime理解 magic API 与 DSL 解析

View File

@ -162,12 +162,14 @@ const value = ref({
加上初始值后点击新增页面就可以渲染出一个画布了但是点击添加HelloWorld组件依然没有反应 加上初始值后点击新增页面就可以渲染出一个画布了但是点击添加HelloWorld组件依然没有反应
这是因为这时的编辑器并能理解HelloWorld是什么需要在[render](../../api/editor/props.html#render)函数中处理 这是因为这时的编辑器并能理解HelloWorld是什么需要在[render](../../api/editor/props.html#render)函数中处理
## 渲染 ## 渲染
api详情[render](../../api/editor/props.md#render) api详情[render](../../api/editor/props.md#render)
> 以下片段省略了 `page` 的获取与完整定义仅展示渲染思路完整示例见下文「最终完整的render函数实现」。
```ts ```ts
const render = () => { const render = () => {
const root = window.document.createElement('div'); const root = window.document.createElement('div');
@ -279,10 +281,10 @@ const render = async ({ renderer }: StageCore) => {
}; };
``` ```
以上就是一个简单的搭建编辑器的示例,安装上面的步骤完成后会发现可以添加组件也可选中组件但是无法拖动配置属性中的样式也无法生效这是因为上述的render函数并不完整没有处理dsl中style下一节将详细介绍runtime的搭建将不再使用render函数的方式而是使用[runtimeUrl](../../api/editor/props.md#runtimeurl)。 以上就是一个简单的搭建编辑器的示例,按照上面的步骤完成后会发现可以添加组件也可选中组件但是无法拖动配置属性中的样式也无法生效这是因为上述的render函数并不完整没有处理dsl中style下一节将详细介绍runtime的搭建将不再使用render函数的方式而是使用[runtimeUrl](../../api/editor/props.md#runtimeurl)。
::: tip ::: tip
并不是render函数不好但是从设计上render函数还是让渲染逻辑落到了编辑器中@tmagic/editor的设计是希望做到渲染跟编辑器解耦 并不是render函数不好但是从设计上render函数还是让渲染逻辑落到了编辑器中@tmagic/editor的设计是希望做到渲染跟编辑器解耦
::: :::
[源码](https://github.com/vft-magic/tmagic-tutorial) [源码](https://github.com/vft-magic/tmagic-tutorial)

View File

@ -1,18 +1,32 @@
# 3.[DSL](../conception.md#dsl) 解析渲染 # 3.[DSL](../conception.md#dsl) 解析渲染
tmagic 提供了 vue/react 两个版本的解析渲染组件,可以直接使用 tmagic 提供了 vue/react 两个版本的解析渲染组件,可以直接使用。基础渲染组件以 container 为核心,配合 page、button、img、text 等多个独立的 npm 包,分别发布在 `vue-components/``react-components/` 下:
[@tmagic/ui](https://www.npmjs.com/package/@tmagic/ui) vue 版本:
[@tmagic/ui-react](https://www.npmjs.com/package/@tmagic/ui-react) - [@tmagic/vue-container](https://www.npmjs.com/package/@tmagic/vue-container)
- [@tmagic/vue-page](https://www.npmjs.com/package/@tmagic/vue-page)
- [@tmagic/vue-button](https://www.npmjs.com/package/@tmagic/vue-button)
- [@tmagic/vue-img](https://www.npmjs.com/package/@tmagic/vue-img)
- [@tmagic/vue-text](https://www.npmjs.com/package/@tmagic/vue-text)
- 其他:`@tmagic/vue-overlay``@tmagic/vue-qrcode``@tmagic/vue-page-fragment``@tmagic/vue-page-fragment-container``@tmagic/vue-iterator-container`
接下来是以vue为基础来讲述如何实现一个[@tmagic/ui](https://www.npmjs.com/package/@tmagic/ui) react 版本:
- [@tmagic/react-container](https://www.npmjs.com/package/@tmagic/react-container)
- [@tmagic/react-page](https://www.npmjs.com/package/@tmagic/react-page)
- [@tmagic/react-button](https://www.npmjs.com/package/@tmagic/react-button)
- [@tmagic/react-img](https://www.npmjs.com/package/@tmagic/react-img)
- [@tmagic/react-text](https://www.npmjs.com/package/@tmagic/react-text)
- 其他:`@tmagic/react-overlay``@tmagic/react-qrcode``@tmagic/react-page-fragment``@tmagic/react-page-fragment-container``@tmagic/react-iterator-container`
接下来是以 vue 为基础,来讲述如何实现一个类似 [@tmagic/vue-container](https://www.npmjs.com/package/@tmagic/vue-container) 的渲染器
## 准备工作 ## 准备工作
### 创建项目 ### 创建项目
将[上一教程](./runtime.md)中的[editor-runtime](https://github.com/jia000/tmagic-tutorial/tree/master/course2/editor-runtime)和[hello-editor](https://github.com/jia000/tmagic-tutorial/tree/master/course2/hellow-editor)复制过来 将[上一教程](./runtime.md)中的[editor-runtime](https://github.com/jia000/tmagic-tutorial/tree/master/course2/editor-runtime)和[hello-editor](https://github.com/jia000/tmagic-tutorial/tree/master/course2/hello-editor)复制过来
## 基础概念 ## 基础概念
@ -69,7 +83,7 @@ app.component('hello-world', HelloWorld);
```vue ```vue
<template> <template>
<component v-if="config" :is="type" :tmagic-data-id="`${id}`" :style="style" :config="config"></component> <component v-if="config" :is="type" :data-tmagic-id="`${id}`" :style="style" :config="config"></component>
</template> </template>
<script lang=ts setup> <script lang=ts setup>
@ -91,7 +105,7 @@ const id = computed(() => props.config.id);
</script> </script>
``` ```
接下来就需要解析节点的样式在tmagic/editor中默认会将样式配置保存到节点的style属性中,如果自行定义到了其他属性,则已实际为准 接下来就需要解析节点的样式,在@tmagic/editor中默认会将样式配置保存到节点的style属性中,如果自行定义到了其他属性,则以实际为准
解析style需要注意几个地方 解析style需要注意几个地方
@ -99,13 +113,13 @@ const id = computed(() => props.config.id);
css中的数值有些是需要单位的例如px有些是不需要的例如opacity css中的数值有些是需要单位的例如px有些是不需要的例如opacity
在tmagic/editor中默认都是不带单位的所以需要将需要单位的地方补齐单位 @tmagic/editor中,默认都是不带单位的,所以需要将需要单位的地方补齐单位
这里做补齐px处理如果需要做屏幕大小适应 可以使用rem或者vw这个可以根据自身需求处理。 这里做补齐px处理如果需要做屏幕大小适应 可以使用rem或者vw这个可以根据自身需求处理。
2. url 2. url
css中的[url](https://developer.mozilla.org/zh-CN/docs/Web/CSS/url)需要是用url()所以当值为url时需要转为url(xxx) css中的[url](https://developer.mozilla.org/zh-CN/docs/Web/CSS/url)需要使用 url()所以当值为url时需要转为url(xxx)
3. transform 3. transform

View File

@ -178,6 +178,8 @@ declare global {
} }
``` ```
> 以下片段中 `page` 来自前文中 App.vue 内的 `const page = ref<any>();`,此处省略其重复声明。
```ts ```ts
import type { Id, MApp, MNode } from '@tmagic/core'; import type { Id, MApp, MNode } from '@tmagic/core';
import type { RemoveData, UpdateData } from '@tmagic/stage'; import type { RemoveData, UpdateData } from '@tmagic/stage';
@ -228,7 +230,7 @@ watch(page, async () => {
}); });
``` ```
以上就是一个简单runtime实现以及与编辑的交互这是一个不完善的实现(会发现组件画布中无法自由拖动是因为没有完整的解析style),但是其中已经几乎覆盖所有需要关心的内容 以上就是一个简单runtime实现以及与编辑的交互这是一个不完善的实现(会发现组件画布中无法自由拖动是因为没有完整的解析style),但是其中已经几乎覆盖所有需要关心的内容
当前教程中实现了一个简单的pagetmagic提供了一个比较完善的实现将在下一节介绍 当前教程中实现了一个简单的pagetmagic提供了一个比较完善的实现将在下一节介绍

View File

@ -36,15 +36,32 @@ new App(options: AppOptionsConfig)
| 属性 | 类型 | 说明 | | 属性 | 类型 | 说明 |
|------|------|------| |------|------|------|
| `env` | `Env` | 环境信息实例 | | `env` | `Env` | 环境信息实例 |
| `dsl` | `MApp` | DSL 配置 | | `dsl` | `MApp \| undefined` | DSL 配置 |
| `codeDsl` | `CodeBlockDSL` | 代码块配置 | | `codeDsl` | `CodeBlockDSL \| undefined` | 代码块配置 |
| `dataSourceManager` | `DataSourceManager \| undefined` | 数据源管理器 | | `dataSourceManager` | `DataSourceManager \| undefined` | 数据源管理器 |
| `page` | `Page \| undefined` | 当前页面 | | `page` | `Page \| undefined` | 当前页面 |
| `pageFragments` | `Map<Id, Page>` | 页面片段集合 | | `pageFragments` | `Map<Id, Page>` | 页面片段集合 |
| `platform` | `string` | 平台类型 | | `platform` | `string` | 平台类型 |
| `jsEngine` | `JsEngine` | JS 引擎类型 | | `jsEngine` | `JsEngine` | JS 引擎类型 |
| `components` | `Map<string, any>` | 已注册的组件 | | `components` | `Map<string, any>` | 已注册的组件 |
| `eventHelper` | `EventHelper` | 事件助手实例 | | `eventHelper` | `EventHelper \| undefined` | 事件助手实例(仅当 `platform !== 'editor'` 时创建) |
| `useMock` | `boolean` | 是否使用 Mock 数据,默认 `false` |
| `request` | `RequestFunction \| undefined` | 请求函数 |
| `transformStyle` | `(style: Record<string, any>) => Record<string, any>` | 样式转换函数 |
| `pageFragmentContainerType` | `Set<string>` | 页面片段容器类型集合,默认包含 `page-fragment-container` |
| `iteratorContainerType` | `Set<string>` | 迭代器容器类型集合,默认包含 `iterator-container` |
| `errorHandler` | `ErrorHandler \| undefined` | 错误处理器 |
| `nodeStoreInitialData` | `(() => any) \| undefined` | 节点存储初始数据工厂函数 |
## 静态属性
### nodeClassMap
- **类型:** `Map<string, typeof Node>`
- **详情:**
自定义节点类型的映射表,由 `App.registerNode` 写入;`Page` 在初始化节点时会按 `config.type` 从此 Map 中查找对应的节点类,未命中则回退到默认 `Node`
## 静态方法 ## 静态方法
@ -59,7 +76,7 @@ new App(options: AppOptionsConfig)
- **详情:** - **详情:**
注册自定义节点类型,用于扩展节点功能。 注册自定义节点类型,用于扩展节点功能。内部会将 `NodeClass` 写入 `App.nodeClassMap`
- **示例:** - **示例:**
@ -78,22 +95,25 @@ App.registerNode('custom', CustomNode);
### setEnv ### setEnv
- **参数:** - **参数:**
- `{string} ua` User Agent 字符串 - `{string | Env} ua` User Agent 字符串`Env` 实例(可选)
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
设置环境信息,会根据 UA 字符串更新 `env` 属性 设置环境信息。当传入字符串(或不传)时,会基于 UA 创建一个新的 `Env` 实例并赋值给 `env` 属性;当传入 `Env` 实例时,直接将其设置为当前 `env`
- **示例:** - **示例:**
```typescript ```typescript
import App from '@tmagic/core'; import App, { Env } from '@tmagic/core';
const app = new App({}); const app = new App({});
app.setEnv(navigator.userAgent); app.setEnv(navigator.userAgent);
// 也可以直接传入已创建的 Env 实例
app.setEnv(new Env(navigator.userAgent));
``` ```
### setDesignWidth ### setDesignWidth
@ -181,7 +201,7 @@ app.setPage('page_2');
- **详情:** - **详情:**
获取指定 ID 的页面,不传 ID 则返回当前页面 获取页面:不传 `id` 时返回当前 `this.page`;传入 `id` 时,仅当其与当前 `this.page.data.id` 一致时返回该页面,否则返回 `undefined`。该方法不会按 DSL 遍历所有页面查找
- **示例:** - **示例:**
@ -260,6 +280,19 @@ app.registerComponent('my-button', MyButton);
解析组件,返回已注册的组件。 解析组件,返回已注册的组件。
### emit
- **参数:**
- `{string | symbol} name` 事件名
- `{...any[]} args` 事件参数;约定第一个参数为触发事件的 `Node` 实例
- **返回:**
- `{boolean}`
- **详情:**
重写自 `EventEmitter.emit`。当第一个参数是 `Node` 实例,并且该节点的 `eventKeys` 中存在 `${name}_${node.data.id}` 时,会将事件经由 `EventHelper` 用对应的 `Symbol` 转发(即触发联动事件配置);否则按 `EventEmitter` 默认逻辑触发。
### runCode ### runCode
- **参数:** - **参数:**
@ -270,16 +303,16 @@ app.registerComponent('my-button', MyButton);
- `{Node} node` 节点(可选) - `{Node} node` 节点(可选)
- **返回:** - **返回:**
- `{any}` - `{Promise<void>}` 该方法不会显式返回代码块的返回值。如需获取代码块结果,需在代码块内自行通过 `params`/`flowState` 等回写。
- **详情:** - **详情:**
执行代码块。 执行代码块。`codeId` 为空、`codeDsl` 为空,或代码块的 `content` 不是函数时直接返回;否则 `await` 执行代码块函数。如果执行过程中抛出异常,存在 `errorHandler` 时会交由其处理,否则继续抛出。
- **示例:** - **示例:**
```typescript ```typescript
const result = await app.runCode('code_1', { key: 'value' }); await app.runCode('code_1', { key: 'value' });
``` ```
### runDataSourceMethod ### runDataSourceMethod
@ -293,11 +326,11 @@ const result = await app.runCode('code_1', { key: 'value' });
- `{Node} node` 节点(可选) - `{Node} node` 节点(可选)
- **返回:** - **返回:**
- `{any}` - `{Promise<any | undefined>}` 取决于数据源方法的返回值。当 `dsId``methodName` 缺失,或数据源不存在、未匹配到方法时,返回 `undefined`
- **详情:** - **详情:**
执行数据源方法。 执行数据源方法。如果执行过程中抛出异常,存在 `errorHandler` 时会交由其处理,否则继续抛出。
- **示例:** - **示例:**
@ -319,3 +352,24 @@ const result = await app.runDataSourceMethod('ds_1', 'fetchData', { id: 123 });
```typescript ```typescript
app.destroy(); app.destroy();
``` ```
## 事件
`App` 继承自 `EventEmitter`,会通过 `super.emit` 触发以下事件:
| 事件名 | 触发时机 | 回调参数 |
|--------|----------|----------|
| `dsl-change` | 调用 `setConfig` 时触发 | `({ dsl: MApp, curPage: Id })` |
| `page-change` | 调用 `setPage` 切换页面时触发;切换到不存在的页面时也会触发,此时回调无参数。**注意**:当 `pageConfig === this.page.data`(重复 setPage 到当前页)时会直接 `return`**不**触发该事件 | `(page?: Page)` |
### 监听示例
```typescript
app.on('dsl-change', ({ dsl, curPage }) => {
console.log('DSL 已更新', dsl, curPage);
});
app.on('page-change', (page) => {
console.log('当前页面切换为', page?.data?.id);
});
```

View File

@ -58,17 +58,26 @@ devtoolApi.setDataSourceData('ds_1', { name: 'test' });
devtoolApi.setDataSourceData('ds_1', 'newValue', 'user.name'); devtoolApi.setDataSourceData('ds_1', 'newValue', 'user.name');
``` ```
### delDataSourceData
- **返回:**
- `{void}`
- **详情:**
当前为空实现(预留接口),由具体的开发工具/平台覆盖以实现"删除数据源数据"的能力。
### requestDataSource ### requestDataSource
- **参数:** - **参数:**
- `{Id} dsId` 数据源 ID - `{Id} dsId` 数据源 ID
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void> | void}`
- **详情:** - **详情:**
触发 HTTP 数据源的请求。 触发 HTTP 数据源的请求。优先调用 `dataSource.refresh`,否则调用 `dataSource.request`,再否则将 `isInit` 置为 `false` 并通过 `dataSourceManager.init(ds)` 重新初始化。
- **示例:** - **示例:**
@ -80,59 +89,73 @@ await devtoolApi.requestDataSource('http_ds_1');
- **参数:** - **参数:**
- `{Id} nodeId` 节点 ID - `{Id} nodeId` 节点 ID
- `{CondItem} condItem` 条件项 - `{DisplayCondItem} condItem` 单个条件项
- **返回:** - **返回:**
- `{any}` - `{any}`
- **详情:** - **详情:**
获取显示条件的实际计算值。 获取显示条件的实际计算值。内部会以 `{ [NODE_CONDS_KEY]: [{ cond: [condItem] }] }` 的形式调用 `dataSourceManager.compliedConds`
### callHook ### callHook
- **参数:** - **参数:**
- `{Id} nodeId` 节点 ID - `{Id} nodeId` 节点 ID
- `{string} hookName` 钩子名称 - `{string} hookName` 钩子名称
- `{any} hookData` 钩子数据 - `{ { params: Record<string, any> }[] } hookData` 钩子数据列表,依次传给 `node.runHookCode`
- **返回:**
- `{Promise<any>}`
- **详情:**
调用节点的钩子函数。
- **示例:**
```typescript
await devtoolApi.callHook('button_1', 'mounted', { data: 'test' });
```
### trigger
- **参数:**
- `{Id} nodeId` 节点 ID
- `{EventConfig[]} events` 事件配置数组
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
触发节点的事件 调用节点的钩子函数。会按 `hookData` 顺序执行,每项以 `item.params` 作为 `runHookCode` 的入参。
- **示例:** - **示例:**
```typescript ```typescript
await devtoolApi.trigger('button_1', [ await devtoolApi.callHook('button_1', 'mounted', [
{ { params: { data: 'test' } },
name: 'click',
actions: [{ actionType: 'code', codeId: 'code_1' }]
}
]); ]);
``` ```
### trigger
- **参数:**
- `{Id} nodeId` 节点 ID
- `{EventConfig} eventConfig` 事件配置(单个,非数组)
- **返回:**
- `{void}`
- **详情:**
按节点触发事件。内部通过 `app.emit(eventConfig.name, node)` 触发对应事件。
- **示例:**
```typescript
devtoolApi.trigger('button_1', {
name: 'click',
actions: [{ actionType: 'code', codeId: 'code_1' }]
});
```
### updateDsl
- **参数:**
- `{Id} nodeId` 节点 ID
- `{any} data` 数据
- `{string} path` 路径
- **返回:**
- `{void}`
- **详情:**
当前为空实现(预留接口),由具体的开发工具/平台覆盖以实现"按节点更新 DSL"的能力。
### isValueIncludeDataSource ### isValueIncludeDataSource
- **参数:** - **参数:**
@ -175,14 +198,18 @@ const compiled = devtoolApi.compileDataSourceValue('用户名:${ds_1.user.name
- **参数:** - **参数:**
- `{Id} codeId` 代码块 ID - `{Id} codeId` 代码块 ID
- `{any} value` 新值 - `{any} value` 新值
- `{string} path` 路径(可选 - `{string} path` 路径(必填
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
更新代码块的内容。 `path` 更新指定代码块的内容。当 `path === 'content'``value` 为字符串时,**当前实现**会通过 `eval` 拼接执行后将函数写回。
::: warning 已知限制
当前 `eval` 模板存在多余的右括号(详见 `packages/core/src/DevtoolApi.ts``updateCode`**对大部分常规函数字面量会因语法错误抛出**。直接传入纯函数体或可被裸赋值的合法表达式时也需自行验证;如需稳定使用建议在调用方先编译为函数再写回 `app.codeDsl[codeId].content`,或等待该实现修复。
:::
- **示例:** - **示例:**

View File

@ -5,18 +5,19 @@
## 构造函数 ## 构造函数
```typescript ```typescript
new Env(ua?: string) new Env(ua?: string, options?: Record<string, boolean | string>)
``` ```
### 参数 ### 参数
| 参数 | 类型 | 说明 | | 参数 | 类型 | 说明 |
|------|------|------| |------|------|------|
| `ua` | `string` | User Agent 字符串(可选,默认使用 `navigator.userAgent` | | `ua` | `string` | User Agent 字符串(可选,默认使用 `globalThis.navigator?.userAgent` |
| `options` | `Record<string, boolean \| string>` | 额外的环境字段(可选)。构造时会通过 `Object.entries` 写入到实例上,可用于扩展自定义环境标记。**注意**:构造函数在 `ua` 为空(包括 `''``undefined` 等 falsy 值)时会**提前返回**,此时 `options` 同样**不会**被应用 |
## 属性 ## 属性
所有属性均为只读布尔值: 所有属性均为可赋值的公共字段(非只读),默认布尔值`false`
| 属性 | 类型 | 说明 | | 属性 | 类型 | 说明 |
|------|------|------| |------|------|------|
@ -32,6 +33,8 @@ new Env(ua?: string)
| `isWeb` | `boolean` | 是否为 Web 环境 | | `isWeb` | `boolean` | 是否为 Web 环境 |
| `isOpenHarmony` | `boolean` | 是否为鸿蒙系统 | | `isOpenHarmony` | `boolean` | 是否为鸿蒙系统 |
`Env` 上还允许通过索引签名 `[x: string]: any` 写入自定义字段。
## 使用示例 ## 使用示例
```typescript ```typescript
@ -51,6 +54,10 @@ if (env.isWechat) {
// 使用自定义 UA // 使用自定义 UA
const customEnv = new Env('Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)'); const customEnv = new Env('Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)');
console.log(customEnv.isIphone); // true console.log(customEnv.isIphone); // true
// 通过 options 注入自定义环境标记
const customEnv2 = new Env(navigator.userAgent, { isMiniProgram: true });
console.log(customEnv2.isMiniProgram); // true
``` ```
## 在 App 中使用 ## 在 App 中使用

View File

@ -13,12 +13,15 @@ new EventHelper(options: EventHelperOptions)
| 参数 | 类型 | 说明 | | 参数 | 类型 | 说明 |
|------|------|------| |------|------|------|
| `app` | `App` | 应用实例 | | `app` | `App` | 应用实例 |
| `beforeEventHandler` | `BeforeEventHandler` | 事件处理前钩子(可选),形如 `({ eventConfig, source, args }) => void` |
| `afterEventHandler` | `AfterEventHandler` | 事件处理后钩子(可选),形如 `({ eventConfig, source, args }) => void` |
## 属性 ## 属性
| 属性 | 类型 | 说明 | | 属性 | 类型 | 说明 |
|------|------|------| |------|------|------|
| `app` | `App` | 应用实例 | | `app` | `App` | 应用实例 |
| `eventQueue` | `EventCache[]` | 暂存的待处理事件队列(参见 `getEventQueue` |
## 实例方法 ## 实例方法
@ -76,28 +79,28 @@ eventHelper.bindNodeEvents(node);
### removeDataSourceEvents ### removeDataSourceEvents
- **参数:** - **参数:**
- `{DataSourceSchema[]} dataSourceList` 数据源列表(可选 - `{DataSource[]} dataSourceList` 数据源实例列表(必填
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
移除数据源事件绑定。 移除给定数据源事件绑定。内部根据已注册的事件名前缀,调用 `dataSource.offDataChange``dataSource.off` 注销监听,并清空 `dataSourceEventList`
### getEventQueue ### getEventQueue
- **返回:** - **返回:**
- `{EventConfig[]}` - `{EventCache[]}` 事件缓存项数组,每项形如 `{ toId: Id, method: string, fromCpt: any, args: any[], handled?: boolean }`
- **详情:** - **详情:**
获取当前事件队列。 获取当前事件队列。当目标节点尚未挂载时,联动事件会被缓存到此队列;目标节点 `mounted` 后,会消费匹配项并调用其 `instance` 上的对应方法。
### addEventToQueue ### addEventToQueue
- **参数:** - **参数:**
- `{EventConfig} event` 事件配置 - `{EventCache} event` 事件缓存项,形如 `{ toId: Id, method: string, fromCpt: any, args: any[] }`
- **返回:** - **返回:**
- `{void}` - `{void}`

View File

@ -60,16 +60,16 @@ iteratorContainer.setData({
- `{Map<Id, Node>} map` 节点映射表 - `{Map<Id, Node>} map` 节点映射表
- **返回:** - **返回:**
- `{Node}` - `{void}`
- **详情:** - **详情:**
在指定的节点映射表中初始化节点。 在指定的节点映射表中初始化节点。当节点类型属于 `app.iteratorContainerType` 时,会创建嵌套的 `IteratorContainer` 并直接返回(不再继续向下递归 `config.items`);否则创建普通 `Node` 后会递归初始化 `config.items`
### setNodes ### setNodes
- **参数:** - **参数:**
- `{Map<Id, Node>} nodes` 节点映射表 - `{MNode[]} nodes` 节点配置数组
- `{number} index` 迭代索引 - `{number} index` 迭代索引
- **返回:** - **返回:**
@ -77,26 +77,31 @@ iteratorContainer.setData({
- **详情:** - **详情:**
设置指定索引的节点映射表 `index``this.nodes[index]` 上构建/更新该迭代项对应的节点映射表,内部会对每个节点配置调用 `initNode`
- **示例:** - **示例:**
```typescript ```typescript
iteratorContainer.setNodes(nodesMap, 0); iteratorContainer.setNodes(
[
{ id: 'text_1', type: 'text', text: 'hello' },
],
0,
);
``` ```
### getNode ### getNode
- **参数:** - **参数:**
- `{Id} id` 节点 ID - `{Id} id` 节点 ID
- `{number} index` 迭代索引(可选,默认为 0 - `{number} index` 迭代索引
- **返回:** - **返回:**
- `{Node | undefined}` - `{Node | undefined}`
- **详情:** - **详情:**
获取指定迭代索引中的节点。 获取指定迭代索引中的节点。`index` 为必填参数。
- **示例:** - **示例:**

View File

@ -14,7 +14,7 @@ new Node(options: NodeOptions)
|------|------|------| |------|------|------|
| `config` | `MNode` | 节点配置 | | `config` | `MNode` | 节点配置 |
| `parent` | `Node` | 父节点(可选) | | `parent` | `Node` | 父节点(可选) |
| `page` | `Page` | 所属页面 | | `page` | `Page` | 所属页面(可选) |
| `app` | `App` | 应用实例 | | `app` | `App` | 应用实例 |
## 属性 ## 属性
@ -25,7 +25,7 @@ new Node(options: NodeOptions)
| `style` | `object` | 节点样式 | | `style` | `object` | 节点样式 |
| `events` | `EventConfig[]` | 事件配置 | | `events` | `EventConfig[]` | 事件配置 |
| `instance` | `any` | 组件实例 | | `instance` | `any` | 组件实例 |
| `page` | `Page` | 所属页面 | | `page` | `Page \| undefined` | 所属页面 |
| `parent` | `Node \| undefined` | 父节点 | | `parent` | `Node \| undefined` | 父节点 |
| `app` | `App` | 应用实例 | | `app` | `App` | 应用实例 |
| `store` | `Store` | 节点存储 | | `store` | `Store` | 节点存储 |
@ -59,14 +59,14 @@ node.setData({
### addEventToQueue ### addEventToQueue
- **参数:** - **参数:**
- `{EventConfig} event` 事件配置 - `{EventCache} event` 待处理事件项;类型为 `{ method: string, fromCpt: any, args: any[] }`
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
将事件添加到事件队列,等待绑定到组件实例。 将事件添加到节点内部的事件队列,等待组件实例 `mounted` 后再依次调用对应的方法(`instance[event.method](event.fromCpt, ...event.args)`
### setInstance ### setInstance
@ -87,18 +87,37 @@ node.setData({
node.setInstance(componentInstance); node.setInstance(componentInstance);
``` ```
### runHookCode ### registerMethod
::: warning @deprecated
该方法已废弃,请使用 `setInstance` 替代。
:::
- **参数:** - **参数:**
- `{'created' | 'mounted'} hook` 钩子名称 - `{Methods} methods` 方法集合,形如 `{ [name: string]: (...args: any[]) => any }`
- `{object} params` 参数
- **返回:** - **返回:**
- `{Promise<any>}` - `{void}`
- **详情:** - **详情:**
执行节点的钩子代码。 将给定方法挂载到 `instance` 上。如果当前 `instance` 不存在,会先创建一个空对象再合并方法。
### runHookCode
- **参数:**
- `{string} hook` 钩子名称(如 `'created'``'mounted'``'destroy'` 等,由节点 schema 决定)
- `{object} params` 参数(可选)
- **返回:**
- `{Promise<void>}`
- **详情:**
执行节点的钩子代码。内部会根据节点 schema 中 `hook` 字段的实际形态进行处理:
- 兼容旧格式:当 `data[hook]` 直接是函数时,作为函数调用;
- 新格式:当 `data[hook]``{ hookType, hookData[] }``hookType === HookType.CODE` 时,按顺序遍历 `hookData`,根据 `codeType` 调用 `app.runCode``app.runDataSourceMethod`
- **示例:** - **示例:**

View File

@ -25,24 +25,31 @@ new Page(options: PageOptions)
### initNode ### initNode
- **参数:** - **参数:**
- `{MNode} config` 节点配置 - `{MComponent | MContainer} config` 节点配置
- `{Node} parent` 父节点(可选) - `{Node} parent` 父节点
- **返回:** - **返回:**
- `{Node}` - `{void}`
- **详情:** - **详情:**
初始化节点,根据配置创建节点实例并添加到页面。会递归初始化子节点。 初始化节点,根据配置创建节点实例并通过 `setNode` 添加到页面:
- 当节点类型属于 `app.iteratorContainerType` 时,会创建 `IteratorContainer` 并直接返回,**不会**继续递归 `config.items`(迭代容器内的子节点由 `IteratorContainer` 自身在每次迭代时按需初始化)。
- 当属于 `app.pageFragmentContainerType` 且配置了 `pageFragmentId` 时,会在 `app.pageFragments` 中创建对应的页面片段实例。
- 其他类型会创建普通节点后递归初始化 `config.items` 子节点。
- **示例:** - **示例:**
```typescript ```typescript
const node = page.initNode({ page.initNode(
{
id: 'button_1', id: 'button_1',
type: 'button', type: 'button',
style: { width: 100 } style: { width: 100 }
}); },
page,
);
``` ```
### getNode ### getNode

View File

@ -12,7 +12,7 @@
- **详情:** - **详情:**
将 CSS 样式字符串转换为对象格式。 将 CSS 样式字符串转换为对象格式。若入参不是字符串,则原样返回。
- **示例:** - **示例:**
@ -47,20 +47,20 @@ console.log(bg); // 'url(https://example.com/image.png)'
## getTransform ## getTransform
- **参数:** - **参数:**
- `{object} value` transform 配置 - `{Record<string, string> | string} value` transform 配置(对象或 CSS 字符串)
- `{JsEngine} jsEngine` JS 引擎类型 - `{JsEngine} jsEngine` JS 引擎类型
- **返回:** - **返回:**
- `{string}` CSS transform 字符串 - `{string | Record<string, string>[]}` CSS transform 字符串;当 `jsEngine === 'hippy'` 时返回数组格式
- **详情:** - **详情:**
根据配置生成 CSS transform 字符串,会根据 JS 引擎类型进行适配 根据配置生成 CSS transform。当 `jsEngine === 'hippy'` 时,会将 `"rotate(90deg) scale(1.5)"` 这样的字符串解析成 `[{ rotate: '90deg' }, { scale: '1.5' }]` 形式以适配 Hippy其它情况下返回标准 CSS transform 字符串
## transformStyle ## transformStyle
- **参数:** - **参数:**
- `{object} style` 样式对象 - `{Record<string, any> | string} style` 样式对象或 CSS 字符串
- `{JsEngine} jsEngine` JS 引擎类型 - `{JsEngine} jsEngine` JS 引擎类型
- **返回:** - **返回:**
@ -68,7 +68,7 @@ console.log(bg); // 'url(https://example.com/image.png)'
- **详情:** - **详情:**
转换样式对象,将数值转换为 rem 单位(移动端适配)。 转换样式对象,将数值转换为 rem 单位(移动端适配)。`style` 为字符串时,会先用 `style2Obj` 解析为对象再处理。
- **示例:** - **示例:**

View File

@ -88,11 +88,35 @@ ds.setData('newValue', 'user.name');
ds.setValue('user.age', 25); ds.setValue('user.age', 25);
``` ```
### setFields
- **参数:**
- `{DataSchema[]} fields` 字段配置
- **返回:**
- `{void}`
- **详情:**
设置数据源的字段配置 `fields`。一般在初始化或 schema 更新后调用。
### setMethods
- **参数:**
- `{CodeBlockContent[]} methods` 自定义方法配置
- **返回:**
- `{void}`
- **详情:**
设置数据源的自定义方法配置 `methods`
### onDataChange ### onDataChange
- **参数:** - **参数:**
- `{string} path` 数据路径 - `{string} path` 数据路径
- `{Function} callback` 回调函数 - `{(payload: any) => void} callback` 回调函数
- **返回:** - **返回:**
- `{void}` - `{void}`
@ -101,11 +125,19 @@ ds.setValue('user.age', 25);
监听指定路径的数据变化。 监听指定路径的数据变化。
::: warning callback 入参取决于 `ObservedData` 实现
- `SimpleObservedData`(默认):路径监听触发时,回调收到的是 `{ updateData, path }` 形式的 `ChangeEvent`**不是**纯粹的 newVal。仅在 `options.immediate` 分支会以「当前路径值」回调一次。
- `DeepObservedData`(基于 `deep-state-observer`):回调入参贴近「值」的语义。
如需统一拿到「最新值」,可在回调里用 `ds.getData(path)` 主动读取。
:::
- **示例:** - **示例:**
```typescript ```typescript
ds.onDataChange('user.name', (newVal) => { ds.onDataChange('user.name', (payload) => {
console.log('用户名变更:', newVal); // SimpleObservedData 下 payload 形如 { updateData, path }
console.log('user.name 变更,最新值:', ds.getData('user.name'));
}); });
``` ```
@ -113,7 +145,7 @@ ds.onDataChange('user.name', (newVal) => {
- **参数:** - **参数:**
- `{string} path` 数据路径 - `{string} path` 数据路径
- `{Function} callback` 回调函数 - `{(payload: any) => void} callback` 回调函数(与 `onDataChange` 相同的引用)
- **返回:** - **返回:**
- `{void}` - `{void}`
@ -153,15 +185,15 @@ ds.onDataChange('user.name', (newVal) => {
DataSource 继承自 EventEmitter支持以下事件 DataSource 继承自 EventEmitter支持以下事件
| 事件名 | 说明 | | 事件名 | 说明 | 回调参数 |
|--------|------| |--------|------|----------|
| `change` | 数据变化时触发 | | `change` | 数据变化时触发 | `(changeEvent: ChangeEvent)``ChangeEvent` 形如 `{ updateData, path? }` |
### 示例 ### 示例
```typescript ```typescript
ds.on('change', () => { ds.on('change', (changeEvent) => {
console.log('数据已变化', ds.data); console.log('数据已变化', changeEvent.updateData, changeEvent.path);
}); });
``` ```

View File

@ -91,30 +91,22 @@ DataSourceManager.register('custom', CustomDataSource);
### init ### init
- **参数:** - **参数:**
- `{DataSourceSchema[]} ds` 数据源配置数组 - `{DataSource} ds` 单个数据源实例(必填)
- **返回:** - **返回:**
- `{Promise<void>}` - `{Promise<void>}`
- **详情:** - **详情:**
初始化数据源,会创建所有配置的数据源实例并初始化 初始化单个数据源。会按 `methods``timing === 'beforeInit'` 的方法依次执行,再调用 `ds.init()`,最后执行 `timing === 'afterInit'` 的方法。当 `ds.isInit``true`,或当前 `app.jsEngine` 命中 `ds.schema.disabledInitInJsEngine` 时直接跳过
- **示例:** - **示例:**
```typescript ```typescript
await dataSourceManager.init([ const ds = dataSourceManager.get('ds_1');
{ if (ds) {
id: 'ds_1', await dataSourceManager.init(ds);
type: 'base', }
fields: [{ name: 'count', defaultValue: 0 }]
},
{
id: 'http_1',
type: 'http',
options: { url: '/api/data' }
}
]);
``` ```
### get ### get
@ -138,14 +130,14 @@ const ds = dataSourceManager.get('ds_1');
### addDataSource ### addDataSource
- **参数:** - **参数:**
- `{DataSourceSchema} config` 数据源配置 - `{DataSourceSchema} config` 数据源配置(可选)
- **返回:** - **返回:**
- `{DataSource}` - `{DataSource | undefined}`
- **详情:** - **详情:**
添加新的数据源。 添加新的数据源。当对应类型尚未注册(即 `dataSourceClassMap` 中无该类型)时,会将配置缓存到 `waitInitSchemaList`,并返回 `undefined`,待 `register` 时再补建实例。
- **示例:** - **示例:**
@ -172,15 +164,15 @@ const ds = dataSourceManager.addDataSource({
### setData ### setData
- **参数:** - **参数:**
- `{DataSourceSchema} ds` 数据源配置 - `{DataSource} ds` 数据源实例
- `{ChangeEvent} changeEvent` 变化事件(可选) - `{ChangeEvent} changeEvent` 变化事件,形如 `{ updateData, path? }`
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
设置数据源数据 `ds.data` 同步到 `this.data[ds.id]`,并以 `(ds.id, changeEvent)` 触发 `change` 事件
### updateSchema ### updateSchema
@ -188,11 +180,11 @@ const ds = dataSourceManager.addDataSource({
- `{DataSourceSchema[]} schemas` 数据源配置数组 - `{DataSourceSchema[]} schemas` 数据源配置数组
- **返回:** - **返回:**
- `{Promise<void>}` - `{void}`
- **详情:** - **详情:**
更新数据源 DSL 配置,会自动处理新增、更新和删除 同步更新数据源 DSL 配置:先按 `id` 移除已有数据源,再以 `cloneDeep` 重新 `addDataSource`,并对新建实例触发 `init`(异步执行,不会被该方法 `await`)。一般在编辑器中修改配置后调用
### compiledNode ### compiledNode
@ -222,11 +214,11 @@ const compiledNode = dataSourceManager.compiledNode({
### compliedConds ### compliedConds
- **参数:** - **参数:**
- `{MNode} node` 节点配置 - `{ { [NODE_CONDS_KEY]?: DisplayCond[]; [NODE_CONDS_RESULT_KEY]?: boolean; [NODE_DISABLE_DATA_SOURCE_KEY]?: boolean } } node` 带条件字段的结构(不要求是完整的 MNode
- `{object} data` 数据上下文(可选 - `{DataSourceManagerData} data` 数据上下文(可选,默认使用 `this.data`
- **返回:** - **返回:**
- `{boolean}` - `{boolean}` 节点是否应该显示
- **详情:** - **详情:**
@ -241,9 +233,9 @@ const shouldShow = dataSourceManager.compliedConds(node);
### compliedIteratorItemConds ### compliedIteratorItemConds
- **参数:** - **参数:**
- `{object} itemData` 迭代项数据 - `{any} itemData` 迭代项数据
- `{MNode} node` 节点配置 - `{ { [NODE_CONDS_KEY]?: DisplayCond[] } } node` 带条件字段的结构
- `{string} field` 条件字段名 - `{string[]} dataSourceField` 迭代数据在数据源中的字段路径,格式如 `['dsId', 'key1', 'key2']`(可选,默认 `[]`
- **返回:** - **返回:**
- `{boolean}` - `{boolean}`
@ -255,9 +247,9 @@ const shouldShow = dataSourceManager.compliedConds(node);
### compliedIteratorItems ### compliedIteratorItems
- **参数:** - **参数:**
- `{object} itemData` 迭代项数据 - `{any} itemData` 迭代项数据
- `{MNode[]} nodes` 节点配置数组 - `{MNode[]} nodes` 节点配置数组
- `{string} field` 字段名 - `{string[]} dataSourceField` 迭代数据在数据源中的字段路径(可选,默认 `[]`
- **返回:** - **返回:**
- `{MNode[]}` - `{MNode[]}`
@ -266,19 +258,33 @@ const shouldShow = dataSourceManager.compliedConds(node);
编译迭代器项的节点配置。 编译迭代器项的节点配置。
### isAllDataSourceRegistered
- **返回:**
- `{boolean}`
- **详情:**
判断 DSL 中声明的所有数据源是否都已注册并实例化(即 `dataSourceMap.size === dsl.dataSources.length`,或 DSL 未声明数据源)。
::: tip `registered-all` 触发时机
`registered-all` 事件**仅**在 `addDataSource` 末尾、`isAllDataSourceRegistered()` 为真时触发。当 `dsl.dataSources` 为空数组时,构造函数不会进入任何一次 `addDataSource` 调用,因此**不会**触发该事件,但仍可能执行 `callDsInit()`
:::
### onDataChange ### onDataChange
- **参数:** - **参数:**
- `{string} id` 数据源 ID - `{string} id` 数据源 ID
- `{string} path` 数据路径 - `{string} path` 数据路径
- `{Function} callback` 回调函数 - `{(payload: any) => void} callback` 回调函数(具体入参取决于 `ObservedData` 实现,详见 [DataSource.onDataChange](./dataSource.md#ondatachange)
- `{ { immediate?: boolean } } options` 选项(可选)
- **返回:** - **返回:**
- `{void}` - `{void}`
- **详情:** - **详情:**
监听数据源数据变化。 监听数据源数据变化。`options.immediate``true` 时,订阅后立即用当前值触发一次回调(具体语义取决于 `ObservedData` 的实现)。
- **示例:** - **示例:**
@ -293,7 +299,7 @@ dataSourceManager.onDataChange('ds_1', 'user.name', (newVal) => {
- **参数:** - **参数:**
- `{string} id` 数据源 ID - `{string} id` 数据源 ID
- `{string} path` 数据路径 - `{string} path` 数据路径
- `{Function} callback` 回调函数 - `{(newVal: any) => void} callback` 回调函数
- **返回:** - **返回:**
- `{void}` - `{void}`
@ -317,19 +323,19 @@ DataSourceManager 继承自 EventEmitter支持以下事件
| 事件名 | 说明 | 回调参数 | | 事件名 | 说明 | 回调参数 |
|--------|------|----------| |--------|------|----------|
| `change` | 数据源数据变化 | `(dsId, path, newVal)` | | `change` | 单个数据源数据变化 | `(dsId: string, changeEvent: ChangeEvent)` |
| `init` | 所有数据源初始化完成 | 无 | | `init` | 所有数据源初始化完成;现代分支携带 `(data, errors)`,旧 Promise.all 分支为 `(this.data)` | `(data, errors?)` |
| `registered-all` | 所有数据源注册完成 | 无 | | `registered-all` | 所有数据源注册完成 | 无 |
| `update-data` | 更新节点数据 | `(node, sourceId)` | | `update-data` | `createDataSourceManager` 在数据变化后发出,用于通知节点重新渲染 | `(newNodes: MNode[], sourceId: string, changeEvent: ChangeEvent, pageId: Id)` |
### 事件监听示例 ### 事件监听示例
```typescript ```typescript
dataSourceManager.on('change', (dsId, path, newVal) => { dataSourceManager.on('change', (dsId, changeEvent) => {
console.log(`数据源 ${dsId} 的 ${path} 变更为:`, newVal); console.log(`数据源 ${dsId} 变更:`, changeEvent);
}); });
dataSourceManager.on('init', () => { dataSourceManager.on('init', (data, errors) => {
console.log('所有数据源初始化完成'); console.log('所有数据源初始化完成', data, errors);
}); });
``` ```

Some files were not shown because too many files have changed in this diff Show More