@huanban/rulego-editor-vue
| Install | |
|---|---|
npm install @huanban/rulego-editor-vue |
|
| Latest Version: | 1.4.2 |
| Vue: | 3 |
| License: | Apache-2.0 |
| Last Updated: | Sep 4, 2026 |
| Links: | npm |
@huanban/rulego-editor-vue
RuleGo 编辑器 Vue 3 适配层 — 提供 Vue 组件和 Composables
✨ 特性
- 开箱即用 — 提供
<RuleGoEditor />组件,一行代码嵌入编辑器 - Vue 3 Composables —
useEditorCore、useEditorWorkspace、useEditorDock、useEditorPanels、useServerStatus、useConnectionStatus、useEditorTheme、useEditorI18n - 事件监听 — 支持
@node-click、@ready、@change等 Vue 事件;保存观察使用@save,保存接管通过options.saveMode + saveHandler - 完整内置 UI — 工具栏、侧边栏、属性抽屉、设置、AI 助理、运行调试由 core 统一提供
- 大列表性能 — 组件侧栏对超大分类使用固定行高虚拟窗口,搜索和拖拽行为保持不变
- 独立管理组件 —
WorkflowList/WorkflowInfoPanel可组合出列表、详情和编辑器联动页面 - 独立 AI 对话组件 —
CopilotChat可单独引用,支持流式响应、停止、思考过程和宿主持久化 - 响应式状态 — 所有状态自动转为 Vue
ref,模板中直接使用 - TypeScript — 完整类型定义
- 兼容 Vue 3.2+ — 支持 Composition API
📦 安装
npm install @huanban/rulego-editor-vue
@huanban/rulego-editor-core 和 @huanban/rulego-editor-ui 是 Vue 包的正式运行依赖,
包管理器会自动安装。只有直接使用它们的独立 API 时才需要在宿主清单中显式声明。
🚀 快速开始
方式一:使用 <RuleGoEditor /> 组件
<template>
<RuleGoEditor
height="100vh"
:data="ruleChainData"
:components="components"
:options="editorOptions"
@node-click="onNodeClick"
@change="onChange"
/>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { RuleGoEditor } from '@huanban/rulego-editor-vue'
import '@huanban/rulego-editor-vue/style.css'
const apiBase = ref('http://127.0.0.1:9090/api/v1')
const ruleChainData = ref<any>(null)
const components = ref<any[]>([])
const editorOptions = computed(() => ({
apiBase: apiBase.value,
showToolbar: true,
showSidebar: true,
showSettingsButton: true,
showAiChatButton: true,
showRunButton: true,
}))
const onNodeClick = (node) => console.log('点击节点:', node)
const onChange = () => console.log('画布已变更')
</script>
独立 CopilotChat
CopilotChat 不依赖 <RuleGoEditor />,可以放在宿主自己的右侧 AI 面板或业务页面中。
默认只保留内存会话;需要刷新恢复时显式传入宿主管理的 persistence:
<CopilotChat
rule-chain-id="orders"
:api-base="apiBase"
model="gpt-5.4-mini"
:fetch-headers="() => ({ Authorization: `Bearer ${token}` })"
:persistence="{
adapter: {
getItem: key => localStorage.getItem(key),
setItem: (key, value) => localStorage.setItem(key, value),
removeItem: key => localStorage.removeItem(key),
},
namespace: { host: 'orders-app', editorInstance: 'customer-copilot', version: 'v1' },
}"
/>
持久化 key 按 host/editorInstance/version/chainId/component 隔离;不传
persistence 时组件仍调用宿主提供的真实 OpenAI 兼容接口,但刷新后不恢复历史。
方式二:使用 useEditorCore Composable
<template>
<div ref="editorRef" style="height: 100%"></div>
</template>
<script setup lang="ts">
import { useEditorCore } from '@huanban/rulego-editor-vue'
const { core, isReady, loadData, save } = useEditorCore()
watch(isReady, (ready) => {
if (ready) {
loadData(myRuleChainData)
}
})
</script>
📖 API
<RuleGoEditor /> Props
| 属性 | 类型 | 说明 |
|---|---|---|
data |
RuleChainData | null |
规则链数据 |
components |
RawComponentData |
组件列表,可不传;有 options.apiBase 时会自动请求 /components |
options |
Partial<HuanbanRulegoEditorOptions> |
透传 core 配置,如 apiBase/fetchHeaders/onSettingsSubmit/onLoginClick |
enableConnectionStatus |
boolean |
开启真实规则链节点、endpoint 和共享节点连接状态轮询,默认关闭 |
height |
string | number |
编辑器高度,默认 100% |
width |
string | number |
编辑器宽度,默认 100% |
theme |
string |
主题名称 |
className |
string |
自定义 class |
customStyle |
Record<string,string | number> |
自定义内联样式 |
renderNode |
(type, data, model) => VNode |
自定义 Headless 节点渲染 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
@save |
SaveEventData |
兼容事件;默认保存不依赖它,接管保存请使用 options.onSave |
@node-click |
NodeData |
节点点击时触发 |
@ready |
— | 编辑器就绪时触发 |
@change |
— | 画布数据变化 |
@edge-click |
EdgeData |
连线点击 |
@deploy |
chainId, action |
部署/下线;后端动作严格对应 start/stop |
@restart |
chainId |
重启;与 operate 分离,内置流程读取服务端 DSL 后原样保存 |
@connection-status-change |
ConnectionStatusState |
当前 Core 节点/共享节点连接状态变化,不增加轮询 |
在 options.showRestartButton=true 时显示重启入口。重启会重建节点实例,内存会话、
计数器、定时器等瞬态状态会重置,端点连接可能短暂重连。宿主使用 options.onRestart
接管时也必须执行 GET /rules/:id 后原样 POST /rules/:id,不得调用 operate/reload。
options.showReloadButton 只作为弃用兼容别名保留。
enableConnectionStatus 默认关闭。开启后,编辑器实例按当前规则链串行请求
GET {apiBase}/rules/:id/status,共享节点管理面板打开期间按引用请求
GET {apiBase}/shared-node-statuses。Vue 适配层不会额外创建轮询器;可通过组件 ref 暴露的
方法控制同一个 standalone 实例:
editorRef.value?.refreshConnectionStatuses()
const release = editorRef.value?.acquireSharedConnectionStatuses()
// 关闭共享节点管理面板时释放本次引用。
release?.()
宿主需要在自定义 UI 中响应式展示状态时,主组件直接监听变更事件:
<RuleGoEditor
ref="editorRef"
:enable-connection-status="true"
@connection-status-change="connectionState = $event"
/>
自定义组合层已经持有 ConnectionStatusStore 时,可使用
useConnectionStatus({ connectionStatus: hostStore }) 订阅同一个 store。composable 不创建请求;
未传 store 时只返回空状态。
状态接口返回 401/403 时会暂停对应轮询并交给宿主认证流程,404/501 表示后端未提供能力
并停止探测,网络错误只标记状态可能已过期,不会伪造在线状态。连接状态是运行时展示数据,
不会写入 LogicFlow history、节点复制结果、DSL 导出或保存 payload。
命令式加载与工作区 Tab
组件 ref 暴露的命令式 API 会复用当前 HuanbanRulegoEditor,不会因为加载或切换
Tab 重建 LogicFlow:
<script setup lang="ts">
import { ref } from 'vue'
import {
RuleGoEditor,
type RuleGoEditorRef,
} from '@huanban/rulego-editor-vue'
const editorRef = ref<RuleGoEditorRef | null>(null)
function loadRemote(remoteChain: any) {
// 新远程数据或导入数据:建立新的已保存基线。
editorRef.value?.loadData(remoteChain)
}
function restoreDraft(tabDraft: any) {
// 恢复当前 Tab 草稿:保留 savedData、dirty 标记和 JSON diff。
editorRef.value?.loadData(tabDraft, { preserveWorkspaceTab: true })
}
function activateTab(tabId: string) {
// Tab 不存在时返回 false。
return editorRef.value?.activateWorkspaceTab(tabId) ?? false
}
</script>
<template>
<RuleGoEditor ref="editorRef" :options="editorOptions" :data="ruleChainData" />
</template>
preserveWorkspaceTab 只用于恢复当前已有 Tab 的草稿。首次加载、新建远程规则链或
导入 clean 快照时不要开启。确实需要同时打开同一 chainId 的多个工作副本时,显式
传 { allowDuplicateWorkspaceTab: true }。
自定义工作台隐藏内置工具栏时,可以直接打开组件管理的指定页签:
editorRef.value?.openComponentManager('shared')
页签类型为 ComponentManageDialogTab,可选 installed / market / dsl /
shared。设置 options.onComponentManage 接管弹窗时,component-manage 事件和宿主回调都会
收到同一个初始页签;未接管时使用 Core 内置管理器,不会在 Vue 层创建第二套请求或状态轮询。
保存协议
默认不要传 options.onSave。只要在 options.apiBase 配置后台地址,保存按钮会直接调用:
POST {apiBase}/rules/:id
GET {apiBase}/rules/:id
第二次 GET 用于回读校验,只有后端返回的数据与当前画布一致时才会显示已保存。
只有宿主确实要完全接管保存时才在 options 中设置 saveMode: 'host' 并传
saveHandler。执行器必须返回明确结果:
const editorOptions = computed(() => ({
apiBase: apiBase.value,
saveMode: 'host' as const,
saveHandler: async (data: any) => {
const id = data?.ruleChain?.id
const response = await fetch(`${apiBase.value}/rules/${encodeURIComponent(id)}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...fetchHeaders() },
body: JSON.stringify(data),
})
return response.ok ? { success: true } : { success: false, message: `HTTP ${response.status}` }
},
}))
单纯监听 @save 只观察保存请求,不会短路内置保存。不要在 @save 中再次 POST,
否则会和内置保存重复。旧版 options.onSave 仍兼容宿主执行器,但新接入应使用明确的
saveMode + saveHandler 合同。
<WorkflowList /> 管理列表
WorkflowList 是独立管理组件,不是编辑器。它负责查询、搜索、创建、部署/下线、复制、删除和选择规则链;进入画布编辑需要通过 :on-design 切换到 <RuleGoEditor />。
工作流列表的内置请求层支持宿主管理的认证和服务状态:
<WorkflowList
:api-base="apiBase"
:api-options="{
headers: () => ({ Authorization: `Bearer ${readToken()}` }),
credentials: 'include',
onAuthRequired: ({ status }) => host.openLogin({ reason: status }),
serverStatus,
}"
:on-error="showRequestError"
/>
默认兼容浏览器 token/access_token;纯 Cookie 接入设置
includeStoredToken: false。HTTP 401 表示凭据缺失或失效,宿主应打开登录流程并清理失效凭据;
HTTP 403 表示凭据有效但权限不足,保留当前凭据并显示权限提示;网络失败和超时会通过
:on-error 暴露为离线或请求失败,不能被当成空列表。Vue 只会替换列表请求层,不会因为认证配置变化重建编辑器画布。
结构性配置与重建边界
lfOptions、lfPlugins 和 persistence 在编辑器实例创建时绑定,属于结构性配置。
它们不会被普通 prop 更新热替换;updateOptions() 返回的 structuralKeys 会明确列出这类变更。
宿主应先保存或处理 dirty 状态,再改变 Vue 的原生 key,让组件完整销毁并重建:
<RuleGoEditor
:key="`${editorInstanceId}:${structuralConfigVersion}`"
:options="{ lfOptions, lfPlugins, persistence }"
:data="chainData"
/>
不要用每次 render 都新建的对象内容作为 key,否则会造成画布闪屏、焦点丢失和未保存数据风险。
普通 API、主题、语言、显示开关和回调仍走热更新,不应为了这些选项重建画布。React 和 standalone
使用同一边界契约。
<template>
<section class="workspace">
<WorkflowList
:api-base="apiBase"
layout="grid"
:on-info="workflow => selectedWorkflow = workflow"
:on-design="openEditor"
/>
<WorkflowInfoPanel
:api-base="apiBase"
:workflow="selectedWorkflow"
/>
</section>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { WorkflowInfoPanel, WorkflowList } from '@huanban/rulego-editor-vue'
const apiBase = 'http://127.0.0.1:9090/api/v1'
const selectedWorkflow = ref<any>(null)
async function openEditor(id: string) {
const response = await fetch(`${apiBase}/rules/${encodeURIComponent(id)}`)
const chainData = await response.json()
console.log('switch to editor with', chainData)
}
</script>
常用属性:
| 属性 | 说明 |
|---|---|
layout |
默认 grid 卡片布局;传 list 使用紧凑列表 |
autoOpenAfterCreate |
传了 onDesign 时默认开启;新建成功后自动进入编辑器 |
onDesign |
双击卡片或点击菜单“设计”时触发,宿主在这里打开编辑器 |
onInfo |
单击卡片或点击菜单“信息”时触发,宿主在这里联动详情 |
onViewLogs |
点击“日志”时触发,参数为 (chainId, workflow?);第二个参数是当前列表接口返回的真实工作流对象 |
默认新建弹窗包含 ID、名称、主链/子链、初始状态、调试模式、分类、描述。ID 自动生成,也可手动输入;为兼容后台路由,ID 不能包含 /、\ 或 .。
WorkflowInfoPanel 默认只显示基础信息、输入定义、变量和应用集成。维护验证是扩展能力,不是默认工作流详情的一部分;只有宿主后端已经实现 validate-upstream、schema-diff、repair-plan、patch-preview 这组分析接口时才开启:
<WorkflowInfoPanel
:api-base="apiBase"
:workflow="selectedWorkflow"
show-maintenance
/>
如果后台没有这些接口,保持默认关闭,避免用户点击后出现 404 Not Found。
服务地址、设置和登录
Vue 版通过 :options 传入后台地址、认证和设置回调:
const editorOptions = computed(() => ({
apiBase: apiBase.value,
allowedApiOrigins: [new URL(apiBase.value, window.location.origin).origin],
showSettingsButton: true,
fetchHeaders: () => {
const token = localStorage.getItem('token') || localStorage.getItem('access_token')
return token ? { Authorization: `Bearer ${token}` } : {}
},
onSettingsSubmit: ({ apiBase: nextApiBase }: { apiBase: string }) => {
localStorage.setItem('huanban_rulego_api_base', nextApiBase)
apiBase.value = nextApiBase
},
onLoginClick: () => window.dispatchEvent(new CustomEvent('open-login')),
onAuthExpired: () => window.dispatchEvent(new CustomEvent('open-login')),
clearToken: () => {
localStorage.removeItem('token')
localStorage.removeItem('access_token')
localStorage.removeItem('username')
},
}))
如果不传 onLoginClick,内置设置页会打开默认登录弹窗,并请求 POST {apiBase}/login。完整新项目接入说明见根目录 docs/CLIENT_INTEGRATION.md。
useEditorCore(options?) 返回值
| 属性 | 类型 | 说明 |
|---|---|---|
core |
EditorCore |
编辑器核心实例 |
isReady |
Ref<boolean> |
编辑器是否就绪 |
isDirty |
Ref<boolean> |
数据是否已修改 |
loadData |
(data) => void |
加载规则链数据 |
save |
() => void |
触发保存 |
on |
(event, handler) => void |
监听事件 |
工作区、Dock 和服务状态 Composables
需要自己搭建工作台时,使用这些 composable。它们只负责 Vue 响应式桥接,Tab、dirty
草稿、关闭确认、尺寸限制和 401/1006 状态都由 editor-core 统一管理。
import {
useEditorWorkspace,
useEditorDock,
useServerStatus,
useConnectionStatus,
} from '@huanban/rulego-editor-vue'
const { tabs, activeTab, openTab, closeTab } = useEditorWorkspace()
const { state: dockState, setDockWidth } = useEditorDock()
const { state: serverState, recordHttpStatus, recordWebSocketStatus } = useServerStatus({
baseUrl: 'http://127.0.0.1:19806',
})
// 已持有主编辑器的 Core store 时使用;这里只订阅,不创建轮询。
const { state: connectionState } = useConnectionStatus({ connectionStatus: hostConnectionStatus })
独立工作区 Tab
需要自己组合多规则链工作台时,可以使用 WorkspaceTabs。它只负责渲染
EditorWorkspace 状态,保存、关闭确认和后端请求仍由宿主处理:
<script setup lang="ts">
import { WorkspaceTabs, useEditorWorkspace } from '@huanban/rulego-editor-vue'
import '@huanban/rulego-editor-vue/style.css'
const workspace = useEditorWorkspace()
</script>
<template>
<WorkspaceTabs
:tabs="workspace.tabs.value"
:active-tab-id="workspace.activeTab.value?.id"
@activate="workspace.activateTab"
@close="workspace.closeTab"
@add="() => workspace.openTab({ title: '新规则链' })"
@edit-info="openRuleChainInfo"
:on-tab-action="(tabId, action) => {
if (action === 'rename') openRuleChainInfo(tabId)
if (action === 'run-history') openRunHistory(tabId)
if (action === 'debug') openDebugPanel(tabId)
if (action === 'toggle-disabled') toggleChainDisabled(tabId)
}"
/>
</template>
Tab 组件会显示主链/子链、加载状态、未保存标记和溢出选择菜单,不会重新创建
画布,也不会绕过宿主的保存和权限策略。组件同时发出 tab-action 事件,稳定动作
ID 为 rename、toggle-disabled、run-history、debug;动作对应的真实保存、
start/stop 请求、登录和错误反馈仍由宿主处理。
serverState.value.api 与 serverState.value.ws 独立更新。收到 401/403 时展示登录
入口,收到 WS 1006 时展示实时连接断开和重连入口,不会把两种问题混成同一个状态。
独立状态栏与连接状态
需要自己组合编辑器外壳时,可以复用 EditorStatusBar 和
EditorConnectionStatus。组件只消费宿主传入的 LogicFlow/Core 状态,不自行请求、
重连或登录;服务端动作由宿主回调接管:
<EditorConnectionStatus
:state="serverState"
:on-login="openLogin"
:on-retry="checkConnection"
/>
<EditorStatusBar
:lf="editorRef?.lf"
:problem-count="problems.length"
:on-open-diagnostics="openDiagnostics"
@open-diagnostics="openDiagnostics"
/>
EditorConnectionStatus 分别显示 API 与 WS 状态,EditorStatusBar 提供缩放、节点
数、边数、选中数和诊断入口。未传 on-login/on-retry 时,Vue 组件会发出对应事件,
方便宿主接入自己的认证和重试流程。
独立 Dock 面板
EditorPanelDock 只渲染 EditorPanelRegistry / EditorDockStore 的状态,支持左侧
堆叠、右侧/底部/AI Tab、关闭和拖动尺寸;面板内容通过命名 slot 提供:
<EditorPanelDock
dock="right"
:dock-state="dockState"
:panel-state="panelsState"
@activate-panel="panels.activatePanel"
@close-panel="panels.closePanel"
@toggle-dock="(_, visible) => dock.setDockVisibility('right', visible)"
:on-resize="(id, size) => dock.setDockWidth(id, size)"
>
<template #panel-info><InfoPanel /></template>
<template #panel-node-config><NodeConfigPanel /></template>
</EditorPanelDock>
组件不自行保存、请求或创建面板状态;Vue 宿主可以继续使用自己的设置、AI、登录和 客服测试页面,而不会把场景模块混入编辑器包。
节点与连线悬浮工具
EditorNodeHoverTools 和 EditorEdgeHoverTools 接收宿主计算的目标 ID 与画布坐标,
负责统一渲染编辑、复制、执行、插入和删除按钮,并通过回调或 action 事件转发:
<EditorNodeHoverTools
:target-id="selectedNode.id"
:x="toolbarPosition.x"
:y="toolbarPosition.y"
:on-edit="openNodeEditor"
:on-delete="confirmDeleteNode"
:on-run-from="openRunPanel"
/>
<EditorEdgeHoverTools
:target-id="selectedEdge.id"
:x="edgePosition.x"
:y="edgePosition.y"
:on-insert-node="insertNodeOnEdge"
:on-delete="confirmDeleteEdge"
/>
删除动作只通知宿主,不直接修改画布;二次确认、权限和保存仍由 Core/宿主处理。所有
按钮都带有 title 与 aria-label,flip-down 可用于靠近画布顶部的工具条。
EditorEdgeHoverTools 的 onInsertNode 参数是连线 ID。宿主应调用主编辑器的
openNodePicker({ edgeId, excludeInputNodes: true }),由 Core 统一完成
source -> new -> target 替换和失败回滚,不能把该 ID 当作节点 ID 直接追加边。
🔗 相关包
@huanban/rulego-editor-core— 核心引擎 (必需)@huanban/rulego-editor-ui— UI 组件集 (可选)@huanban/rulego-editor-react— React 适配层
📄 协议
Apache-2.0
Related Packages
Vue 3 composables and components to help integrate Alis Ideate into your product...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.4.2 | >=3.2.0 <4 | Apache-2.0 | |
| 1.4.1 | >=3.2.0 <4 | Apache-2.0 | |
| 1.4.0 | >=3.2.0 <4 | Apache-2.0 | |
| 1.3.18 | >=3.2.0 | Apache-2.0 | |
| 1.3.17 | >=3.2.0 | Apache-2.0 | |
| 1.3.16 | >=3.2.0 | Apache-2.0 | |
| 1.3.15 | >=3.2.0 | Apache-2.0 | |
| 1.3.14 | >=3.2.0 | Apache-2.0 | |
| 1.3.13 | >=3.2.0 | Apache-2.0 | |
| 1.3.12 | >=3.2.0 | Apache-2.0 | |
| 1.3.11 | >=3.2.0 | Apache-2.0 | |
| 1.3.10 | >=3.2.0 | Apache-2.0 | |
| 1.3.9 | >=3.2.0 | Apache-2.0 | |
| 1.3.8 | >=3.2.0 | Apache-2.0 | |
| 1.3.7 | >=3.2.0 | Apache-2.0 | |
| 1.3.6 | >=3.2.0 | Apache-2.0 | |
| 1.3.5 | >=3.2.0 | Apache-2.0 | |
| 1.3.4 | >=3.2.0 | Apache-2.0 | |
| 1.3.3 | >=3.2.0 | Apache-2.0 | |
| 1.3.2 | >=3.2.0 | Apache-2.0 | |
| 1.3.1 | >=3.2.0 | Apache-2.0 | |
| 1.3.0 | >=3.2.0 | Apache-2.0 | |
| 1.2.0 | >=3.2.0 | Apache-2.0 | |
| 1.1.6 | >=3.2.0 | Apache-2.0 | |
| 1.1.5 | >=3.2.0 | Apache-2.0 | |
| 1.1.4 | >=3.2.0 | Apache-2.0 | |
| 1.1.3 | >=3.2.0 | Apache-2.0 | |
| 1.1.2 | >=3.2.0 | Apache-2.0 | |
| 1.1.0 | >=3.2.0 | Apache-2.0 | |
| 1.0.15 | >=3.2.0 | Apache-2.0 |
Showing the latest 30 of 32. See every release on npm