关于 syncfusion-react-tabs
这是一份使用 Syncfusion React Tab 组件构建标签页界面的参考技能,涵盖初始化、内容渲染、无障碍支持、自定义及程序化控制。
主要功能
- 01配置标签标题与溢出模式
- 02选择内容渲染方式
- 03通过拖放重排标签
- 04支持无障碍与本地化
- 05通过组件方法控制标签
适用场景
- 01构建自适应标签页视图
- 02切换标签时保留状态
- 03允许用户重排标签区
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ syncfusion/ react-ui-components-skills --skill syncfusion-react-tabs安装后在 Claude Code 中输入/syncfusion-react-tabs确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/accessibility-localization.mdcontent-rendering.mddrag-drop-reordering.mdgetting-started.mdheader-styling.mdorientation-overflow.md详细介绍
在 Syncfusion React 中实现选项卡
Tab 组件会将相关内容组织到带有标题的选项卡区域中,让用户能够在不同视图之间切换。本指南将全面介绍设置、自定义、内容渲染策略、API 方法、事件、无障碍访问、动画、持久化,以及拖放重新排序等高级功能。
目录
何时使用此技能
- 创建选项卡式界面,使用基于标题的导航
- 将内容组织为逻辑分区或视图
- 构建响应式布局,处理可滚动或弹出式溢出内容
- 自定义标题样式和图标位置
- 管理内容渲染性能(延迟加载、动态渲染或初始渲染)
- 实现拖放选项卡重新排序,让用户自定义布局
- 添加本地化支持,以适用于国际化应用
- 确保符合无障碍访问规范(WCAG、ARIA、键盘导航)
- 使用自定义 CSS 或主题自定义选项卡样式
- 以编程方式管理选项卡(添加、移除、选择、隐藏/显示)
- 处理选项卡相关事件(选择、拖放、添加、移除)
- 通过状态持久化保留用户偏好设置
- 实现流畅的动画和过渡效果
组件概述
Tab 组件是一种导航控件,用于显示按选项卡组织的内容。每个选项卡都包含一个标题及其关联内容。选项卡支持:
- 多个标题位置(顶部、底部、左侧、右侧)
- 溢出处理(可滚动导航或弹出模式)
- 灵活的内容渲染(按需、动态或初始加载)
- 拖放重新排序,实现交互式选项卡管理
- 完整的无障碍访问支持,包括 ARIA 属性和键盘导航
- 通过 CSS 和主题选项进行广泛的自定义
- 通过本地化 API 实现国际化
- 用于内容过渡的动画效果
- 跨页面重新加载的状态持久化
- 用于安全性的 HTML 清理
文档与导航指南
入门
📄 阅读: references/getting-started.md
- 软件包依赖项和安装
- Vite 和 Create React App 设置
- CSS 导入和主题配置
- 使用 JSON 项目进行基本选项卡初始化
- 最小可运行示例及应用运行方法
何时阅读: 从这里开始,在 React 应用中设置基本的 Tab 组件。
标题样式与自定义
📄 阅读: references/header-styling.md
- 内置标题样式类(e-fill、e-background、e-accent)
- 图标位置选项(左侧、右侧、顶部、底部)
- 使用 CSS 类自定义图标和标题
- 标题样式示例代码
- 内容和悬停状态样式
何时阅读: 需要自定义选项卡标题外观、添加图标或应用预定义样式时,请参阅此部分。
方向与溢出模式
📄 阅读: references/orientation-overflow.md
- 标题放置位置(顶部、底部、左侧、右侧)
- 带导航箭头的可滚动模式
- 带下拉显示的弹出模式
- 触摸和滑动支持
- 宽度限制和响应式行为
何时阅读: 需要控制标题位置、处理大量选项卡导致的溢出,或构建响应式布局时,请参阅此部分。
内容渲染策略
📄 阅读: references/content-rendering.md
- 按需渲染(延迟加载,默认模式)
- 为状态隔离的选项卡动态渲染
- 初始渲染以保留状态
- 性能与状态方面的考量
- 选择合适的渲染模式
何时阅读: 优化选项卡内容的性能,或在切换选项卡时保留用户交互状态时,请阅读此文档。
拖放重排
📄 阅读: references/drag-drop-reordering.md
- 使用 allowDragAndDrop 启用拖放
- 处理拖动事件(onDragStart、dragging、dragged)
- 禁止特定项目进行拖放
- 选项卡之间拖放
- 将选项卡拖动到外部来源(TreeView)
- 拖动区域限制
何时阅读: 允许用户重新排列选项卡,或将选项卡拖动与其他组件集成时,请阅读此文档。
无障碍与本地化
📄 阅读: references/accessibility-localization.md
- 符合 WCAG 2.2 和 Section 508 标准
- 选项卡的 ARIA 属性和角色
- 键盘导航(箭头键、Home、End、Enter、Escape)
- 屏幕阅读器支持
- 使用 L10n 类进行本地化
- 从右到左(RTL)语言支持
何时阅读: 构建无障碍应用程序或支持多种语言时,请阅读此文档。
快速入门示例
以下是一个最简 Tab 组件配置:
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
import '@syncfusion/ej2-base/styles/tailwind3.css';
import '@syncfusion/ej2-buttons/styles/tailwind3.css';
import '@syncfusion/ej2-popups/styles/tailwind3.css';
import '@syncfusion/ej2-react-navigations/styles/tailwind3.css';
export default function TabExample() {
const tabItems = [
{
header: { text: 'Home' },
content: 'Welcome to the home tab'
},
{
header: { text: 'Profile' },
content: 'User profile information'
},
{
header: { text: 'Settings' },
content: 'Application settings'
}
];
return (
<TabComponent>
<TabItemsDirective>
{tabItems.map((item, index) => (
<TabItemDirective key={index} header={item.header} content={item.content} />
))}
</TabItemsDirective>
</TabComponent>
);
}
常见模式
模式 1:带图标的样式化选项卡
<TabComponent className="e-fill">
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Home', iconCss: 'e-icons e-home' }}
content="Home content"
/>
<TabItemDirective
header={{ text: 'Profile', iconCss: 'e-icons e-user' }}
content="Profile content"
/>
</TabItemsDirective>
</TabComponent>
模式 2:左侧的垂直选项卡
<TabComponent headerPlacement="Left">
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
模式 3:延迟加载内容(默认)
<TabComponent>
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Lazy Tab' }}
content={() => <ExpensiveComponent />}
/>
</TabItemsDirective>
</TabComponent>
模式 4:可拖动选项卡
<TabComponent allowDragAndDrop={true}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
关键属性概览
| 属性 | 类型 | 默认值 | 用途 |
|---|---|---|---|
headerPlacement | String | 'Top' | 选项卡标题的位置:Top、Bottom、Left、Right |
overflowMode | String | 'Scrollable' | 溢出处理方式:Scrollable 或 Popup |
loadOn | String | 'Demand' | 内容渲染方式:Demand、Dynamic 或 Init |
allowDragAndDrop | Boolean | false | 启用拖放以重新排列选项卡 |
showCloseButton | Boolean | false | 在选项卡标题上显示关闭按钮 |
locale | String | 'en-US' | 本地化区域代码(例如,'fr-FR') |
width | String/Number | '100%' | 选项卡容器宽度 |
height | String/Number | 'auto' | 选项卡容器高度 |
heightAdjustMode | String | 'Content' | 高度调整模式:None、Auto、Content、Fill |
selectedItem | Number | 0 | 当前活动选项卡的索引 |
enablePersistence | Boolean | false | 在重新加载后保留选中的选项卡状态 |
enableHtmlSanitizer | Boolean | true | 清理 HTML 内容以确保安全 |
cssClass | String | '' | 应用于组件的自定义 CSS 类 |
enableRtl | Boolean | false | 启用从右到左的布局 |
scrollStep | Number | null | 使用滚动箭头时的滚动距离 |
reorderActiveTab | Boolean | true | 调整顺序,使活动选项卡显示在标题区域 |
clearTemplates | Boolean | true | 项目动态变化时清除模板 |
dragArea | String | null | 限制选项卡重排的拖动区域 |
swipeMode | String | 'Both' | 滑动检测方式:Both、Touch、Mouse、None |
animation | TabAnimationSettingsModel | Default | 选项卡切换的动画设置 |
方法与 API 参考
addTab(items, index)
向 Tab 组件添加新项目。项目会插入指定索引处。
参数:
items- 要添加的TabItemModel对象数组index(可选)- 项目插入的位置。默认值为 0。
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function AddTabExample() {
const tabRef = useRef(null);
const handleAddTab = () => {
const newItems = [
{
header: { text: 'New Tab' },
content: 'This is dynamically added content'
}
];
// Add at the end (index 2 if there are 2 existing tabs)
tabRef.current.addTab(newItems, 2);
};
return (
<div>
<button onClick={handleAddTab}>Add Tab</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
removeTab(index)
移除指定索引处的选项卡项目。
参数:
index- 要移除的选项卡索引
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RemoveTabExample() {
const tabRef = useRef(null);
const handleRemoveTab = (tabIndex) => {
tabRef.current.removeTab(tabIndex);
};
return (
<div>
<button onClick={() => handleRemoveTab(1)}>Remove Tab 2</button>
<TabComponent ref={tabRef} showCloseButton={true}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
select(args, event)
按索引或 DOM 元素选择选项卡。以编程方式切换到其他选项卡。
参数:
args- 要选择的选项卡的索引(数字)或 HTMLElementevent(可选)- DOM 事件对象
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function SelectTabExample() {
const tabRef = useRef(null);
const handleSelectTab = (index) => {
tabRef.current.select(index);
};
return (
<div>
<div>
<button onClick={() => handleSelectTab(0)}>Select Tab 1</button>
<button onClick={() => handleSelectTab(1)}>Select Tab 2</button>
<button onClick={() => handleSelectTab(2)}>Select Tab 3</button>
</div>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
enableTab(index, value)
启用或禁用指定的选项卡项。已禁用的选项卡无法选择,但仍会显示。
参数:
index- 要启用或禁用的选项卡索引value- 布尔值。true表示启用,false表示禁用
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function EnableTabExample() {
const tabRef = useRef(null);
const toggleTabEnabled = (index) => {
const isCurrentlyEnabled = !tabRef.current.items[index].isDisabled;
tabRef.current.enableTab(index, isCurrentlyEnabled);
};
return (
<div>
<button onClick={() => toggleTabEnabled(1)}>Toggle Tab 2 Enable</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
hideTab(index, value)
显示或隐藏指定索引处的选项卡项。隐藏的选项卡会从 DOM 中移除。
参数:
index- 要显示或隐藏的选项卡索引value(可选)- 布尔值。true表示隐藏,false表示显示。默认为true
返回值: void
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function HideTabExample() {
const tabRef = useRef(null);
const [visibleTabs, setVisibleTabs] = useState([true, true, true]);
const toggleTabVisibility = (index) => {
const newVisibleTabs = [...visibleTabs];
newVisibleTabs[index] = !newVisibleTabs[index];
setVisibleTabs(newVisibleTabs);
tabRef.current.hideTab(index, !newVisibleTabs[index]);
};
return (
<div>
<div>
<button onClick={() => toggleTabVisibility(0)}>
Toggle Tab 1 Visibility
</button>
<button onClick={() => toggleTabVisibility(1)}>
Toggle Tab 2 Visibility
</button>
</div>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
getItemIndex(tabItemId)
根据 ID 获取选项卡项的索引。
参数:
tabItemId- 选项卡项的 ID
返回值: number - 选项卡的索引;如果未找到,则返回 -1
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function GetItemIndexExample() {
const tabRef = useRef(null);
const findTabIndex = () => {
const itemId = 'tab_2';
const index = tabRef.current.getItemIndex(itemId);
console.log(`Tab with ID '${itemId}' is at index: ${index}`);
};
return (
<div>
<button onClick={findTabIndex}>Find Tab Index</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective id="tab_1" header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective id="tab_2" header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective id="tab_3" header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
refresh()
刷新整个 Tab 组件。在动态更改项或属性后很有用。
参数: 无
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RefreshTabExample() {
const tabRef = useRef(null);
const handleRefresh = () => {
tabRef.current.refresh();
console.log('Tab component refreshed');
};
return (
<div>
<button onClick={handleRefresh}>Refresh Tab</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
refreshActiveTab()
仅刷新当前活动选项卡的内容,不会重新加载其他选项卡。
参数: 无
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RefreshActiveTabExample() {
const tabRef = useRef(null);
const handleRefreshActive = () => {
tabRef.current.refreshActiveTab();
console.log('Active tab content refreshed');
};
return (
<div>
<button onClick={handleRefreshActive}>Refresh Active Tab</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Dynamically updated content" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
refreshActiveTabBorder()
刷新活动选项卡的视觉指示器(下划线/边框)。在样式更改后很有用。
参数: 无
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RefreshBorderExample() {
const tabRef = useRef(null);
const handleRefreshBorder = () => {
tabRef.current.refreshActiveTabBorder();
};
return (
<div>
<button onClick={handleRefreshBorder}>Refresh Border</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
refreshOverflow()
重新排列并调整 Tab 标题,以适应可用宽度,而无需重新渲染整个组件。适用于响应式布局。
参数: 无
返回值: void
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RefreshOverflowExample() {
const tabRef = useRef(null);
const [tabCount, setTabCount] = useState(3);
const handleWindowResize = () => {
if (tabRef.current) {
tabRef.current.refreshOverflow();
}
};
React.useEffect(() => {
window.addEventListener('resize', handleWindowResize);
return () => window.removeEventListener('resize', handleWindowResize);
}, []);
const addMoreTabs = () => {
const newTab = {
header: { text: `Tab ${tabCount + 1}` },
content: `Content ${tabCount + 1}`
};
tabRef.current.addTab([newTab]);
setTabCount(tabCount + 1);
tabRef.current.refreshOverflow();
};
return (
<div>
<button onClick={addMoreTabs}>Add Tab & Refresh Overflow</button>
<TabComponent ref={tabRef} width="100%">
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
disable(value)
禁用或启用整个 Tab 组件。
参数:
value- 布尔值。true表示禁用,false表示启用
返回值: void
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function DisableTabExample() {
const tabRef = useRef(null);
const [isDisabled, setIsDisabled] = useState(false);
const toggleDisable = () => {
tabRef.current.disable(!isDisabled);
setIsDisabled(!isDisabled);
};
return (
<div>
<button onClick={toggleDisable}>
{isDisabled ? 'Enable' : 'Disable'} Tab Component
</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
destroy()
从 DOM 中移除该组件,并分离所有事件处理程序、属性和类。
参数: 无
返回值: void
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function DestroyTabExample() {
const tabRef = useRef(null);
const handleDestroy = () => {
tabRef.current.destroy();
console.log('Tab component destroyed');
};
return (
<div>
<button onClick={handleDestroy}>Destroy Tab</button>
<TabComponent ref={tabRef}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
事件与事件参数
Tab 组件提供全面的事件支持,用于处理用户交互和组件状态更改。
selected
在选项卡项被选中后触发。用于在用户切换到其他选项卡时执行操作。
事件参数: SelectEventArgs
SelectEventArgs 属性:
selectedIndex(number)- 新选中选项卡的索引selectedItem(HTMLElement)- 所选选项卡的 DOM 元素selectedContent(HTMLElement)- 所选选项卡的内容区域previousIndex(number)- 上一个选中选项卡的索引previousItem(HTMLElement)- 上一个选项卡的 DOM 元素isInteracted(boolean)- 表示选择是否由用户交互触发(true),而非以编程方式触发(false)isSwiped(boolean)- 表示选择是否由滑动手势触发preventFocus(boolean)- 设置为 true 可阻止选中的选项卡获得焦点cancel(boolean)- 设置为 true 可阻止选择
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function SelectedEventExample() {
const tabRef = useRef(null);
const [selectedIndex, setSelectedIndex] = useState(0);
const handleTabSelected = (args) => {
console.log('Tab selected:', {
selectedIndex: args.selectedIndex,
previousIndex: args.previousIndex,
isInteracted: args.isInteracted,
isSwiped: args.isSwiped
});
setSelectedIndex(args.selectedIndex);
};
return (
<div>
<p>Currently selected tab index: {selectedIndex}</p>
<TabComponent ref={tabRef} selected={handleTabSelected}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
selecting
在选项卡项被选中前触发。可用于在特定条件下阻止选择。
事件参数: SelectingEventArgs(属性与 SelectEventArgs 相同)
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function SelectingEventExample() {
const handleTabSelecting = (args) => {
// Prevent selection of tab at index 1
if (args.selectedIndex === 1) {
console.log('Tab 2 selection prevented');
args.cancel = true;
}
};
return (
<TabComponent selecting={handleTabSelecting}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2 (Locked)' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
);
}
added
在向组件添加新的选项卡项后触发。
事件参数: AddEventArgs
AddEventArgs 属性:
addedItems(TabItemModel[])- 已添加选项卡项的数组name(string)- 事件名称cancel(boolean)- 设置为 true 可阻止该操作
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function AddedEventExample() {
const tabRef = useRef(null);
const handleTabAdded = (args) => {
console.log('Tabs added:', args.addedItems.length);
console.log('First added item header:', args.addedItems[0].header.text);
};
const handleAddTab = () => {
const newItems = [
{
header: { text: 'Newly Added Tab' },
content: 'This tab was added dynamically'
}
];
tabRef.current.addTab(newItems);
};
return (
<div>
<button onClick={handleAddTab}>Add Tab</button>
<TabComponent ref={tabRef} added={handleTabAdded}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
adding
在添加新的选项卡项前触发。可用于在添加前验证或修改选项卡项。
事件参数: AddEventArgs
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function AddingEventExample() {
const tabRef = useRef(null);
const maxTabs = 5;
const handleTabAdding = (args) => {
const totalTabs = tabRef.current.items.length + args.addedItems.length;
if (totalTabs > maxTabs) {
console.log(`Cannot exceed ${maxTabs} tabs`);
args.cancel = true;
}
};
const handleAddTab = () => {
const newItems = [
{
header: { text: `Tab ${tabRef.current.items.length + 1}` },
content: 'New content'
}
];
tabRef.current.addTab(newItems);
};
return (
<div>
<button onClick={handleAddTab}>Add Tab (Max 5)</button>
<TabComponent ref={tabRef} adding={handleTabAdding}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
removed
在选项卡项从组件中移除后触发。
事件参数: RemoveEventArgs
RemoveEventArgs 属性:
removedItem(HTMLElement)- 被移除选项卡的 DOM 元素index(number)- 被移除选项卡的索引name(string)- 事件名称
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RemovedEventExample() {
const tabRef = useRef(null);
const [removedCount, setRemovedCount] = useState(0);
const handleTabRemoved = (args) => {
console.log(`Tab at index ${args.index} was removed`);
setRemovedCount(removedCount + 1);
};
const handleRemoveTab = (index) => {
tabRef.current.removeTab(index);
};
return (
<div>
<p>Tabs removed: {removedCount}</p>
<button onClick={() => handleRemoveTab(0)}>Remove First Tab</button>
<TabComponent ref={tabRef} removed={handleTabRemoved}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
removing
在选项卡项移除前触发。可使用此事件在特定条件下阻止移除。
事件参数: RemoveEventArgs
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RemovingEventExample() {
const handleTabRemoving = (args) => {
const confirmed = window.confirm('Are you sure you want to remove this tab?');
if (!confirmed) {
args.cancel = true;
}
};
return (
<TabComponent removing={handleTabRemoving} showCloseButton={true}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
);
}
onDragStart
在拖动选项卡项前触发。可使用此事件阻止拖动特定选项卡或自定义拖动行为。
事件参数: DragEventArgs
DragEventArgs 属性:
draggedItem(HTMLElement)- 正在拖动的选项卡clonedElement(HTMLElement)- 被拖动元素的克隆event(MouseEvent)- 拖动事件index(number)- 被拖动选项卡的索引cancel(boolean)- 设置为 true 可阻止拖动name(string)- 事件名称target(HTMLElement)- 目标元素droppedItem(HTMLElement)- 被放置到其上的项
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function OnDragStartExample() {
const handleDragStart = (args) => {
// Prevent dragging the first tab (index 0)
if (args.index === 0) {
args.cancel = true;
console.log('First tab cannot be dragged');
}
};
return (
<TabComponent allowDragAndDrop={true} onDragStart={handleDragStart}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1 (Locked)' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
);
}
dragging
在拖动选项卡时触发。
事件参数: DragEventArgs
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function DraggingEventExample() {
const [dragStatus, setDragStatus] = useState('');
const handleDragging = (args) => {
setDragStatus(`Dragging tab at index ${args.index}`);
};
return (
<div>
<p>Drag status: {dragStatus}</p>
<TabComponent allowDragAndDrop={true} dragging={handleDragging}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
dragged
选项卡成功放置到新位置后触发。
事件参数: DragEventArgs
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function DraggedEventExample() {
const [dropMessage, setDropMessage] = useState('');
const handleDragged = (args) => {
setDropMessage(`Tab dropped at new position. Index: ${args.index}`);
console.log('Tab reordered successfully');
};
return (
<div>
<p>{dropMessage}</p>
<TabComponent allowDragAndDrop={true} dragged={handleDragged}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
<TabItemDirective header={{ text: 'Tab 3' }} content="Content 3" />
</TabItemsDirective>
</TabComponent>
</div>
);
}
created
Tab 组件完全渲染并初始化后触发。
事件参数: Event
示例:
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function CreatedEventExample() {
const tabRef = useRef(null);
const handleCreated = () => {
console.log('Tab component created and initialized');
console.log('Total tabs:', tabRef.current.items.length);
};
return (
<TabComponent ref={tabRef} created={handleCreated}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
);
}
destroyed
销毁 Tab 组件并将其从 DOM 中移除时触发。
事件参数: Event
示例:
import React, { useRef, useState } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function DestroyedEventExample() {
const [showTab, setShowTab] = useState(true);
const handleDestroyed = () => {
console.log('Tab component destroyed');
alert('Tab component has been removed from DOM');
};
return (
<div>
<button onClick={() => setShowTab(!showTab)}>
{showTab ? 'Destroy' : 'Create'} Tab
</button>
{showTab && (
<TabComponent destroyed={handleDestroyed}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
)}
</div>
);
}
动画与高级设置
Tab 组件支持动画、HTML 清理和状态持久化等高级功能。
动画配置
使用 animation 属性控制选项卡内容在切换时的过渡效果。
动画设置:
previous- 切换到上一个选项卡时的动画效果next- 切换到下一个选项卡时的动画效果- 每种动画都包含:
effect、duration(ms)、easing
可用的动画效果:
SlideLeftIn- 从右向左滑入SlideRightIn- 从左向右滑入SlideUpIn- 从下向上滑入SlideDownIn- 从上向下滑入FadeIn- 淡入效果FadeOut- 淡出效果FadeZoomIn- 淡入并缩放FadeZoomOut- 淡出并缩放ZoomIn- 放大效果ZoomOut- 缩小效果None- 无动画
示例:自定义动画
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function AnimationExample() {
const tabRef = useRef(null);
const animationSettings = {
previous: { effect: 'SlideLeftIn', duration: 600, easing: 'ease' },
next: { effect: 'SlideRightIn', duration: 600, easing: 'ease' }
};
return (
<TabComponent ref={tabRef} animation={animationSettings}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Twitter' }} content="Twitter is an online social networking service..." />
<TabItemDirective header={{ text: 'Facebook' }} content="Facebook is an online social networking service..." />
<TabItemDirective header={{ text: 'WhatsApp' }} content="WhatsApp Messenger is a proprietary cross-platform instant messaging client..." />
</TabItemsDirective>
</TabComponent>
);
}
示例:禁用动画
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function NoAnimationExample() {
const animationSettings = {
previous: { effect: 'None' },
next: { effect: 'None' }
};
return (
<TabComponent animation={animationSettings}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
);
}
HTML 清理
启用 HTML 清理可防范 XSS 攻击。enableHtmlSanitizer 属性用于控制是否清理不可信的 HTML。
示例:HTML 清理
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function HtmlSanitizationExample() {
return (
<div>
{/* Sanitization enabled (default) - malicious scripts are removed */}
<h2>With Sanitization (Safe)</h2>
<TabComponent enableHtmlSanitizer={true}>
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Safe Content' }}
content="<b>Bold text</b> - This is safe HTML"
/>
<TabItemDirective
header={{ text: 'Dangerous Script' }}
content="<img src=x onerror='alert(\"XSS\")' /> - Script will be removed"
/>
</TabItemsDirective>
</TabComponent>
{/* Sanitization disabled - use only with trusted content */}
<h2>Without Sanitization (Use with Caution)</h2>
<TabComponent enableHtmlSanitizer={false}>
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Trusted Content Only' }}
content="<b>Only use when content is from trusted sources</b>"
/>
</TabItemsDirective>
</TabComponent>
</div>
);
}
状态持久化
enablePersistence 属性允许 Tab 组件在页面重新加载后保留所选选项卡。
示例:状态持久化
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function PersistenceExample() {
return (
<div>
<p>
Select a different tab and refresh the page.
The previously selected tab will be restored.
</p>
<TabComponent enablePersistence={true} selectedItem={0}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'Twitter' }} content="Twitter is an online social networking service that enables users to send and read short 140-character messages..." />
<TabItemDirective header={{ text: 'Facebook' }} content="Facebook is an online social networking service headquartered in Menlo Park, California..." />
<TabItemDirective header={{ text: 'WhatsApp' }} content="WhatsApp Messenger is a proprietary cross-platform instant messaging client for smartphones..." />
</TabItemsDirective>
</TabComponent>
</div>
);
}
持久化状态:
selectedItem- 当前活动选项卡的索引
持久化功能使用浏览器本地存储来保存和恢复状态。
滑动导航
swipeMode 属性用于启用或禁用通过滑动手势进行选项卡导航。此功能对于移动设备和触控界面尤其有用,也可进行自定义以防止误触滑动。
SwipeMode 选项:
Both(默认)- 允许使用触控和鼠标滑动Touch- 仅允许使用触控手势滑动Mouse- 仅允许使用鼠标手势滑动None- 完全禁用滑动导航
示例:禁用滑动,防止误切换选项卡
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function SwipeModeExample() {
return (
<div>
<h3>Form Tab - Swipe Disabled to Prevent Data Loss</h3>
<TabComponent heightAdjustMode='Auto' swipeMode='None'>
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Personal Info' }}
content="Fill out your personal information without accidental swipes"
/>
<TabItemDirective
header={{ text: 'Address' }}
content="Enter your address details"
/>
<TabItemDirective
header={{ text: 'Confirmation' }}
content="Review and confirm your information"
/>
</TabItemsDirective>
</TabComponent>
<h3>Mobile Navigation - Touch Swipe Only</h3>
<TabComponent swipeMode='Touch'>
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Twitter' }}
content="Twitter content - Swipe on mobile only"
/>
<TabItemDirective
header={{ text: 'Facebook' }}
content="Facebook content - Swipe on mobile only"
/>
<TabItemDirective
header={{ text: 'WhatsApp' }}
content="WhatsApp content - Swipe on mobile only"
/>
</TabItemsDirective>
</TabComponent>
</div>
);
}
示例:禁用鼠标滑动,允许触控滑动
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function TouchSwipeExample() {
return (
<TabComponent swipeMode='Touch'>
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Dashboard' }}
content="Dashboard content - Swipe available on touch devices"
/>
<TabItemDirective
header={{ text: 'Analytics' }}
content="Analytics content"
/>
</TabItemsDirective>
</TabComponent>
);
}
标签页滚动步长自定义
scrollStep 属性用于控制点击左右导航箭头时标签页标题滚动的距离(以像素为单位)。当标签页溢出时,可通过此属性微调滚动行为。
示例:自定义滚动步长
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function ScrollStepExample() {
const htmlContent = () => {
return <div>
HyperText Markup Language, commonly referred to as HTML, is the standard markup language used to create web pages.
</div>;
};
const csharpContent = () => {
return <div>
C# is intended to be a simple, modern, general-purpose, object-oriented programming language.
</div>;
};
const javaContent = () => {
return <div>
Java is a set of computer software and specifications developed by Sun Microsystems.
</div>;
};
const vbNetContent = () => {
return <div>
The command-line compiler, VBC.EXE, is installed as part of the freeware .NET Framework SDK.
</div>;
};
const xamarinContent = () => {
return <div>
Xamarin is a software company created in May 2011 by the engineers that created Mono.
</div>;
};
const aspNetcontent = () => {
return <div>
ASP.NET is an open-source server-side web application framework designed for web development.
</div>;
};
const mvcContent = () => {
return <div>
The ASP.NET MVC is a web application framework developed by Microsoft.
</div>;
};
const jsContent = () => {
return <div>
JavaScript (JS) is an interpreted computer programming language.
</div>;
};
return (
<div>
<h3>Tab Scroll Step: 50px per click</h3>
<p>Click the left/right navigation arrows - tabs scroll 50 pixels at a time</p>
<TabComponent height="250px" scrollStep={50}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'HTML' }} content={htmlContent} />
<TabItemDirective header={{ text: 'C#' }} content={csharpContent} />
<TabItemDirective header={{ text: 'Java' }} content={javaContent} />
<TabItemDirective header={{ text: 'VB.Net' }} content={vbNetContent} />
<TabItemDirective header={{ text: 'Xamarin' }} content={xamarinContent} />
<TabItemDirective header={{ text: 'ASP.NET' }} content={aspNetcontent} />
<TabItemDirective header={{ text: 'ASP.NET MVC' }} content={mvcContent} />
<TabItemDirective header={{ text: 'JavaScript' }} content={jsContent} />
</TabItemsDirective>
</TabComponent>
<h3>Tab Scroll Step: 100px per click (Faster)</h3>
<p>Larger scroll step for quicker tab navigation</p>
<TabComponent height="250px" scrollStep={100}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'HTML' }} content={htmlContent} />
<TabItemDirective header={{ text: 'C#' }} content={csharpContent} />
<TabItemDirective header={{ text: 'Java' }} content={javaContent} />
<TabItemDirective header={{ text: 'VB.Net' }} content={vbNetContent} />
<TabItemDirective header={{ text: 'Xamarin' }} content={xamarinContent} />
<TabItemDirective header={{ text: 'ASP.NET' }} content={aspNetcontent} />
<TabItemDirective header={{ text: 'ASP.NET MVC' }} content={mvcContent} />
<TabItemDirective header={{ text: 'JavaScript' }} content={jsContent} />
</TabItemsDirective>
</TabComponent>
</div>
);
}
高级设置:CSS 类和 RTL
自定义 CSS 类
使用 cssClass 属性应用自定义样式:
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
import './CustomTab.css';
export default function CustomCssExample() {
return (
<TabComponent cssClass="custom-tab-theme">
<TabItemsDirective>
<TabItemDirective header={{ text: 'Tab 1' }} content="Content 1" />
<TabItemDirective header={{ text: 'Tab 2' }} content="Content 2" />
</TabItemsDirective>
</TabComponent>
);
}
RTL(从右到左)支持
为阿拉伯语、希伯来语及其他 RTL 语言启用 RTL 布局:
import React from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function RTLExample() {
return (
<TabComponent enableRtl={true}>
<TabItemsDirective>
<TabItemDirective header={{ text: 'ملخص' }} content="محتوى في اللغة العربية" />
<TabItemDirective header={{ text: 'تفاصيل' }} content="المزيد من المحتوى" />
<TabItemDirective header={{ text: 'الإعدادات' }} content="إعدادات التطبيق" />
</TabItemsDirective>
</TabComponent>
);
}
高级设置综合示例
import React, { useRef } from 'react';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
export default function AdvancedSettingsExample() {
const tabRef = useRef(null);
const handleTabSelecting = (args) => {
console.log(`Switching from tab ${args.previousIndex} to tab ${args.selectedIndex}`);
};
const animationSettings = {
previous: { effect: 'SlideLeftIn', duration: 500, easing: 'ease-out' },
next: { effect: 'SlideRightIn', duration: 500, easing: 'ease-out' }
};
return (
<TabComponent
ref={tabRef}
headerPlacement="Top"
overflowMode="Scrollable"
enablePersistence={true}
enableHtmlSanitizer={true}
enableRtl={false}
cssClass="advanced-tab-demo"
animation={animationSettings}
heightAdjustMode="Auto"
selecting={handleTabSelecting}
>
<TabItemsDirective>
<TabItemDirective
header={{ text: 'Overview', iconCss: 'e-icons e-home' }}
content="Welcome to the overview tab"
/>
<TabItemDirective
header={{ text: 'Profile', iconCss: 'e-icons e-user' }}
content="User profile information"
/>
<TabItemDirective
header={{ text: 'Settings', iconCss: 'e-icons e-settings' }}
content="Application settings"
/>
</TabItemsDirective>
</TabComponent>
);
}
相关技能