Beekeeper Studio UI Kit 实体列表(Entity List)组件完全指南:属性、事件与实战用法
【免费下载链接】beekeeper-studioModern and easy to use SQL client for MySQL, Postgres, SQLite, SQL Server, and more. Linux, MacOS, and Windows.项目地址: https://gitcode.com/GitHub_Trending/be/beekeeper-studio
实体列表(Entity List)是 Beekeeper Studio UI Kit 提供的 Web Component,用于以可展开/折叠的树形结构展示数据库对象(表、视图、物化视图、例程与模式),是数据库客户端侧边栏的核心交互组件。本文以 Entity List API 为骨架,结合 Entity List 使用指南 与仓库源码,完整讲解其全部属性(Properties)、事件(Events)以及 Schema 分组、隐藏、置顶、懒加载列、虚拟渲染等实战能力,帮助你在自己的数据库工具或管理界面中直接复用该组件。
组件概览:如何引入 bks-entity-list
bks-entity-list是一个通过 define.ts 注册到window.customElements的自定义元素,底层由 EntityList.vue 经@vue/web-component-wrapper包装而成(见 index.ts)。也就是说,你可以像使用原生 HTML 标签一样在任意页面中使用它,并通过属性(property)赋值和事件监听(addEventListener)来驱动它:
<bks-entity-list></bks-entity-list> <script> const entityList = document.querySelector("bks-entity-list"); entityList.entities = [{ name: "users" }]; </script>其数据来源是entities属性——一个由 Entity 对象组成的数组。Entity 类型在源码中定义为TableEntity | RoutineEntity | SchemaEntity三种联合类型,见 types.ts。
Properties:组件全部可配置属性
以下是 Entity List API 中声明的全部属性:
| 名称 | 类型 | 说明 | 默认值 |
|---|---|---|---|
entities | object[] | 实体数组,详见 Entity API | [] |
hiddenEntities | object[] | 被隐藏的实体数组,详见 Entity API | [] |
contextMenuItems | object[]|function | 扩展默认右键菜单,详见 Context Menu | undefined |
除了 API 文档声明的三个核心属性,组件的实际 props 定义(entity-list.ts)还暴露了以下常用配置项,源码中有明确注释说明其用途:
| 属性 | 类型 | 说明 | 默认值 |
|---|---|---|---|
pinnedEntities | Entity[] | 显示在主列表上方的置顶实体数组 | [] |
enablePinning | boolean | 是否启用实体置顶功能 | false |
pinnedSortBy | "position"|"name" | 置顶实体的排序字段 | "position" |
pinnedSortOrder | string | 置顶实体的排序方向 | "asc" |
showCreateEntityBtn | boolean | 是否显示"新建实体(+)"按钮 | true |
其中pinnedSortBy的可选值在源码中通过SortByValues = ["position", "name"]常量约束,contextMenuItems同时接受数组或函数两种形态(CustomMenuItems类型),用于静态或动态生成菜单项。
Events:组件对外广播的全部事件
Entity List API 声明了以下 9 个事件,完整列表如下:
| 事件名 | 触发时机 | Event Detail |
|---|---|---|
bks-entity-expand | 实体被展开时 | { entity: Entity } |
bks-entity-collapse | 实体被折叠时 | { entity: Entity } |
bks-entity-dblclick | 实体被双击时 | { event: MouseEvent, entity: Entity } |
bks-entity-contextmenu | 实体被右键点击时 | { event: MouseEvent, entity: Entity } |
bks-entities-request-columns | 展开实体但其columns为undefined时 | { entity: Entity } |
bks-expand-all | 点击"全部展开"按钮且所有实体均已展开时 | - |
bks-collapse-all | 点击"全部折叠"按钮且所有实体均已折叠时 | - |
bks-add-entity-click | 点击"新建实体"按钮时 | { event: MouseEvent } |
bks-refresh-click | 点击"刷新"按钮时 | { event: MouseEvent } |
这些事件在源码中有类型化定义:EntityListEventMap(types.ts)将事件名与CustomEvent的 payload 类型一一绑定,例如"bks-entity-dblclick": CustomEvent<{ entity: Entity }>。同时组件还额外派发了bks-entity-pin、bks-entity-unpin、bks-entity-unhide、bks-refresh-btn-click、bks-pinned-entities-sort-by等事件(见 EntityList.vue 与事件映射表),分别对应置顶、取消置顶、取消隐藏与刷新按钮等交互。
典型的事件监听方式:
entityList.addEventListener("bks-entity-dblclick", (event) => { console.log("双击了实体:", event.detail.entity); });基本用法:从最小实体到带列结构
只提供名称的实体
最简单的实体只需一个name字段,此时默认按table类型渲染:
const entities = [{ name: "users" }, { name: "orders" }];携带列信息的实体
提供columns后,展开实体即可看到列清单,每个列由field(列名,必填)和dataType(数据类型,可选)构成,对应TableColumn接口(Entity API):
<bks-entity-list></bks-entity-list> <script> const entities = [ { name: "users", columns: [ { field: "id", dataType: "integer" }, { field: "name", dataType: "string" }, ], }, ]; const entityList = document.querySelector("bks-entity-list"); entityList.entities = entities; </script>Schemas:按模式自动分组
给实体对象提供一个schema字符串属性,实体就会自动归入对应的模式(schema)文件夹内,同一模式的多个实体共享一个文件夹:
const entities = [ { name: "users", schema: "public" }, { name: "orders", schema: "public" }, ];该行为在 treeItems.ts 的树构建逻辑与 entity-list.spec.ts 中有明确的测试印证:当实体携带schema时,树中会先插入一个type: "schema"、entity: { entityType: "schema", name: "public" }的文件夹节点,实体节点则以level: 1挂在其下;测试还验证了无 schema、单 schema、多 schema 三种场景下树的生成结构。
Entity types:四种实体类型
组件识别table、view、materialized-view、routine四种类型,schema类型则由组件在按模式分组时自动生成。示例如下:
const entities = [ { name: "users" }, // 缺省类型,默认按 table 处理 { name: "users", entityType: "table" }, { name: "order_summary", entityType: "view" }, { name: "order_summary_2", entityType: "materialized-view" }, { name: "get_order", entityType: "routine", returnType: "integer", type: "function", // function / window / aggregate / procedure }, ];在 models.ts 中,例程类型RoutineTypeNames被映射为四种展示名称:function(Function)、window(Window Function)、aggregate(Aggregate Function)、procedure(Stored Procedure)。例程实体的完整结构见 Entity API:entityType必须为"routine",returnType必填,还可选提供returnTypeLength与routineParams(每个参数包含必填的name、type与可选的length)。
Identifier:实体标识符的确定规则
实体列表默认使用name、schema、entityType三者的组合作为实体的唯一标识符(key)。如果需要使用自定义标识,可在实体对象上添加id属性:
const users = { id: "abc123", name: "users" };从测试用例(entity-list.spec.ts)可以看到实际 key 的生成形态:无 schema 时形如table..users、routine..get_users;带 schema 时形如table.public.users;schema 文件夹节点形如schema.public。也就是说,标识符按{entityType}.{schema}.{name}的模式拼接,提供id后即可绕过这一默认规则。
Hiding:隐藏实体与 UI 辅助
从逻辑上讲,只要不把某个实体放进entities数组,它就不会显示。但组件还提供了 UI 提示与一个"隐藏实体"弹窗(HiddenEntitiesModal),帮助用户统一管理被隐藏的实体列表。启用方式是把要隐藏的实体放进hiddenEntities属性:
const entities = [users, orders]; const hiddenEntities = [orders]; entityList.entities = entities; entityList.hiddenEntities = hiddenEntities; // 监听"取消隐藏"事件,从 hiddenEntities 中移除目标实体 entityList.addEventListener("bks-entity-unhide", (event) => { const entity = event.detail.entity; const entities = hiddenEntities.filter( (hiddenEntity) => hiddenEntity !== entity ); entityList.hiddenEntities = entities; });在组件模板(EntityList.vue)中,当hiddenEntities非空且没有激活过滤时,标题区会显示一个visibility_off徽标与隐藏数量(超过 99 显示为99+),并提供"Right click an entity to hide it"的悬浮提示与"View hidden"入口,点击后打开HiddenEntitiesModal弹窗,弹窗内的"取消隐藏"通过bks-entity-unhide事件回传给宿主应用。
Pinning:置顶实体
置顶功能可以把常用实体固定显示在主列表上方。启用方式为:将enablePinning设为true,并把需要置顶的实体放入pinnedEntities:
const entities = [users, orders]; const pinnedEntities = [orders]; entityList.enablePinning = true; entityList.entities = entities; entityList.pinnedEntities = pinnedEntities; // 处理置顶:追加实体到 pinnedEntities entityList.addEventListener("bks-entity-pin", (event) => { const entity = event.detail.entity; const entities = pinnedEntities.concat(entity); entityList.pinnedEntities = entities; }); // 处理取消置顶:从 pinnedEntities 中移除实体 entityList.addEventListener("bks-entity-unpin", (event) => { const entity = event.detail.entity; const entities = pinnedEntities.filter( (pinnedEntity) => pinnedEntity !== entity ); entityList.pinnedEntities = entities; });置顶区域由独立的 PinnedTableList.vue 渲染,主列表与置顶列表之间通过split.js提供了可拖拽的分隔条(见 EntityList.vue)。置顶实体还支持排序(bks-pinned-entities-sort-by、bks-pinned-entities-sort-order、bks-pinned-entities-sort-position事件),默认按position升序排列,可切换为按name排序。
Lazy Loading Columns:列信息的懒加载
开启列懒加载非常简单:不设置实体的columns属性,或显式将其设为undefined,组件就会在需要时主动请求列信息。
当实体被展开(点击实体图标旁的展开箭头,或点击右上角的"全部展开"按钮)时,组件会派发bks-entities-request-columns事件,宿主应用在此事件中异步获取列并写回实体对象:
entityList.addEventListener("bks-entities-request-columns", (event) => { const entities = event.detail.entities; for (const entity of entities) { const columns = await fetchColumns(entity); entity.columns = columns; } });该机制同样适用于其他表类实体(view与materialized-view)。借助虚拟渲染,组件只会为进入视口的实体发起请求,避免一次加载海量列定义。如果想彻底关闭懒加载、阻止事件派发,只需把实体的columns设为[](空数组)。事件的派发链路在 EntityList.vue 中可以看到:handleRequestItemsColumns/handleRequestEntitiesColumns将Item[]或Entity[]映射为{ entities: [...] }后统一 emit。
Virtual Rendering:虚拟渲染与内置过滤
实体列表采用虚拟渲染策略,只渲染视口内的实体,并在用户滚动时增量更新,从而支撑包含大量表/视图/例程的大型数据库侧边栏。
组件内部还内置了实体过滤能力(sql_tools.ts):顶部的过滤输入框按名称做"前缀优先、包含次之"的两级匹配(先收集以查询词开头的实体,再收集包含查询词的实体并拼接);右上角的过滤菜单则支持按 Tables / Views / Routines 分类开关,showPartitions用于控制分区实体(parenttype == 'p')的显示。过滤激活时标题区会显示shownEntities / totalEntities的计数徽标(EntityList.vue)。
Context Menu:扩展右键菜单
contextMenuItems属性用于在默认右键菜单基础上追加自定义项,它可以是一个菜单项数组,也可以是一个函数(动态生成菜单项)。组件默认内置了"Copy Name"菜单项(将实体名写入剪贴板,见 EntityList.vue)。右键实体的处理流程在 EntityList.vue 中:先派发bks-entity-contextmenu事件,再通过useCustomMenuItems合并默认菜单与自定义菜单,最后调用openMenu打开菜单。
关于自定义菜单项的完整配置方式(数组/函数两种形态、菜单项字段结构等),请参考 Context Menu 文档。
API 速查:相关文档与源码索引
- Entity List API:组件属性与事件的官方 API 参考
- Entity List 使用指南:完整的使用示例
- Entity API:
Entity类型定义(表/视图/物化视图/例程/模式) - Context Menu:右键菜单扩展指南
- 组件实现:EntityList.vue、entity-list.ts、types.ts、treeItems.ts
- 类型定义:types.ts、models.ts
- 单元测试:entity-list.spec.ts(覆盖无 schema / 单 schema / 多 schema 三种树的构建场景)
小结
bks-entity-list是一个开箱即用的数据库实体树组件:通过entities、hiddenEntities、contextMenuItems三个核心属性完成数据与交互注入,通过bks-entity-expand、bks-entities-request-columns、bks-entity-pin等事件与宿主应用双向协作;配合 Schema 自动分组、四种实体类型、置顶、懒加载列与虚拟渲染,足以支撑从个人工具到生产级数据库客户端侧边栏的完整需求。需要获取列信息、持久化隐藏/置顶状态或注入自定义菜单时,记得在对应事件中更新属性,让组件始终保持单一数据源驱动。
【免费下载链接】beekeeper-studioModern and easy to use SQL client for MySQL, Postgres, SQLite, SQL Server, and more. Linux, MacOS, and Windows.项目地址: https://gitcode.com/GitHub_Trending/be/beekeeper-studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考