docs: 完善组件开发/runtime/表单配置文档
This commit is contained in:
@@ -83,30 +83,29 @@ export default {
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent, inject } from 'vue';
|
||||
import { type ComponentProps, registerNodeHooks, useApp } from '@tmagic/vue-runtime-help';
|
||||
|
||||
const props = defineProps({
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
})
|
||||
const props = defineProps<ComponentProps>()
|
||||
|
||||
const app: Core | undefined = inject('app');
|
||||
|
||||
const node = app?.page?.getNode(props.config.id);
|
||||
const { app, node } = useApp(props);
|
||||
|
||||
const onClick = () => {
|
||||
// app.emit 第一个参数为事件名,其余参数为你要传给接受事件组件的参数
|
||||
app?.emit("yourComponent:finishSomething", node, /*可以传参给接收方*/);
|
||||
app.emit("yourComponent:finishSomething", node, /*可以传参给接收方*/);
|
||||
};
|
||||
|
||||
// 此处实现事件动作
|
||||
const toast = () => {
|
||||
toast('测试 vue3')
|
||||
};
|
||||
|
||||
// 实际触发时是调用node上的方法,所以需要将改方法暴露到node上
|
||||
registerNodeHooks(node, {
|
||||
toast,
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
// 此处实现事件动作
|
||||
// 实际触发时是调用vue实例上的方法,所以需要将改方法暴露到实例上
|
||||
toast: (/*触发组件node*/, /*接收触发事件组件传进来的参数*/) => {
|
||||
toast('测试 vue3')
|
||||
}
|
||||
toast,
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@@ -151,10 +150,3 @@ function Test({ config }) {
|
||||
|
||||
export default Test;
|
||||
```
|
||||
|
||||
按照上述实现触发事件和事件动作,就可以完成组件的联动事件分发响应。
|
||||
|
||||
:::tip
|
||||
组件事件的联动是借助了@tmagic/core,需要在组件实例化的时候将需要暴露的方法提供给@tmagic/core,在上述例子中useApp方法的调用就是完成这个操作,useApp返回的app对象就是@tmagic/core的实例。在vue的实现中useApp是将整个vue实例都提供给了app,所以需要defineExpose来定义vue instance上的方法,react则是将需要暴露的方法作为useApp的参数传入
|
||||
:::
|
||||
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
# 如何开发一个组件
|
||||
tmagic-editor支持业务方进行自定义组件开发。在tmagic-editor中,组件是以 npm 包形式存在的,组件和插件只要按照规范开发,就可以在tmagic-editor的 runtime 中被加入并正确渲染组件。
|
||||
|
||||
## 组件开发
|
||||
以 vue 的组件开发为例。运行项目中的 playground 示例,会自动加载 vue 的 runtime。runtime会加载[@tmagic/ui](https://github.com/Tencent/tmagic-editor/tree/master/packages/ui)
|
||||
|
||||
## 组件注册
|
||||
在 [playground](https://tencent.github.io/tmagic-editor/playground/index.html#/) 中,我们可以尝试点击添加一个组件,在模拟器区域里,就会出现这个组件。其中就涉及到组件注册。
|
||||
|
||||
这一步需要开发者基于tmagic-editor搭建了平台后,实现组件列表的注册、获取机制,tmagic-editor组件注册其实就是保存好组件 `type` 的映射关系。`type` 可以参考[组件介绍](../guide/conception.html#组件)。
|
||||
|
||||
可以参考 vue 版本的 @tmagic/ui 中,[组件渲染](../guide/advanced/page.html#组件渲染)逻辑里,type 会作为组件名进入渲染。所以在 vue 的组件开发中,我们也需要在为 vue 组件声明 name 字段时,和 type 值对应起来,才能正确渲染组件。
|
||||
|
||||
### 组件规范
|
||||
组件的基础形式,需要有四个文件
|
||||
- index 入口文件,引入下面几个文件
|
||||
- formConfig 表单配置描述
|
||||
- initValue 表单初始值
|
||||
- form-config 表单配置描述
|
||||
- init-value 表单初始值
|
||||
- event 定义联动事件,具体可以参考[组件联动](../guide/advanced/coupling.html#组件联动)
|
||||
- component.{vue,jsx} 组件样式、逻辑代码
|
||||
|
||||
@tmagic/ui 中的 button/text 就是基础的组件示例。我们要求声明 index 入口,因为我们希望在后续的配套打包工具实现上,可以有一个统一规范入口。
|
||||
|
||||
### 1. 创建组件
|
||||
在项目中,如 runtime 目录中,创建一个名为 test-component 的组件目录,其中包含上面四个规范文件。
|
||||
|
||||
可以使用`npm create tmagic` 选择 `components:组件库(组件/插件/数据源)` 来快速创建一个组件库。
|
||||
|
||||
然后继续使用`npm create tmagic` 选择 `component:组件` 来快速创建一个组件。
|
||||
|
||||
:::tip
|
||||
|
||||
组件库并不是必须,组件如何管理可以根据具体情况来选择。直接放到 runtime 目录中也是一个不错的选择,如果选择放到runtime中可以在runtime中的package.json添加`"tmagicComponentsPath": "./components"` 来指定组件库的路径。这样在使用`npm create tmagic` 来创建组件时,会自动将组件添加到组件库中。
|
||||
|
||||
:::
|
||||
|
||||
手动创建组件,可以在项目中,如 runtime 目录中,创建一个名为 test-component 的组件目录,其中包含上面四个规范文件。
|
||||
```javascript
|
||||
// index.js
|
||||
// vue
|
||||
@@ -30,14 +29,18 @@ import Test from './Test.vue';
|
||||
// react
|
||||
import Test from './Test.tsx';
|
||||
|
||||
export { default as config } from './formConfig';
|
||||
export { default as value } from './initValue';
|
||||
export { default as config } from './form-config';
|
||||
export { default as value } from './init-value';
|
||||
|
||||
export default Test;
|
||||
```
|
||||
|
||||
:::tip
|
||||
如果在runtime中使用了@tmagic/cli,则必须保持此规范;不使用则可以自由书写。
|
||||
:::
|
||||
|
||||
```javascript
|
||||
// formConfig.js
|
||||
// form-config.js
|
||||
export default [
|
||||
{
|
||||
type: 'select',
|
||||
@@ -61,15 +64,40 @@ export default [
|
||||
];
|
||||
```
|
||||
|
||||
:::tip
|
||||
配置内容必须是一个数组,每个元素是一个对象,包含 type、text、name 等属性,每个对象代表一个表单项。
|
||||
|
||||
type 是表单项的类型
|
||||
|
||||
text 是表单项的文本
|
||||
|
||||
name 是表单项值的key。
|
||||
|
||||
上述实例对应生成的值为
|
||||
```json
|
||||
{
|
||||
"color": "red",
|
||||
"text": "一段文字",
|
||||
}
|
||||
```
|
||||
|
||||
type 在@tmagic/form 和 @tmagic/editor 中默认提供了种,@tmagic/form提供的可以前往[表单配置](/form-config/fields/text.html)查看。
|
||||
:::
|
||||
|
||||
|
||||
```javascript
|
||||
// initValue.js
|
||||
// init-value.js
|
||||
export default {
|
||||
color: 'red',
|
||||
text: '一段文字',
|
||||
};
|
||||
```
|
||||
|
||||
版本的组件代码示例
|
||||
:::tip
|
||||
在编辑器中添加组件时使用,作为初始值。
|
||||
:::
|
||||
|
||||
Vue版本的组件代码示例
|
||||
```vue
|
||||
<!-- Test.vue -->
|
||||
<template>
|
||||
@@ -79,22 +107,24 @@ export default {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'magic-ui-test',
|
||||
});
|
||||
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
defineProps({
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
setup() {},
|
||||
};
|
||||
}):
|
||||
</script>
|
||||
```
|
||||
|
||||
:::tip
|
||||
编辑器中配置的 config 对象,会作为 props 传入组件中。
|
||||
:::
|
||||
|
||||
react 版本组件代码示例
|
||||
```javascript
|
||||
// Test.tsx
|
||||
@@ -118,84 +148,52 @@ export default Test;
|
||||
|
||||
```
|
||||
|
||||
### 2. 使用tmagic-cli
|
||||
在 runtime vue 中,我们已经提供好一份示例。在 tmagic.config.ts 文件中。只需要在 packages 加入你创建的组件的路径(如果是个 npm 包,则将路径替换为包名即可),打包工具就会自动识别到你的组件。
|
||||
## 插件开发
|
||||
插件开发和组件开发形式类似,但是插件开发不需要有组件的规范。
|
||||
|
||||
我们只需要在插件中提供一个入口文件。插件需要提供一个 install 方法。
|
||||
|
||||
### 3. 启动 playground
|
||||
在上面的步骤完成后,在 playground/src/configs/componentGroupList 中。找到组件栏的基础组件列表,在其中加入你的开发组件
|
||||
```javascript
|
||||
{
|
||||
title: '基础组件',
|
||||
items: [
|
||||
// 在Vue的runtime中
|
||||
export default {
|
||||
install(vueApp, { app: tmagicApp }) {}
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
// 在React的runtime中
|
||||
export default {
|
||||
install({ app: tmagicApp }) {}
|
||||
}
|
||||
```
|
||||
|
||||
在插件中开发者可以自由实现需要的业务逻辑。
|
||||
|
||||
## 集成到runtime中
|
||||
|
||||
### 使用@tmagic/cli
|
||||
|
||||
在使用`npm create tmagic` 创建的runtime中,自动集成了@tmagic/cli,将组件集成到此runtime中只需要在`tmagic.config.ts`中的packages字段中添加
|
||||
```javascript
|
||||
import { defineConfig } from '@tmagic/cli';
|
||||
|
||||
export default defineConfig({
|
||||
// other config
|
||||
packages: [
|
||||
{
|
||||
text: '文本',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
text: '按钮',
|
||||
type: 'button',
|
||||
},
|
||||
// 加入这个测试组件
|
||||
{
|
||||
text: '测试',
|
||||
type: 'test',
|
||||
'组件type': '组件目录或者npm包名',
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
然后,在 magic 项目根目录中,运行
|
||||
});
|
||||
|
||||
```
|
||||
npm run playground
|
||||
```
|
||||
|
||||
至此,我们打开 playground 后,就能添加开发的中的组件,并且得到这个开发中的组件**在编辑器中的表现**了。
|
||||
:::tip
|
||||
组件type需要与[componentGroupList](../api/editor/props.html#componentgrouplist)中的type对应。
|
||||
:::
|
||||
|
||||
<img src="https://image.video.qpic.cn/oa_fd3c9c-3_548108267_1636719045199471">
|
||||
|
||||
### 4. 启动 runtime
|
||||
在完成开发中组件在编辑器中的实现后,我们将编辑器中的 DSL 源码📄 打开,复制 DSL。并在 runtime/vue/src/page 下。创建一个 page-config.js 文件。将 DSL 作为配置导出。
|
||||
配置到packages字段中后,执行`npm run tmagic`来创建组件库的入口文件。
|
||||
|
||||
```javascript
|
||||
window.magicDSL = [
|
||||
// DSL
|
||||
]
|
||||
```
|
||||
然后使用`npm run build:libs`命令来构建用于编辑器中的组件配置、组件初始值、组件事件联动的资源文件。
|
||||
|
||||
在 page/main.ts 中,将这份配置读入
|
||||
```javascript
|
||||
import './page-config.js';
|
||||
```
|
||||
|
||||
然后执行在 runtime/ 目录下执行
|
||||
```
|
||||
npm run build:libs
|
||||
npm run dev
|
||||
```
|
||||
|
||||
至此,我们就可以得到这个开发中组件在编辑器中进行了配置并保存后,在真实页面中应该有的样子。
|
||||
|
||||
<img src="https://image.video.qpic.cn/oa_fd3c9c-3_1731965034_1636719708671597?imageView2/q/70" width="50%">
|
||||
|
||||
## 插件开发
|
||||
插件开发和组件开发形式类似,但是插件开发不需要有组件的规范。在以 vue 为基础的 ui 和 runtime 中,插件其实就是一个 vue 插件。
|
||||
|
||||
我们只需要在插件中提供一个入口文件,其中包含 vue 的 install 方法即可。
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
install() {}
|
||||
}
|
||||
```
|
||||
|
||||
在插件中开发者可以自由实现需要的业务逻辑。插件和组件一样,只需要在 units.js 中,加入导出的 units 对象里即可。
|
||||
|
||||
## 业务定制
|
||||
上述的步骤,如
|
||||
1. 组件/插件初始化
|
||||
2. 编辑器中的组件调试
|
||||
3. 真实页面的组件调试
|
||||
4. 编辑器中的 DSL 同步至本地调试页面
|
||||
|
||||
等许多步骤,都可以交由业务方进行定制,开发业务自定义的脚手架工具,或者如示例中一样,使用打包脚本来处理。
|
||||
@@ -195,6 +195,9 @@ npm install sass -D
|
||||
## runtimeUrl
|
||||
|
||||
该配置涉及到 [runtime 概念](runtime.md),tmagic-editor编辑器中心的模拟器画布,是一个 iframe(这里的 `runtimeUrl` 配置的,就是你提供的 iframe 的 url),其中渲染了一个 runtime,用来响应编辑器中的组件增删改等操作。
|
||||
:::tip
|
||||
可以使用`npm create tmagic` 来快速创建一个runtime项目。
|
||||
:::
|
||||
|
||||
## componentGroupList
|
||||
|
||||
|
||||
@@ -1,70 +1,29 @@
|
||||
# RUNTIME
|
||||
本章详细介绍如何深入理解tmagic-editor的打包,以及如何根据需求定制,修改tmagic-editor的页面打包发布方案。页面发布、打包相关的定制化开发,需要使用tmagic-editor的业务方,搭建好基于开源tmagic-editor的管理平台、存储服务等配套设施。
|
||||
|
||||
## runtime 是什么
|
||||
|
||||
runtime是用来解析DSL的执行环境,用于渲染 DSL 呈现页面。
|
||||
|
||||
编辑器生成出来的DSL需要通过 runtime 来渲染。
|
||||
|
||||
## 实现一个 runtime
|
||||
在 [@tmagic/ui](./advanced/tmagic-ui.html) 部分,我们已经说过,runtime 和 UI 是配套实现的。每个版本的 runtime 都需要一个对应的 UI 来作为渲染器,实现渲染 DSL 呈现页面的功能。
|
||||
|
||||
### UI
|
||||
一个 UI 应该至少包含一个渲染器,来实现[页面渲染](./advanced/page.html)。同时可以提供一些基础组件。具体实现可以参考[@tmagic/ui](./advanced/tmagic-ui.html)。
|
||||
:::tip
|
||||
可以使用`npm create tmagic` 来快速创建一个runtime项目。
|
||||
:::
|
||||
|
||||
### page
|
||||
runtime 的 `page` 部分,就是真实项目页面的渲染环境。发布出去的项目页都需要基于该部分来实现渲染功能。而 `page` 的主要逻辑,就是需要加载 UI,同时实现业务方需要的业务逻辑,比如:
|
||||
- 提供页面需要的全局 api
|
||||
- 业务需要的特殊实现逻辑
|
||||
- 加载第三方全局组件/插件等
|
||||
|
||||
具体的 page 实现示例,可以参考
|
||||
- [vue runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue/page)
|
||||
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react/page)
|
||||
|
||||
### playground
|
||||
runtime 的 `playground` 部分,和 `page` 做的事情几乎一致,业务方可以包含上述 `page` 所拥有的全部能力。但是,因为 playground 需要被编辑器加载,作为编辑器中页面模拟器的渲染容器,和编辑器通信,接受编辑器中组件的增删改查。所以,除了保持和 `page` 一样的渲染逻辑之外,`playground` 还要额外实现一套既定通信内容和 api,才能实现和编辑器的通信功能。
|
||||
|
||||
#### onRuntimeReady
|
||||
**在 playground 页面渲染后**,需要调用接口通知编辑器完成加载。该调用需要传入一个参数 API,即挂载了增删改查功能的对象示例,提供给编辑器。
|
||||
```javascript
|
||||
window.magic?.onRuntimeReady(API)
|
||||
创建出来的项目会包含page、playground两个目录。
|
||||
```bash
|
||||
.
|
||||
├── page
|
||||
├── playground
|
||||
```
|
||||
|
||||
#### onPageElUpdate
|
||||
**playground 在每次更新了页面配置后**,调用一次 onPageElUpdate 并传入一个 DOM 节点,该方法作用是传入一个页面渲染组件的根节点,用来告知编辑器的模拟器遮罩如何作出反应。
|
||||
```javascript
|
||||
window.magic.onPageElUpdate(document.querySelector('.magic-ui-page'));
|
||||
```
|
||||
page用于生产环境
|
||||
|
||||
#### 提供 API
|
||||
| API | 说明 | 参数 |
|
||||
|---------- |-------- |---------- |
|
||||
|updateRootConfig| 根节点更新 | `root: MApp` |
|
||||
|updatePageId| 更新当前页面 id | `id: string` |
|
||||
|select| 选中组件 | `id: string`|
|
||||
|add| 增加组件 | { `config` , `root` }: `UpdateData` |
|
||||
|update| 更新组件 | { `config` , `root` }: `UpdateData` |
|
||||
|remove| 删除组件 | { `config` , `root` }: `UpdateData` |
|
||||
|sortNode| 组件在容器间排序 |{ `src` , `dist`, `root` }: `SortEventData` |
|
||||
playground用于编辑器中
|
||||
|
||||
runtime 的实现示例,可以参考tmagic-editor提供的:
|
||||
- [vue runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/vue)
|
||||
- [react runtime](https://github.com/Tencent/tmagic-editor/blob/master/runtime/react)
|
||||
|
||||
### 页面发布
|
||||
如介绍中提到的,tmagic-editor页面发布方案,是对构建产物 `page/index.html` 进行项目信息注入。项目信息就是搭建平台存储的页面配置。发布时,将注入项目信息的 `page/index.html` 发布出去即可。
|
||||
|
||||
## 版本管理
|
||||
基于上一步提到的打包原理,每次构建后,得到的产物都可以进行归档编号,存为版本。涉及到的组件改动和新增修改,体现在各个版本中。
|
||||
|
||||
<img src="https://image.video.qpic.cn/oa_88b7d-32_1233288257_1633783105283986" width="40%" alt="版本选择">
|
||||
|
||||
版本管理具体如何实现,这取决于使用tmagic-editor的业务方。版本管理具有如下优点:
|
||||
1. 对于已经配置好发布的项目,使用固定版本,不会被新版本的特性影响,保证项目线上稳定运行
|
||||
2. 发布的新版本如果出现问题,可以及时回退选择使用旧版本
|
||||
|
||||
## 结合业务定制
|
||||
tmagic-editor的静态资源构建,项目配置保存,页面发布,在tmagic-editor的提供的示例方案中,流程是:
|
||||
1. 触发构建,执行流水线,基于 runtime 执行 build
|
||||
2. 将构建产物归档推送至 cdn,存为一个ui版本
|
||||
3. 项目配保存后,项目发布时,将项目配置发布至 CDN 存储为 DSL.js,同时根据当前项目使用的ui版本,获取到 page/index.html,将 DSL.js 引用方式以 script 标签形式写入。
|
||||
4. 将注入信息的 page/index.html 发布为项目静态资源 act.html
|
||||
5. 线上可加载 act.html 访问项目
|
||||
|
||||
其中各个步骤的定制,可以交由业务方根据tmagic-editor提供的示例进行自定义修改。
|
||||
:::tip
|
||||
想要了解DSL的解析以及runtime与编辑器的通信,可以前往[教程](/guide/tutorial/index.md)
|
||||
:::
|
||||
|
||||
Reference in New Issue
Block a user