# 事件系统设计 **设计日期**:2026-01-28 **设计范围**:数据库客户端全局事件系统 **状态**:设计阶段 --- ## 一、设计概述 ### 1.1 设计目标 - **简洁统一**:所有组件使用统一的事件命名和参数格式 - **易于扩展**:新增事件时,遵循统一规范,易于维护 - **类型安全**:使用 TypeScript 类型定义,确保类型安全 - **功能强大**:支持事件传递、事件拦截、事件日志等高级功能 ### 1.2 设计原则 1. **命名规范**:事件名称使用 kebab-case,语义清晰 2. **参数统一**:事件参数使用对象格式,包含必要上下文信息 3. **类型定义**:所有事件都有明确的 TypeScript 类型定义 4. **文档完善**:每个事件都有清晰的文档说明 --- ## 二、事件分类 ### 2.1 连接相关事件 ```typescript // 连接选择 'connection-select': { connection: DbConnection database?: string // 可选,选中的数据库 } // 连接编辑 'connection-edit': { connectionId: number } // 连接删除 'connection-delete': { connectionId: number } // 连接刷新 'connection-refresh': { connectionId?: number // 可选,不提供则刷新所有 } ``` ### 2.2 表结构相关事件 ```typescript // 查看表结构 'table-structure': { connectionId: number database: string tableName: string // 表名/集合名/Key名 dbType: 'mysql' | 'mongo' | 'redis' nodeType: 'table' | 'collection' | 'key' | 'database' | 'connection' } // 表选择(生成SQL) 'table-select': { connectionId: number database: string tableName: string sql?: string // 可选,预生成的SQL } ``` ### 2.3 SQL执行相关事件 ```typescript // SQL执行 'sql-execute': { sql: string connectionId: number database?: string } // SQL执行完成 'sql-execute-complete': { result: SqlResult error?: string } ``` ### 2.4 编辑器相关事件 ```typescript // SQL插入 'sql-insert': { sql: string tabKey?: string // 可选,指定Tab } // Tab切换 'tab-switch': { tabKey: string } // Tab关闭 'tab-close': { tabKey: string } ``` --- ## 三、事件系统架构 ### 3.1 事件总线设计 ```typescript // 事件总线接口 interface EventBus { // 注册事件监听器 on(event: string, handler: (data: T) => void): () => void // 注册一次性事件监听器 once(event: string, handler: (data: T) => void): void // 移除事件监听器 off(event: string, handler?: Function): void // 触发事件 emit(event: string, data: T): void // 清除所有监听器 clear(): void } // 全局事件总线实例 export const eventBus = createEventBus() ``` ### 3.2 组件事件映射 ```typescript // ConnectionTree 组件事件 interface ConnectionTreeEvents { 'connection-select': { connection: DbConnection; database?: string } 'connection-edit': { connectionId: number } 'connection-delete': { connectionId: number } 'table-select': { connectionId: number; database: string; tableName: string } 'table-structure': { connectionId: number database: string tableName: string dbType: 'mysql' | 'mongo' | 'redis' nodeType: string } 'new-connection': void 'show-bookmarks': void 'show-templates': void } // SqlEditor 组件事件 interface SqlEditorEvents { 'execute': { sql: string } 'execute-selected': { sql: string } 'sql-insert': { sql: string; tabKey?: string } 'tab-switch': { tabKey: string } 'tab-close': { tabKey: string } 'toggle-editor': void } ``` --- ## 四、事件命名规范 ### 4.1 命名规则 - **格式**:`<组件>-<动作>` 或 `<功能>-<动作>` - **示例**: - `connection-select`:连接选择 - `table-structure`:表结构查看 - `sql-execute`:SQL执行 ### 4.2 动作词汇表 | 动作 | 说明 | 示例 | |------|------|------| | select | 选择 | `connection-select` | | edit | 编辑 | `connection-edit` | | delete | 删除 | `connection-delete` | | create | 创建 | `tab-create` | | close | 关闭 | `tab-close` | | switch | 切换 | `tab-switch` | | execute | 执行 | `sql-execute` | | insert | 插入 | `sql-insert` | | refresh | 刷新 | `connection-refresh` | --- ## 五、事件参数设计 ### 5.1 参数原则 1. **对象格式**:所有事件参数使用对象,不使用多个参数 2. **必要信息**:包含事件处理所需的所有上下文信息 3. **可选字段**:使用可选字段(`?`)标记非必需信息 4. **类型明确**:所有字段都有明确的类型定义 ### 5.2 参数示例 ```typescript // ✅ 好的设计:对象格式,类型明确 emit('table-structure', { connectionId: 1, database: 'test', tableName: 'users', dbType: 'mysql', nodeType: 'table' }) // ❌ 不好的设计:多个参数,类型不明确 emit('table-structure', 1, 'test', 'users', 'mysql', 'table') ``` --- ## 六、事件处理流程 ### 6.1 事件触发流程 ``` 组件内触发事件 ↓ emit('event-name', data) ↓ 父组件监听事件 ↓ 调用处理函数 ↓ 更新状态/执行操作 ``` ### 6.2 事件拦截机制(可选) ```typescript // 事件拦截器接口 interface EventInterceptor { beforeEmit?: (event: string, data: any) => boolean // 返回false阻止事件 afterEmit?: (event: string, data: any) => void // 事件触发后执行 } // 注册拦截器 eventBus.addInterceptor(interceptor) ``` --- ## 七、实现细节 ### 7.1 事件类型定义 ```typescript // 事件类型定义文件:types/events.ts export interface ConnectionSelectEvent { connection: DbConnection database?: string } export interface TableStructureEvent { connectionId: number database: string tableName: string dbType: 'mysql' | 'mongo' | 'redis' nodeType: 'table' | 'collection' | 'key' | 'database' | 'connection' } // ... 其他事件类型 ``` ### 7.2 组件事件声明 ```typescript // ConnectionTree.vue const emit = defineEmits<{ 'connection-select': [data: ConnectionSelectEvent] 'table-structure': [data: TableStructureEvent] 'table-select': [data: TableSelectEvent] // ... 其他事件 }>() ``` ### 7.3 事件处理 ```typescript // index.vue const handleTableStructure = (data: TableStructureEvent) => { // 加载表结构 structureState.loadStructure( data.connectionId, data.database, data.tableName, data.dbType ) // 切换到结构Tab resultTab.value = 'structure' } ``` --- ## 八、扩展性设计 ### 8.1 事件日志(开发模式) ```typescript // 开发模式下记录所有事件 if (import.meta.env.DEV) { eventBus.on('*', (event, data) => { console.log(`[Event] ${event}`, data) }) } ``` ### 8.2 事件统计(可选) ```typescript // 统计事件触发次数 const eventStats = new Map() eventBus.on('*', (event) => { eventStats.set(event, (eventStats.get(event) || 0) + 1) }) ``` --- ## 九、实现优先级 ### P0(必须实现) 1. ✅ 事件类型定义(TypeScript) 2. ✅ 连接相关事件 3. ✅ 表结构相关事件 4. ✅ SQL执行相关事件 ### P1(重要功能) 1. 事件参数验证 2. 事件文档完善 3. 事件处理错误处理 ### P2(优化功能) 1. 事件拦截机制 2. 事件日志(开发模式) 3. 事件统计 --- ## 十、总结 事件系统设计遵循以下原则: 1. **简洁统一**:统一的事件命名和参数格式 2. **类型安全**:完整的 TypeScript 类型定义 3. **易于扩展**:清晰的事件分类和命名规范 4. **功能强大**:支持事件拦截、日志等高级功能 通过以上设计,可以实现一个简洁、强大、易扩展的事件系统。