事件系统
RuleGo-Editor 提供了一套完整的事件系统,用于组件间通信和扩展功能。事件系统基于 LogicFlow 的 eventCenter 实现,支持监听编辑器内部事件和自定义事件。
两套通信渠道,别混淆:
- LogicFlow eventCenter(本文主要内容):编辑器内部各模块之间通信。因为工具栏、侧边栏等是独立的 Vue 应用实例(
createApp创建,无法用 provide/inject 共享状态),所以用 LogicFlow 的 eventCenter 当事件总线。事件常量EDITOR_EVENTS定义在源码src/components/constants/events.js。- Vue emit(
RuleGoEditor对宿主):如saveOk/saveError/reset/updateLocales/dirty-change/open-chain/request-info/selection-change/sidebar-toggled。宿主集成用这套,见 配置 · 事件。访问路径:
EDITOR_EVENTS是内部常量,未从@rulego/editor公共入口导出。作为库消费时,宿主监听画布元素事件用ruleGoEditorRef.value.lf.on(...)(LogicFlow 原生 API),监听业务结果用 Vue emit;只有二次开发(改源码)场景才直接import { EDITOR_EVENTS } from '../constants/events'。
# 事件常量
编辑器内置了以下事件常量,可通过 EDITOR_EVENTS 对象访问:
# Toolbar 命令事件
| 事件常量 | 事件名 | 说明 | 触发源 |
|---|---|---|---|
| NEW | rulego-editor:new | 新建规则链 | Toolbar |
| OPEN | rulego-editor:open | 打开规则链 | Toolbar |
| IMPORT | rulego-editor:import | 导入规则链 | Toolbar |
| UPDATE | rulego-editor:update | 更新规则链 | Toolbar |
| SAVE | rulego-editor:save | 保存规则链 | Toolbar |
| SETTING | rulego-editor:setting | 打开设置面板 | Toolbar |
| RESET | rulego-editor:reset | 重置规则链 | Toolbar |
| DELETE_SELECTS | rulego-editor:deleteSelects | 删除选中的节点/边 | Toolbar |
| SHOW_EDIT_PANEL | rulego-editor:showEditPanel | 显示编辑面板 | Toolbar |
| FULL_SCREEN | rulego-editor:fullScreen | 切换全屏模式 | Toolbar |
| LOAD_COMPONENTS | rulego-editor:loadComponents | 加载组件列表 | Toolbar |
# 核心通知事件
| 事件常量 | 事件名 | 说明 | 触发源 |
|---|---|---|---|
| SAVE_OK | rulego-editor:saveOk | 保存成功通知 | 核心模块 |
| COMPONENT_OK | rulego-editor:componentOk | 组件加载完成 | 核心模块 |
| SIDEBAR_OK | rulego-editor:sidebarOk | 侧边栏加载完成 | 核心模块 |
| DELETED | rulego-editor:deleted | 删除完成通知 | 核心模块 |
# 调试事件
| 事件常量 | 事件名 | 说明 | 触发源 |
|---|---|---|---|
| TOGGLE_DEBUG_CONSOLE | rulego-editor:toggleDebugConsole | 切换调试控制台显示 | 调试模块 |
| CLEAR_DEBUG_HIGHLIGHT | rulego-editor:clearDebugHighlight | 清除调试高亮 | 调试模块 |
| DEBUG_DATA | rulego-editor:debugData | 接收调试数据 | 调试模块 |
| TOGGLE_RULE_CHAIN_CHAT | rulego-editor:toggleRuleChainChat | 切换规则链聊天面板 | 调试模块 |
| OPEN_NODE_DETAIL | rulego-editor:openNodeDetail | 打开节点详情面板 | 调试模块 |
# 搜索 / 文档 / 诊断 / 面板折叠事件
| 事件常量 | 事件名 | 说明 | 触发源 |
|---|---|---|---|
| SEARCH | rulego-editor:search | 触发跨规则链搜索 | 工作区 |
| TOGGLE_DOC_BROWSER | rulego-editor:toggleDocBrowser | 切换文档浏览器 | 工作区 |
| TOGGLE_TOPOLOGY_PANEL | rulego-editor:toggleTopologyPanel | 切换链路诊断面板 | 诊断模块 |
| TOPOLOGY_PROBLEMS | rulego-editor:topologyProblems | 推送拓扑问题列表 | 诊断模块 |
| TOGGLE_SIDEBAR | rulego-editor:toggleSidebar | 切换组件面板折叠(可带 {expanded} 指定目标态,不带则翻转) | 工作区 |
| SIDEBAR_TOGGLED | rulego-editor:sidebarToggled | 折叠态回传(把手点击与 Ctrl+B 同样会发),宿主靠它对齐状态 | 核心模块 |
# 扩展事件
| 事件常量 | 事件名 | 说明 | 触发源 |
|---|---|---|---|
| START | rulego-editor:start | 编辑器启动完成 | 核心模块 |
# Vue emit(宿主通信)
RuleGoEditor 组件通过 Vue emit 向宿主发事件。这套是库消费方主要使用的通信渠道(不需要 eventCenter):
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| saveOk | 保存成功 | data:规则链数据 |
| saveError | 保存失败 | data:规则链数据,e:错误信息 |
| reset | 重置规则链 | data:规则链数据 |
| updateLocales | 更新国际化 | locales:国际化数据 |
| dirty-change | 脏态变化(宿主据此在 tab 上打脏点) | dirty:boolean |
| open-chain | 请求打开另一条链(仅 features.hostOwnsChainOpen 为 true 时发出) | chainId:string |
| request-info | 请求打开链元信息/集成弹窗 | chainId:string |
| selection-change | 选中元素变化 | payload:选中项信息 |
| sidebar-toggled | 组件面板折叠态变化 | { expanded: boolean } |
<template>
<RuleGoEditor
ref="ruleGoEditorRef"
:options="options"
@saveOk="onSaveOk"
@dirty-change="onDirtyChange"
@open-chain="onOpenChain"
@selection-change="onSelectionChange"
/>
</template>
<script setup>
import { RuleGoEditor } from '@rulego/editor'
import '@rulego/editor/style.css'
const onDirtyChange = (dirty) => console.log('脏态:', dirty)
const onOpenChain = (chainId) => console.log('请求打开链:', chainId)
const onSelectionChange = (payload) => console.log('选中变化:', payload)
const onSaveOk = (data) => console.log('保存成功', data)
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
完整事件说明见 配置 · 事件。
# 事件监听方式
# 通过 LogicFlow 实例监听
LogicFlow 实例提供了图形元素相关的事件监听:
// 获取 LogicFlow 实例(lf 是属性,不是函数)
const lf = ruleGoEditorRef.value.lf
// 监听节点点击事件
lf.on('node:click', ({ data }) => {
console.log('节点被点击:', data)
})
// 监听边点击事件
lf.on('edge:click', ({ data }) => {
console.log('边被点击:', data)
})
// 监听空白区域点击事件
lf.on('blank:click', () => {
console.log('点击了空白区域')
})
// 监听节点拖拽事件
lf.on('node:drag', ({ data }) => {
console.log('节点拖拽中:', data)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 通过 eventCenter 监听
eventCenter 用于监听编辑器内部的业务事件:
// 二次开发(源码内)场景;库消费方无法从 @rulego/editor 导入 EDITOR_EVENTS
import { EDITOR_EVENTS } from '../constants/events'
// 获取 eventCenter
const eventCenter = lf.graphModel.eventCenter
// 监听保存成功事件
eventCenter.on(EDITOR_EVENTS.SAVE_OK, (data) => {
console.log('保存成功:', data)
})
// 监听组件加载完成事件
eventCenter.on(EDITOR_EVENTS.COMPONENT_OK, (data) => {
console.log('组件加载完成:', data)
})
// 监听调试数据事件
eventCenter.on(EDITOR_EVENTS.DEBUG_DATA, (data) => {
console.log('收到调试数据:', data)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 自定义事件使用示例
# 触发自定义事件
// 通过 eventCenter 触发自定义事件
const eventCenter = lf.graphModel.eventCenter
// 触发事件并传递数据
eventCenter.emit('custom:myEvent', {
type: 'custom',
data: { key: 'value' }
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 监听自定义事件
// 监听自定义事件
eventCenter.on('custom:myEvent', (payload) => {
console.log('收到自定义事件:', payload)
})
1
2
3
4
2
3
4
# 事件监听清理
为避免内存泄漏,应在组件卸载时移除事件监听:
import { onBeforeUnmount } from 'vue'
// 定义事件处理函数
const handleSaveOk = (data) => {
console.log('保存成功:', data)
}
// 注册事件监听
eventCenter.on(EDITOR_EVENTS.SAVE_OK, handleSaveOk)
// 组件卸载时移除监听
onBeforeUnmount(() => {
eventCenter.off(EDITOR_EVENTS.SAVE_OK, handleSaveOk)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 常见事件使用场景
# 场景一:监听保存操作并执行自定义逻辑
import { EDITOR_EVENTS } from '../constants/events' // 二次开发场景
const eventCenter = lf.graphModel.eventCenter
// 保存成功后刷新外部数据
eventCenter.on(EDITOR_EVENTS.SAVE_OK, (ruleChainData) => {
// 调用外部 API 保存数据
saveToServer(ruleChainData)
// 显示成功提示
ElMessage.success('规则链保存成功')
})
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 场景二:节点点击时显示自定义面板
lf.on('node:click', ({ data }) => {
// 获取节点类型
const nodeType = data.type
// 根据节点类型显示不同的编辑面板
if (nodeType === 'customNode') {
showCustomEditPanel(data)
} else {
showDefaultEditPanel(data)
}
})
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 场景三:调试模式下高亮执行路径
import { EDITOR_EVENTS } from '../constants/events' // 二次开发场景
const eventCenter = lf.graphModel.eventCenter
// 监听调试数据,高亮当前执行的节点
eventCenter.on(EDITOR_EVENTS.DEBUG_DATA, (debugInfo) => {
const { nodeId, status } = debugInfo
// 清除之前的高亮
eventCenter.emit(EDITOR_EVENTS.CLEAR_DEBUG_HIGHLIGHT)
// 高亮当前节点
if (status === 'success') {
lf.getNodeModelById(nodeId).setProperties({
class: 'node-success'
})
} else if (status === 'error') {
lf.getNodeModelById(nodeId).setProperties({
class: 'node-error'
})
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 场景四:全屏模式下调整布局
import { EDITOR_EVENTS } from '../constants/events' // 二次开发场景
const eventCenter = lf.graphModel.eventCenter
// 监听全屏切换事件
eventCenter.on(EDITOR_EVENTS.FULL_SCREEN, (isFullScreen) => {
if (isFullScreen) {
// 进入全屏时隐藏侧边栏
hideSidebar()
// 调整画布大小
lf.resize()
} else {
// 退出全屏时显示侧边栏
showSidebar()
lf.resize()
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 场景五:批量删除选中元素
import { EDITOR_EVENTS } from '../constants/events' // 二次开发场景
const eventCenter = lf.graphModel.eventCenter
// 监听删除选中元素事件
eventCenter.on(EDITOR_EVENTS.DELETE_SELECTS, () => {
const selectedElements = lf.getSelectElements()
// 确认删除
ElMessageBox.confirm('确定删除选中的元素吗?', '提示', {
type: 'warning'
}).then(() => {
// 执行删除
selectedElements.edges.forEach(edge => {
lf.deleteEdge(edge.id)
})
selectedElements.nodes.forEach(node => {
lf.deleteNode(node.id)
})
// 触发删除完成事件
eventCenter.emit(EDITOR_EVENTS.DELETED, {
nodes: selectedElements.nodes,
edges: selectedElements.edges
})
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# LogicFlow 内置事件列表
除了 RuleGo-Editor 自定义事件外,还可以使用 LogicFlow 提供的内置事件:
# 画布事件
| 事件名 | 说明 |
|---|---|
| blank:click | 点击空白区域 |
| blank:dblclick | 双击空白区域 |
| blank:mousedown | 空白区域鼠标按下 |
| blank:mousemove | 空白区域鼠标移动 |
| blank:mouseup | 空白区域鼠标抬起 |
| blank:dragstart | 空白区域拖拽开始 |
| blank:drag | 空白区域拖拽中 |
| blank:dragend | 空白区域拖拽结束 |
# 节点事件
| 事件名 | 说明 |
|---|---|
| node:click | 点击节点 |
| node:dblclick | 双击节点 |
| node:mousedown | 节点鼠标按下 |
| node:mousemove | 节点鼠标移动 |
| node:mouseup | 节点鼠标抬起 |
| node:dragstart | 节点拖拽开始 |
| node:drag | 节点拖拽中 |
| node:dragend | 节点拖拽结束 |
| node:delete | 节点删除 |
| node:add | 节点添加 |
| node:copy | 节点复制 |
# 边事件
| 事件名 | 说明 |
|---|---|
| edge:click | 点击边 |
| edge:dblclick | 双击边 |
| edge:mousedown | 边鼠标按下 |
| edge:mouseup | 边鼠标抬起 |
| edge:delete | 边删除 |
| edge:add | 边添加 |
更多 LogicFlow 事件请参考 LogicFlow 官方文档 (opens new window)。
上次更新: 2026/08/12, 06:37:08