amis 可视化编辑器, 在线体验:https://aisuda.github.io/amis-editor-demo
要使用编辑器必须熟悉 React,如果不了解建议使用速搭。
npm i
安装依赖npm run dev
等编译完成后本地打开页面看效果。
- 6.0.0(2023-12-29)
- 5.6.2(2023-10-31)
- 5.6.1(2023.9.28) history模式
- 5.6.1(2023.9.28)
- 5.4.1(2023.6.9)
- 4.1.0-beta.28(2022.5.27)
- 4.0.2-beta.10(2022-02-23)
- 3.3.5(2021-08-12)
npm i amis-editor
使用 方法
import {Editor} from 'amis-editor';
render() {
return (
<Editor
{...props}
/>
)
}
属性说明:
value: any
值,amis 的 json 配置。onChange: (value: any) => void
。 当编辑器修改的时候会触发。preview?: boolean
是否为预览状态。autoFocus?: boolean
是否自动聚焦第一个可编辑的组件。plugins
插件类集合
如何扩充 amis 渲染器,请前往如何注册自定义类型,这里主要介绍如何把自定义的组件加入到编辑器里面来。
示例:
- ./renderer/MyRenderer.tsx
- ./editor/MyRenderer.tsx
首先,注册自定义组件的时候需要设置一个 name
属性,这个属性值应该是唯一的。后续注册编辑器是靠这个关联。
如本仓库中示例,name 值为 my-renderer
。
@Renderer({
test: /\bmy-renderer$/,
name: 'my-renderer'
})
export default class MyRenderer extends React.Component<MyRendererProps> {
static defaultProps = {
target: 'world'
};
render() {
const {target} = this.props;
return <p>Hello {target}!</p>;
}
}
然后开始注册编辑器。
import {RendererEditor, BasicEditor} from 'amis-editor';
@RendererEditor('my-renderer', {
name: '自定义渲染器',
description: '这只是个示例',
// docLink: '/docs/renderers/Nav',
type: 'my-renderer', // 这个在 scaffold 没设置的时候有用。
previewSchema: {
// 用来生成预览图的
type: 'my-renderer',
target: 'demo'
},
scaffold: {
// 拖入组件里面时的初始数据
type: 'my-renderer',
target: '233'
}
})
export default class MyRendererEditor extends BasicEditor {
tipName = '自定义组件';
settingsSchema = {
title: '自定义组件配置',
body: [
{
type: 'tabs',
tabsMode: 'line',
className: 'm-t-n-xs',
contentClassName: 'no-border p-l-none p-r-none',
tabs: [
{
title: '常规',
controls: [
{
name: 'target',
label: 'Target',
type: 'text'
}
]
},
{
title: '外观',
controls: []
}
]
}
]
};
}
然后直接看效果吧 https://github.com/fex-team/amis-editor 这里面插入的时候选择输入 my-renderer 然后就可以插入自定义的组件了。
amis-editor 重构了一版,之前定义注册自定义组件的方式也能用,但是已经标记了 deprecated
,新的添加自定义编辑器的方式有两种。
- registerEditorPlugin 注册全局插件。
- 不注册,但是调用
<Editor>
的时候时候通过plugins
属性传入。
效果都一样,重点还是怎么写个 Plugin,示例:
import {BasePlugin} from 'amis-editor';
export class MyRendererPlugin extends BasePlugin {
rendererName = 'my-renderer';
// 暂时只支持这个,配置后会开启代码编辑器
$schema = '/schemas/UnkownSchema.json';
// 用来配置名称和描述
name = '自定义渲染器';
description = '这只是个示例';
// tag,决定会在哪个 tab 下面显示的
tags = ['自定义', '表单项'];
// 图标
icon = 'fa fa-user';
// 用来生成预览图的
previewSchema = {
type: 'my-renderer',
target: 'demo'
};
// 拖入组件里面时的初始数据
scaffold = {
type: 'my-renderer',
target: '233'
};
// 右侧面板相关
panelTitle = '自定义组件';
panelControls = [
{
type: 'tabs',
tabsMode: 'line',
className: 'm-t-n-xs',
contentClassName: 'no-border p-l-none p-r-none',
tabs: [
{
title: '常规',
controls: [
{
name: 'target',
label: 'Target',
type: 'text'
}
]
},
{
title: '外观',
controls: []
}
]
}
];
}
定义好 plugin 后,可以有两种方式启用。
// 方式 1,注册默认插件,所有编辑器实例都会自动实例话。
import {registerEditorPlugin} from 'amis-editor';
registerEditorPlugin(MyRendererPlugin);
// 方式2,只让某些编辑器启用
() => <Editor plugins={[MyRendererPlugin]} />;
前面的示例只做了简单的说明,可用属性还有, 具体还是先看 npm 包里面的 .d.ts 文件吧,后面再补充更详细的文档。
export interface PluginEventListener {
onActive?: (event: PluginEvent<ActiveEventContext>) => void;
/**
* 事件,当有配置项插入前调用。通过 event.preventDefault() 可以干预。
*/
beforeInsert?: (event: PluginEvent<InsertEventContext>) => false | void;
afterInsert?: (event: PluginEvent<InsertEventContext>) => void;
/**
* 面板里面编辑修改的事件。
*/
beforeUpdate?: (event: PluginEvent<ChangeEventContext>) => false | void;
afterUpdate?: (event: PluginEvent<ChangeEventContext>) => void;
/**
* 更新渲染器,或者右键粘贴配置。
*/
beforeReplace?: (event: PluginEvent<ReplaceEventContext>) => false | void;
afterReplace?: (event: PluginEvent<ReplaceEventContext>) => void;
/**
* 移动节点的时候触发,包括上移,下移
*/
beforeMove?: (event: PluginEvent<MoveEventContext>) => false | void;
aftterMove?: (event: PluginEvent<MoveEventContext>) => void;
/**
* 删除的时候触发
*/
beforeDelete?: (event: PluginEvent<BaseEventContext>) => false | void;
afterDelete?: (event: PluginEvent<BaseEventContext>) => void;
beforeResolveEditorInfo?: (event: PluginEvent<RendererInfoResolveEventContext>) => false | void;
afterResolveEditorInfo?: (event: PluginEvent<RendererInfoResolveEventContext>) => void;
beforeResolveJsonSchema?: (event: PluginEvent<RendererJSONSchemaResolveEventContext>) => false | void;
afterResolveJsonSchema?: (event: PluginEvent<RendererJSONSchemaResolveEventContext>) => void;
onDndAccept?: (event: PluginEvent<DragEventContext>) => false | void;
onBuildPanels?: (event: PluginEvent<BuildPanelEventContext>) => void;
onBuildContextMenus?: (event: PluginEvent<ContextMenuEventContext>) => void;
onPreventClick?: (event: PluginEvent<PreventClickEventContext>) => false | void;
}
/**
* 插件的 interface 定义
*/
export interface PluginInterface extends Partial<BasicRendererInfo>, Partial<BasicSubRenderInfo>, PluginEventListener {
readonly manager: EditorManager;
order?: number;
/**
* 渲染器的名字,关联后不用自己实现 getRendererInfo 了。
*/
rendererName?: string;
/**
* 默认的配置面板信息
*/
panelIcon?: string;
panelTitle?: string;
panelControls?: Array<any>;
panelDefinitions?: any;
panelApi?: any;
panelSubmitOnChange?: boolean;
panelControlsCreator?: (context: BaseEventContext) => Array<any>;
/**
* 返回渲染器信息。不是每个插件都需要。
*/
getRendererInfo?: (context: RendererInfoResolveEventContext) => BasicRendererInfo | void;
/**
* 生成节点的 JSON Schema 的 uri 地址。
*/
buildJSONSchema?: (context: RendererJSONSchemaResolveEventContext) => void | string;
/**
* 构建右上角功能按钮集合
*/
buildEditorToolbar?: (context: BaseEventContext, toolbars: Array<BasicToolbarItem>) => void;
/**
* 构建右键菜单项
*/
buildEditorContextMenu?: (context: ContextMenuEventContext, menus: Array<ContextMenuItem>) => void;
/**
* 构建编辑器面板。
*/
buildEditorPanel?: (context: BaseEventContext, panels: Array<BasicPanelItem>) => void;
/**
* 构建子渲染器信息集合。
*/
buildSubRenderers?: (
context: RendererEventContext,
subRenderers: Array<SubRendererInfo>,
renderers: Array<RendererConfig>
) => BasicSubRenderInfo | Array<BasicSubRenderInfo> | void;
}