From 725fc442f7859727d2ec93e5bbd86be704dfeb3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B4=A4=E5=BF=83?= <3277200+sentsim@users.noreply.github.com> Date: Wed, 5 Mar 2025 19:37:39 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E5=86=99=20tabs=20?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=A1=B5=E7=BB=84=E4=BB=B6=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.layui/prompt.txt | 2 +- docs/tabs/detail/demo.md | 34 ++- docs/tabs/detail/options.md | 133 ++++++++--- docs/tabs/examples/beforeChange.md | 44 ++++ docs/tabs/examples/beforeClose.md | 44 ++++ docs/tabs/examples/card.md | 4 +- docs/tabs/examples/custom.md | 5 +- docs/tabs/examples/demo.md | 90 +++++-- docs/tabs/examples/trigger.md | 43 ++++ docs/tabs/index.md | 369 +++++++++++++++++++++++------ 10 files changed, 625 insertions(+), 143 deletions(-) create mode 100644 docs/tabs/examples/beforeChange.md create mode 100644 docs/tabs/examples/beforeClose.md create mode 100644 docs/tabs/examples/trigger.md diff --git a/docs/.layui/prompt.txt b/docs/.layui/prompt.txt index e64eee10..7ff69634 100644 --- a/docs/.layui/prompt.txt +++ b/docs/.layui/prompt.txt @@ -1,7 +1,7 @@ > 自动生成组件文档提示词 # 角色 -你是一位专业级的前端专家,能够高效、准确地为 JavaScript 组件代码生成对应的接口文档,并且严格遵循给定的模板规则。 +你是一位顶级的前端开发专家,能够高效、准确地为 JavaScript 组件代码生成对应的接口文档,并且严格遵循给定的模板规则。 ## 组件 本次生成的组件名称为: input (统一简称为 MOD_NAME) diff --git a/docs/tabs/detail/demo.md b/docs/tabs/detail/demo.md index a46dd138..94674a32 100644 --- a/docs/tabs/detail/demo.md +++ b/docs/tabs/detail/demo.md @@ -1,4 +1,6 @@ -
动态操作
+
+
   
 
-

方法渲染

+

方法渲染

即通过方法设置 tabs 标签,而非默认的自动渲染页面中的 `class="layui-tabs"` 的容器模板。 -
+
   
 
-

卡片风格

+

卡片风格

-
+
   
 
-

HASH 状态匹配

+

自定义事件

+ +
+  
+
+ +

通过 HASH 匹配选中标签

切换 tabs 标签项后,地址栏同步 `hash` 值,当页面刷新时,tabs 仍保持对应的切换状态。 -
+
   
 
-

标签嵌套

+

标签嵌套

-
+
   
 
-

给任意元素添加 Tab 功能

+

给任意元素绑定 tabs 切换功能

-
+
   
diff --git a/docs/tabs/detail/options.md b/docs/tabs/detail/options.md
index 45401761..37b092b4 100644
--- a/docs/tabs/detail/options.md
+++ b/docs/tabs/detail/options.md
@@ -11,63 +11,87 @@
       描述
       类型
       默认值
-     
+    
   
   
     
 elem
 
-  
-绑定元素选择器或 DOM 对象
+
+组件渲染指定的目标元素选择器或 DOM 对象
 
 
 string/DOM
 -
     
     
-header
+    
+id
 
-  
-选项卡的标题列表,可以是一个包含标题文本的数组,也可以是一个包含标题对象的数组。标题对象支持以下属性:
-- `title` 标题文本
-- `id` 标题唯一索引
-- `disabled` 是否禁用
+
+组件渲染的唯一实例 ID
 
 
-array
+string
 -
     
     
-body
+className
 
-  
-选项卡的内容列表,可以是一个包含内容文本的数组,也可以是一个包含内容对象的数组。内容对象支持以下属性:
-- `content` 内容文本
-- `id` 内容唯一索引
+
+给主容器追加 CSS 类名,以便自定义样式
 
 
-array
+string
 -
     
     
+trigger
+
+
+标签切换的触发事件
+
+
+boolean
+
+
+`click`
+
+
+    
+    
+headerMode
+
+
+标签头部的显示模式。可选值有:
+
+- `auto` 自动模式,根据标签头部是否溢出自动显示不同模式
+- `scroll` 始终滚动模式
+- `normal` 始终常规模式,不渲染头部滚动结构
+
+
+string
+
+
+`auto`
+
+
+    
+    
 index
 
-  
-初始选中的选项卡索引
+
+初始选中的标签索引或标签 `lay-id` 属性值
 
 
 number
-
-
-`0`
-
-
+-
     
     
 closable
 
-  
-是否允许选项卡被关闭
+
+是否开启标签项关闭功能
 
 
 boolean
@@ -78,21 +102,58 @@
 
     
     
-headerMode
-
-  
-选项卡标题栏的展现模式。可选值:
-- `default` 默认模式
-- `brief` 简约模式
-- `card` 卡片模式
+header
+
+
+设置标签头部列表,通常在「非自动渲染」的场景下使用:
+
+**1. 方法渲染**
+
+若 `header` 传入一个数组,且成员值为对象,即为方法渲染时传入的头部列表数据。如:
+
+```js
+header: [
+  { title: 'Tab1' }, // 除 `title` 为必传项外,也可传入其他任意字段。
+  { title: 'Tab2' }
+]
+```
+
+**2. 任意元素渲染**
+
+若 `header` 传入一个数组,则成员值为元素选择器,即为绑定标签头部列表元素。如:
+
+```js
+header: ['#tabsHeader', '>li'],
+```
 
 
-string
-
+    
+    
+body
+
 
-`default`
+设置标签内容列表,通常在「非自动渲染」的场景下使用:
+
+**1. 方法渲染**
+
+若 `body` 传入一个数组,且成员值为对象,即为方法渲染时传入的标签内容列表数据。如:
+
+```js
+body: [
+  { content: 'Tab1' }, // `content` 为必传项
+  { content: 'Tab2' }
+]
+```
+
+**2. 任意元素渲染**
+
+若 `body` 传入一个数组,则成员值为元素选择器,即为绑定标签内容列表元素。如:
+
+```js
+body: ['#tabsBody', '>div'],
+```
 
 
     
   
-
\ No newline at end of file
+
diff --git a/docs/tabs/examples/beforeChange.md b/docs/tabs/examples/beforeChange.md
new file mode 100644
index 00000000..c9a53b9a
--- /dev/null
+++ b/docs/tabs/examples/beforeChange.md
@@ -0,0 +1,44 @@
+
+
    +
  • Tab1
  • +
  • Tab2
  • +
  • Tab3
  • +
  • Tab4
  • +
  • Tab5
  • +
  • Tab6
  • +
+
+
Tab Content-1
+
Tab Content-2
+
Tab Content-3
+
Tab Content-4
+
Tab Content-5
+
Tab Content-6
+
+
+ +本示例演示:切换标签时,弹出确认提示。 + + + diff --git a/docs/tabs/examples/beforeClose.md b/docs/tabs/examples/beforeClose.md new file mode 100644 index 00000000..eecc5749 --- /dev/null +++ b/docs/tabs/examples/beforeClose.md @@ -0,0 +1,44 @@ +
+
    +
  • Tab1
  • +
  • Tab2
  • +
  • Tab3
  • +
  • Tab4
  • +
  • Tab5
  • +
  • Tab6
  • +
+
+
Tab Content-1
+
Tab Content-2
+
Tab Content-3
+
Tab Content-4
+
Tab Content-5
+
Tab Content-6
+
+
+ +本示例演示:删除标签之前,弹出确认提示。 + + + diff --git a/docs/tabs/examples/card.md b/docs/tabs/examples/card.md index ba3545cb..a538c9a7 100644 --- a/docs/tabs/examples/card.md +++ b/docs/tabs/examples/card.md @@ -1,4 +1,4 @@ -

普通卡片:

+#### 普通卡片
    @@ -19,7 +19,7 @@
-

边框卡片:

+#### 边框卡片
    diff --git a/docs/tabs/examples/custom.md b/docs/tabs/examples/custom.md index c18ba0f2..f3ace3cf 100644 --- a/docs/tabs/examples/custom.md +++ b/docs/tabs/examples/custom.md @@ -24,10 +24,7 @@ layui.use(function(){ tabs.render({ elem: '#demoTabs3', header: ['#demoTabsHeader', '>button'], - body: ['#demoTabsBody', '>.test-item'], - change: function(obj) { - console.log(obj); - } + body: ['#demoTabsBody', '>.test-item'] }); }); diff --git a/docs/tabs/examples/demo.md b/docs/tabs/examples/demo.md index 7e8e9e22..ebcd7daa 100644 --- a/docs/tabs/examples/demo.md +++ b/docs/tabs/examples/demo.md @@ -1,6 +1,6 @@
      -
    • Tab1
    • +
    • Tab1
    • Tab2
    • Tab3
    • Tab4
    • @@ -8,7 +8,7 @@
    • Tab6
    -
    Tab Content-1
    +
    Tab Content-1
    Tab Content-2
    Tab Content-3
    Tab Content-4
    @@ -17,6 +17,8 @@
    +🔔 操作提示:在「标签头部」点击鼠标右键,可开启标签操作的更多实用演示 +
    @@ -27,25 +29,81 @@ +``` + +#### 3. 为任意元素渲染 tabs 功能 + +当 `header` 和 `body` 参数传入元素选择器时,可为任意元素绑定标签切换功能。 + +```js +// 给任意元素绑定 Tab 功能 +tabs.render({ + elem: '#demoTabs3', // 目标主容器选择器 + header: ['#demoTabsHeader', '>button'], // 标签头部主元素选择器、标签头部列表选择器 + body: ['#demoTabsBody', '>.test-item'] // 标签内容主元素选择器、标签内容列表选择器 +}); +``` + +具体用法可直接参考上述示例:[给任意元素绑定 tabs 切换功能](#demo-custom) + + +

    属性

    {{- d.include("/tabs/detail/options.md") }}
    -

    新增标签

    +

    新增标签

    -`tabs.add(id, options);` +`tabs.add(id, opts)` -- 参数 `id` : tabs 容器的唯一 id 标识 -- 参数 `options` : 标签配置项 - ```js - { - title: '标题', // 标签标题 - content: '内容', // 标签内容 - id: 'xxx', // 标签的 lay-id 属性值 - mode: 'append', // 插入模式。可选值: append/prepend/curr - unclosed: true, // 是否禁止关闭。默认 false - done: function(obj){} // 标签添加完毕的回调 - } - ``` +- 参数 `id` : 组件的实例 ID +- 参数 `opts` : 标签配置项。可选项详见下表 -

    关闭标签

    +| opts | 描述 | 类型 | 默认值 | +| --- | --- | --- | --- | +| title | 标签标题。必填项 | string | - | +| content | 标签内容。必填项 | string | - | +| id | 标签的 `lay-id` 属性值 | string | - | +| index | 活动标签的索引或 `lay-id` 属性值,默认取当前选中标签的索引 | number | - | +| mode | 标签的插入方式。支持以下可选值:
    • `append` 插入标签到最后
    • `prepend` 插入标签到最前
    • `before` 在活动标签前插入
    • `after` 在活动标签后插入
    | string | `append` | +| closable | 标签是否可关闭。初始值取决于 `options.closable` | boolean | `false` | +| headerItem | 自定义标签头部元素,如 `headerItem: '
  • '` | string | - | +| bodyItem | 自定义标签内容元素,如 `bodyItem: '
    '` | string | - | +| done | 标签添加成功后执行的回调函数 | Function | - | -`tabs.close(id, index);` +该方法用于给对应的 tabs 实例新增一个标签 -- 参数 `id` : tabs 容器的唯一 id 标识 -- 参数 `index` : 标签项的索引或 lay-id 属性值 +```js +tabs.add('test', { + title: 'New Tab 1', + content: 'New Tab Content 1', +}); +``` -

    批量关闭标签

    +

    关闭标签

    -`tabs.closeMore(id, type, index);` +`tabs.close(id, index, force)` -- 参数 `id` : tabs 容器的唯一 id 标识 -- 参数 `type` : 关闭类型。可选值: - - `'all'` : 关闭所有标签 - - `'other'` : 关闭其他标签 - - `'left'` : 关闭左侧标签 - - `'right'` : 关闭右侧标签 -- 参数 `index` : 标签项的索引或 lay-id 属性值,用于定位基准点 +- 参数 `id` : 组件的实例 ID +- 参数 `index` : 标签索引或标签的 `lay-id` 属性值 +- 参数 `force` : 是否强制关闭。若设置 `true` 将忽略 `beforeClose` 事件行为。默认 `false` -

    切换标签

    +该方法用于关闭指定的标签项。 -`tabs.change(id, index);` +```js +tabs.close('test', 3); // 关闭索引为 3 的标签 +tabs.close('test', 3, true); // 强制关闭索引为 3 的标签 +tabs.close('test', 'abc'); // 关闭 lay-id="abc" 的标签 +``` -- 参数 `id` : tabs 容器的唯一 id 标识 -- 参数 `index` : 标签项的索引或 lay-id 属性值 +

    批量关闭标签

    -

    获取标签信息

    +`tabs.closeMult(id, mode, index)` -`tabs.data(id);` +- 参数 `id` : 组件的实例 ID +- 参数 `mode` : 关闭方式。支持以下可选值: -- 参数 `id` : tabs 容器的唯一 id 标识 -- 返回值:包含当前标签页信息的对象 - ```js - { - index: 0, // 当前标签项的索引 - prevIndex: -1, // 上一个标签项的索引 - headerElem: {}, // 当前标签头部元素 - bodyElem: {} // 当前标签内容元素 - } - ``` +| mode | 描述 | +| --- | --- | +| other | 关闭除当前标签外的所有标签 | +| right | 关闭当前标签及右侧标签 | +| all | 关闭所有标签 | -

    获取标签头部项

    +- 参数 `index` : 活动标签的索引或 `lay-id` 属性值,默认取当前选中标签的索引。一般用于标签右键事件。 -`tabs.headerItem(id, index);` +该方法用于批量关闭标签。 -- 参数 `id` : tabs 容器的唯一 id 标识 -- 参数 `index` : 标签项的索引或 lay-id 属性值 -- 返回值:标签头部项的 DOM 元素 +```js +tabs.closeMult(id, 'other'); // 关闭除当前标签外的所有标签 +tabs.closeMult(id, 'other', 3); // 关闭除索引为 3 的标签外的所有标签 +tabs.closeMult(id, 'right'); // 关闭当前标签及右侧标签 +tabs.closeMult(id, 'right', 3); // 关闭索引为 3 的标签的右侧所有标签 +tabs.closeMult(id, 'all'); // 关闭所有标签 +``` -

    获取标签内容项

    +

    切换标签

    -`tabs.bodyItem(id, index);` +`tabs.change(id, index, force)` -- 参数 `id` : tabs 容器的唯一 id 标识 -- 参数 `index` : 标签项的索引或 lay-id 属性值 -- 返回值:标签内容项的 DOM 元素 +- 参数 `id` : 组件的实例 ID +- 参数 `index` : 标签索引或标签的 `lay-id` 属性值 +- 参数 `force` : 是否强制切换。若设置 `true` 将忽略 `beforeChange` 事件行为。默认 false -

    重新调整视图

    +该方法用于切换到指定的标签项。 -`tabs.setView(id);` +```js +tabs.change('test', 3); // 切换到索引为 3 的标签 +tabs.change('test', 3, true); // 强制切换到索引为 3 的标签 +tabs.change('test', 'abc'); // 切换到 lay-id="abc" 的标签 +tabs.change('test', 'abc', true); // 强制切换到 lay-id="abc" 的标签 +``` -- 参数 `id` : tabs 容器的唯一 id 标识 -- 描述:用于重新调整标签视图结构,如在容器尺寸变化时调用 +

    获取标签相关数据

    + +`tabs.data(id)` + +- 参数 `id` : 组件的实例 ID + +该方法用于获取标签相关数据。 + +```js +var data = tabs.data('test'); +console.log(data); +``` + +返回的 `data` 包含以下字段: + +```js +{ + options, // 标签配置信息 + container, // 标签容器的相关元素 + thisHeaderItem, // 当前标签头部项 + thisBodyItem, // 当前标签内容项 + index, // 当前标签索引 + length, // 当前标签数 +} +``` + +

    获取标签头部项

    + +`tabs.getHeaderItem(id, index)` + +- 参数 `id` : 组件的实例 ID +- 参数 `index` : 标签索引或标签的 `lay-id` 属性值 + +该方法用于获取标签头部项元素。 + +```js +var headerItem = tabs.getHeaderItem('test', 3); // 获取索引为 3 的标签头部项元素 +``` + +

    获取标签内容项

    + +`tabs.getBodyItem(id, index)` + +- 参数 `id` : 组件的实例 ID +- 参数 `index` : 标签索引或标签的 `lay-id` 属性值 + +该方法用于获取标签内容项元素。 + +```js +var bodyItem = tabs.getBodyItem('test', 3); // 获取索引为 3 的标签内容项元素 +``` + +

    刷新标签视图

    + +`tabs.refresh(id)` + +- 参数 `id` : 组件的实例 ID + +该方法用于刷新标签视图,如标签头部的滚动结构等,一般通过非 API 方式对标签进行修改的场景中使用。 + +```js +tabs.refresh('test'); // 刷新标签视图 +``` + + +

    事件

    + +`tabs.on('event(id)', callback)` + +- 参数介绍详见 `component` 组件的[事件定义](../component/#on)。以下是组件提供的 `event` 事件列表 + +| event | 描述 | +| --- | --- | +| [afterRender](#on-afterRender) | 标签渲染后的事件 | +| [beforeChange](#on-beforeChange) | 标签切换前的事件 | +| [afterChange](#on-afterChange) | 标签切换后的事件 | +| [beforeClose](#on-beforeClose) | 标签关闭前的事件 | +| [afterClose](#on-afterClose) | 标签关闭后的事件 | + + +

    标签渲染后的事件

    + +`tabs.on('afterRender(id)', callback)` + +标签渲染成功后触发。 + +```js +tabs.on('afterRender(testID)', function(data){ + console.log(data); // 标签相关数据 +}); +``` + +

    标签切换前的事件

    + +`tabs.on('beforeChange(id)', callback)` + +标签在切换前触发,通过在事件中 `return false` 可阻止默认标签切换行为。通常和 `tabs.change()` 方法搭配使用。 + +```js +// tabs 切换前的事件 +tabs.on(`beforeChange(testID)`, function(data) { + console.log(data); // 标签相关数据 + console.log(data.from.index); // 切换前的选中标签索引 + console.log(data.from.headerItem); // 切换前的选中标签头部项 + console.log(data.to.index); // 切换后的选中标签索引 + console.log(data.to.headerItem); // 切换后的选中标签头部项 + + // 阻止标签默认关闭 + return false; +}); +``` + +示例演示: + +
    +  
    +
    + +

    标签切换后的事件

    + +`tabs.on('afterChange(id)', callback)` + +标签成功切换后触发。 + +```js +// tabs 切换后的事件 +tabs.on('afterChange(testID)', function(data) { + console.log(data); +}); +``` + +

    标签关闭前的事件

    + +`tabs.on('beforeClose(id)', callback)` + +标签在切换前触发,通过在事件中 `return false` 可阻止默认标签切换行为。通常和 `tabs.close()` 方法搭配使用。 + +
    +  
    +
    + +

    标签关闭后的事件

    + +`tabs.on('afterClose(id)', callback)` + +标签被成功关闭后触发。 + +```js +// tabs 关闭后的事件 +tabs.on('afterClose(testID)', function(data) { + console.log(data); +}); +``` + +## 💖 心语 + +tabs 是通过 component 重构的首个组件,它来自于最早试图发布的 Layui 3.0(后因为 3.0 技术路线的变化,而整理放至 2.10+ 版本中),目的是将 element 模块中的 tab 组件进行解耦,增强其可扩展性。为了给开发者必要的时间缓冲,我们会将旧 tab 组件仍然保留在后续的若干版本中,但会在合适的时机对旧 tab 组件进行剔除,建议开发者尽量提前过渡到当前新的 tabs 组件。