docs/docs/cn/plugin-development/client/examples/custom-block.md
在 NocoBase 中,区块是页面上的内容区域。这个示例展示怎么用 BlockModel 做一个最简单的自定义区块——支持在界面上编辑 HTML 内容,用户可以通过配置面板修改区块显示的内容。
这是第一个涉及 FlowEngine 的示例,会用到 BlockModel、renderComponent、registerFlow 和 uiSchema。
:::tip 前置阅读
建议先了解以下内容,开发时会更顺畅:
load() 生命周期tExpr() 延迟翻译的用法:::
我们要做的是一个「Simple block」区块:
完整源码见 @nocobase-example/plugin-simple-block。如果你想直接在本地跑起来看效果:
yarn pm enable @nocobase-example/plugin-simple-block
下面从零开始,一步步搭建这个插件。
在仓库根目录执行:
yarn pm create @my-project/plugin-simple-block
这会在 packages/plugins/@my-project/plugin-simple-block 下生成基础文件结构。详细说明见 编写第一个插件。
新建 src/client-v2/models/SimpleBlockModel.tsx。这是整个插件的核心——定义区块怎么渲染、怎么配置。
// src/client-v2/models/SimpleBlockModel.tsx
import React from 'react';
import { BlockModel } from '@nocobase/client-v2';
import { tExpr } from '../locale';
export class SimpleBlockModel extends BlockModel {
renderComponent() {
return <div dangerouslySetInnerHTML={{ __html: this.props.html }} />;
}
}
// 设置区块在「添加区块」菜单里的显示名
SimpleBlockModel.define({
label: tExpr('Simple block'),
});
// 注册配置面板,让用户可以编辑 HTML 内容
SimpleBlockModel.registerFlow({
key: 'flow1',
title: tExpr('Simple Block Flow'),
on: 'beforeRender', // 渲染前执行
steps: {
editHtml: {
title: tExpr('Edit HTML Content'),
// uiSchema 定义配置面板的表单 UI
uiSchema: {
html: {
type: 'string',
title: tExpr('HTML Content'),
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
},
},
// 配置面板的默认值
defaultParams: {
html: `<h3>This is a simple block</h3>
<p>You can edit the HTML content.</p>`,
},
// 把配置面板的值写入 model 的 props
handler(ctx, params) {
ctx.model.props.html = params.html;
},
},
},
});
几个关键点:
renderComponent() — 渲染区块 UI,通过 this.props.html 读取 HTML 内容define() — 设置区块在「添加区块」菜单里的显示名。tExpr() 用于延迟翻译,因为 define() 在模块加载时就执行了,此时 i18n 还没初始化registerFlow() — 添加配置面板。uiSchema 用 JSON Schema 定义表单(语法参考 UI Schema),handler 把用户填写的值写入 ctx.model.props,renderComponent() 就能读到编辑插件的 src/locale/ 下的翻译文件,把 tExpr() 用到的 key 都加上翻译:
// src/locale/zh-CN.json
{
"Simple block": "简单区块",
"Simple Block Flow": "简单区块配置",
"Edit HTML Content": "编辑 HTML 内容",
"HTML Content": "HTML 内容"
}
// src/locale/en-US.json
{
"Simple block": "Simple block",
"Simple Block Flow": "Simple Block Flow",
"Edit HTML Content": "Edit HTML Content",
"HTML Content": "HTML Content"
}
:::warning 注意
初次添加语言文件需要重启应用才能生效。
:::
关于翻译文件的写法和 tExpr() 的更多用法,详见 i18n 国际化。
编辑 src/client-v2/plugin.tsx,用 registerModelLoaders 按需加载模型:
// src/client-v2/plugin.tsx
import { Plugin } from '@nocobase/client-v2';
export class PluginSimpleBlockClient extends Plugin {
async load() {
this.flowEngine.registerModelLoaders({
SimpleBlockModel: {
// 按需加载,首次用到时才加载模块
loader: () => import('./models/SimpleBlockModel'),
},
});
}
}
export default PluginSimpleBlockClient;
registerModelLoaders 使用动态导入,模型代码在首次真正用到时才会加载——这是推荐的注册方式。
yarn pm enable @my-project/plugin-simple-block
启用后,新建一个页面,点击「添加区块」就能看到「Simple block」。添加后,点击区块的配置按钮可以编辑 HTML 内容。
这个示例用到的能力:
| 能力 | 用法 | 文档 |
|---|---|---|
| 区块渲染 | BlockModel + renderComponent() | FlowEngine → 区块扩展 |
| 菜单注册 | define({ label }) | FlowEngine 概述 |
| 配置面板 | registerFlow() + uiSchema | FlowEngine 概述 |
| 模型注册 | registerModelLoaders(按需加载) | Plugin 插件 |
| 延迟翻译 | tExpr() | i18n 国际化 |