1
0
mirror of synced 2026-05-21 01:36:40 +08:00

docs: 完善 editor/form/runtime/stage 等 API 文档参数与说明

补全方法的参数类型、返回值类型与详情说明,规范字段编辑器/字段配置/运行时 API 等文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
roymondchen
2026-05-07 17:33:58 +08:00
parent a520626ef6
commit 3eb8cc0614
85 changed files with 2061 additions and 1462 deletions

View File

@@ -10,7 +10,7 @@
下面将主要介绍代码块的实现原理包含dsl结构定义以及代码块挂载执行时机等
## 协议描述
我们将在线编写的代码内容保存在[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
[{
@@ -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下看到当前活动的代码块列表
<img src="/code-block.png" alt="代码块列表">
## 组件绑定
代码块的初衷是为了实现对组件逻辑的在线干预代码执行的时机平台提供了组件created, mounted两个钩子因此我们需要将创建的代码与组件进行关联。
<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
@@ -70,9 +70,9 @@
## 代码内容注入与执行
在实现代码块创建和绑定操作之后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)。

View File

@@ -25,7 +25,7 @@ tmagic-editor的联动指这两种情况
}]`">
</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)。
@@ -95,28 +95,31 @@ const onClick = () => {
};
// 此处实现事件动作
const toast = () => {
toast('测试 vue3')
// 注意:示例中的 ElMessage 仅作演示,业务可替换为自己的弹窗工具
import { ElMessage } from 'element-plus';
const showToast = () => {
ElMessage('测试 vue3');
};
// 实际触发时是调用node上的方法所以需要将方法暴露到node上
// 实际触发时是调用node上的方法所以需要将方法暴露到node上
registerNodeHooks(node, {
toast,
toast: showToast,
});
defineExpose({
toast,
toast: showToast,
});
</script>
```
#### react 版本实现
在 react 的实现中由于tmagic-editor提供的 @tmagic/ui-react 版本是用 hook 实现的。所以组件开发我们也相应的需要使用 hook 方式。
在 react 的实现中由于tmagic-editor提供的 @tmagic/react-runtime-help 版本是用 hook 实现的。所以组件开发我们也相应的需要使用 hook 方式。
```jsx
import React from 'react';
import { useApp } from '@tmagic/ui-react';
import { useApp } from '@tmagic/react-runtime-help';
function Test({ config }) {
// react 和 vue 实现不同,我们通过 useApp 这个 hook 来提供 app 等核心内容

View File

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

View File

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

View File

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

View File

@@ -152,7 +152,7 @@ react 版本组件代码示例
import React, { useContext } from 'react';
import Core from '@tmagic/core';
import { AppContent } from '@tmagic/ui-react';
import { AppContent } from '@tmagic/react-runtime-help';
function Test({ config }: { config: any }) {
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`的数据格式如下:
@@ -16,7 +16,7 @@
{ left: [], center: [], right: [] }
```
数组的内容可以有三种形式:`内部定义好的字符串``其他字符串``MenuButton 或者 MenuComponent 对象`
数组的内容可以有三种形式:`内部定义好的字符串``其他字符串``MenuButton 或者 MenuComponent 对象`
#### 1. 内部定义好的字符串:
```ts
@@ -38,7 +38,7 @@ MenuButton 的[定义](https://github.com/Tencent/tmagic-editor/blob/239b5d3efea
```js
{
type: 'buuton',
type: 'button',
text: '返回',
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分页

View File

@@ -13,7 +13,7 @@ $ pnpm create tmagic
```
:::
按照提示操作可以创建`6`项目:
按照提示操作可以创建`6`项目:
* runtime:运行时DSL渲染
* admin-client:管理端(编辑器)
@@ -75,7 +75,6 @@ const app = createApp(App);
app.use(ElementPlus, {
locale: zhCn,
});
app.use(router);
app.use(editorPlugin, MagicElementPlusAdapter);
app.mount('#app');
```
@@ -166,7 +165,7 @@ app.mount('#app');
关于 [@tmagic/editor](https://github.com/Tencent/tmagic-editor/tree/master/packages/editor) 组件,更多的属性配置详情请参考[编辑器 API](../api/editor/props.md)。
其中,**有四个需要注意的属性配置项**`runtimeUrl` `values` `configs` `componentGroupList`。这是能让我们的编辑器正常运行的关键。
其中,**有四个需要注意的属性配置项**`runtimeUrl` `propsValues` `propsConfigs` `componentGroupList`。这是能让我们的编辑器正常运行的关键。
:::tip
如果出现```Preprocessor dependency "sass" not found. Did you install it?```那么需要install sass

View File

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

View File

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

View File

@@ -65,7 +65,7 @@ import { defineConfig } from '@tmagic/cli';
export default defineConfig({
/** 组件目录或者npm包名 */
packages: [path.join(__dirname, '../../packages/ui')],
packages: [path.join(__dirname, '../../vue-components')],
/** 组件文件后缀名例如vue文件为.vuetsx文件为.tsx普通js文件则为.js */
componentFileAffix: '.vue',
/** npm 配置用于当packages配置有npm包名时可以自动安装npm包 */
@@ -113,7 +113,7 @@ tmagic-editor的页面发布目前使用的是静态资源发布。而所有
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<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>
<link rel="modulepreload" href="assets/App.10f9c9e1.js">
<link rel="modulepreload" href="assets/vendor.1dc07625.js">
@@ -139,7 +139,7 @@ tmagic-editor的页面发布目前使用的是静态资源发布。而所有
<title>Publish Page</title>
<!-- 这里插入了项目相关的 DSL.js -->
<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>
<link rel="modulepreload" href="assets/App.10f9c9e1.js">
<link rel="modulepreload" href="assets/vendor.1dc07625.js">

View File

@@ -25,5 +25,5 @@ page用于生产环境
playground用于编辑器中
:::tip
想要了解DSL的解析以及runtime与编辑器的通信可以前往[教程](/guide/tutorial/index.md)
想要了解DSL的解析以及runtime与编辑器的通信可以前往[教程](/guide/tutorial/)
:::

View File

@@ -162,12 +162,14 @@ const value = ref({
加上初始值后点击新增页面就可以渲染出一个画布了但是点击添加HelloWorld组件依然没有反应
这是因为这时的编辑器并能理解HelloWorld是什么需要在[render](../../api/editor/props.html#render)函数中处理
这是因为这时的编辑器并能理解HelloWorld是什么需要在[render](../../api/editor/props.html#render)函数中处理
## 渲染
api详情[render](../../api/editor/props.md#render)
> 以下片段省略了 `page` 的获取与完整定义仅展示渲染思路完整示例见下文「最终完整的render函数实现」。
```ts
const render = () => {
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
并不是render函数不好但是从设计上render函数还是让渲染逻辑落到了编辑器中@tmagic/editor的设计是希望做到渲染跟编辑器解耦
并不是render函数不好但是从设计上render函数还是让渲染逻辑落到了编辑器中@tmagic/editor的设计是希望做到渲染跟编辑器解耦
:::
[源码](https://github.com/vft-magic/tmagic-tutorial)

View File

@@ -1,6 +1,6 @@
# 3.[DSL](../conception.md#dsl) 解析渲染
tmagic 提供了 vue/react 两个版本的解析渲染组件,可以直接使用
tmagic 提供了 vue/react 两个版本的解析渲染组件,可以直接使用
[@tmagic/ui](https://www.npmjs.com/package/@tmagic/ui)
@@ -12,7 +12,7 @@ tmagic 提供了 vue/react 两个个版本的解析渲染组件,可以直接
### 创建项目
将[上一教程](./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 +69,7 @@ app.component('hello-world', HelloWorld);
```vue
<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>
<script lang=ts setup>
@@ -91,7 +91,7 @@ const id = computed(() => props.config.id);
</script>
```
接下来就需要解析节点的样式在tmagic/editor中默认会将样式配置保存到节点的style属性中如果自行定义到了其他属性实际为准
接下来就需要解析节点的样式,在@tmagic/editor中默认会将样式配置保存到节点的style属性中,如果自行定义到了其他属性,则实际为准
解析style需要注意几个地方
@@ -99,13 +99,13 @@ const id = computed(() => props.config.id);
css中的数值有些是需要单位的例如px有些是不需要的例如opacity
在tmagic/editor中默认都是不带单位的所以需要将需要单位的地方补齐单位
@tmagic/editor中,默认都是不带单位的,所以需要将需要单位的地方补齐单位
这里做补齐px处理如果需要做屏幕大小适应 可以使用rem或者vw这个可以根据自身需求处理。
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

View File

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