bricks/aidocs/tab.md
2025-10-05 06:39:58 +08:00

8.0 KiB
Raw Blame History

TabPanel 组件技术文档

命名空间: bricks.TabPanel
继承自: bricks.Layout
注册名称: 'TabPanel'(可通过工厂创建)


概述

TabPanel 是一个可切换内容区域的布局组件,支持多标签页管理。每个标签页可以包含独立的内容组件(如其他 widget并支持动态加载、缓存和事件通知机制。

标签位置可配置为上下左右四种方向,内容区自动适配布局顺序。


构造函数

new bricks.TabPanel(options)

参数

参数 类型 说明
options Object 配置选项对象,继承自 bricks.Layout 并扩展以下属性

Options 配置项

{
  tab_pos: "top",        // 标签栏位置: 'top', 'bottom', 'left', 'right'
  tab_long: "100%",      // 标签宽度或高度CSS 值字符串)
  items: [               // 标签项数组
    {
      name: "tab1",      // 标签唯一标识名(必填)
      label: "Tab 1",    // 显示文本
      icon: "",          // 图标类名(可选)
      removable: false,  // 是否可关闭(显示删除按钮)
      refresh: false,    // 是否每次点击都重新构建内容
      content: {         // 内容描述对象,用于构建子 Widget
        widgettype: "..."// 如: "Text", "Grid" 等
        // 其他 widget 特定参数
      }
    }
  ],
  css: ""                // 自定义 CSS 类名(附加到根元素)
}

⚠️ 注意:content 可以是标准 widget 描述对象,也可以直接是一个 bricks.JsWidget 实例。


布局结构

根据 tab_pos 不同,整体采用 vboxhbox 布局:

tab_pos 主轴方向 子组件排列顺序
"top" / "bottom" 垂直 (vbox) 上/下:标签 → 内容;下/上:内容 → 标签
"left" / "right" 水平 (hbox) 左/右:标签 → 内容;右/左:内容 → 标签
  • 标签容器this.tab_containerVBox 容器)
  • 内容容器this.content_containerFiller 容器,用于动态替换内容)

样式类CSS Classes

组件使用如下 CSS 类进行样式控制:

类名 作用
.tabpanel 根元素样式
.tab-button 单个标签按钮默认样式
.tab-button-active 当前激活标签样式
.tab-button-hover 鼠标悬停时标签样式
.tab-content 内容区域样式(已通过 set_css('tabpanel-content') 设置)
.vbox, .hbox 布局方向控制

开发者可在主题 CSS 中覆盖这些类以自定义外观。


事件系统

1. switch 事件(在 TabPanel 上触发)

当标签切换导致内容变更时触发。

  • 事件名: 'switch'
  • 回调参数: 被激活的内容 widget 实例
  • 示例:
tabpanel.bind('switch', function(widget) {
  console.log("当前显示内容组件:", widget);
});

2. active 事件(在内容 widget 上触发)

当该内容面板被切换为可见状态时,在其自身上触发 active 事件。

  • 用途: 用于内容初始化、数据刷新等操作。
  • 示例:
contentWidget.bind('active', function() {
  this.refreshData(); // 自定义刷新逻辑
});

3. Toolbar 内部事件(自动绑定)

  • 'command': 用户点击标签时触发 → 调用 show_tabcontent
  • 'remove': 用户关闭标签时触发 → 调用 tab_removed
  • 'ready': Toolbar 初始化完成后 → 自动显示第一个标签

方法说明

constructor(options)

初始化 TabPanel 实例,创建标签栏与内容容器,并根据配置设置布局方向。

关键行为:

  • 创建内部 toolbarcontent_container
  • 根据 tab_pos 设置主轴布局(vbox / hbox
  • 调用 createToolbar() 构建标签工具栏
  • 最后调用 show_first_tab() 显示首个标签页

show_first_tab()

手动触发第一个标签页的显示。

this.show_first_tab();

通常由 'ready' 事件自动调用。


createToolbar()

基于 options.items 创建一个 bricks.Toolbar 作为标签栏。

行为:

  • 设置 orientation
    • top / bottomhorizontal
    • left / rightvertical
  • 绑定事件:
    • 'command'show_tabcontent
    • 'remove'tab_removed
    • 'ready'show_first_tab
  • 添加至 tab_container

async show_tabcontent(event)

处理标签点击事件,加载并显示对应内容。

流程:

  1. 若点击的是当前标签,忽略重复操作。
  2. 查找匹配的 item 配置。
  3. 尝试从缓存 content_buffer 获取已有 widget
    • 若存在且 refresh: false,直接复用。
  4. 否则异步构建新 widget
    • 支持直接传入 bricks.JsWidget 实例
    • 或通过 bricks.widgetBuild() 解析配置生成
  5. 缓存 widget调用 switch_content(w) 切换显示

错误捕获:构建失败会输出 debug 日志。


switch_content(w)

切换内容区域为指定 widget。

动作:

  • 清空当前内容容器:clear_widgets()
  • 添加新 widget
  • 触发 switch 事件(携带 widget 参数)
  • 触发内容 widget 的 active 事件
this.switch_content(widgetInstance);

add_tab(desc)

动态添加一个新的标签页。

参数:

  • desc: 符合 items 结构的对象(必须含 name, label 等)

行为:

  • 调用 toolbar.createTool(desc) 添加按钮
  • removable === true,启用关闭功能(需手动实现 UI 支持)

示例:

tabpanel.add_tab({
  name: 'dynamic',
  label: '动态标签',
  content: { widgettype: 'Text', text: '这是动态添加的内容' },
  removable: true
});

tab_removed(event)

处理标签被移除后的逻辑。

参数:

  • event.params.name: 被删除标签的 name

行为:

  • content_buffer 中清除缓存
  • 如果当前正在显示该标签,则自动切换回第一个标签页

缓存机制

  • 所有已加载的 content widget 缓存在 this.content_buffer 对象中(键为 name
  • 默认不重复加载(除非设置 refresh: true
  • 删除标签时自动清理缓存

提升性能,避免频繁重建复杂组件。


使用示例

基本用法

var tabpanel = new bricks.TabPanel({
  tab_pos: 'top',
  items: [
    {
      name: 'home',
      label: '首页',
      content: { widgettype: 'Text', text: '欢迎来到首页' }
    },
    {
      name: 'settings',
      label: '设置',
      icon: 'icon-gear',
      removable: true,
      content: { widgettype: 'Form', fields: [...] }
    }
  ]
});

document.body.appendChild(tabpanel.get_dom());

监听切换事件

tabpanel.bind('switch', function(activeWidget) {
  console.log('切换到了:', activeWidget);
});

// 在内容组件中监听激活事件
var dashboardWidget = {
  widgettype: 'Dashboard',
  init: function() {
    this.bind('active', function() {
      this.loadData(); // 仅在显示时加载数据
    });
  }
};

注册信息

bricks.Factory.register('TabPanel', bricks.TabPanel);

可通过工厂方式创建:

bricks.widgetBuild({ widgettype: 'TabPanel', ... }, parent);

调试信息

  • 重复点击相同标签:输出调试日志
  • 内容构建失败:记录错误日志
  • 未匹配的点击事件:提示“无响应”

使用 bricks.debug() 输出信息(生产环境建议关闭)


注意事项

  1. name 字段必须唯一,否则缓存和查找将出错。
  2. content 必须合法,确保能被 widgetBuild 正确解析。
  3. 若需实时刷新内容,请设置 refresh: true
  4. 移除标签不会销毁 widget但会清除缓存防止内存泄漏。

版本兼容性

  • 依赖 bricks.Layout, bricks.Toolbar, bricks.Filler, bricks.VBox
  • 需支持 ES6 class 语法
  • 异步加载依赖 Promise 环境

推荐场景:后台管理系统、多文档界面、配置面板切换等需要标签式导航的 UI 场景。