Tab 选项卡

如果项目中使用的是 1.x 版本的基础组件(@alifd/next),请在左侧导航顶部切换组件版本。

安装方法

  1. 在命令行中执行以下命令npm install @icedesign/base@latest -S

Guide

TAB 让用户可以在不同子任务、视图、模式之间切换,它具有全局导航的作用,是全局功能的主要展示和切换区域,一个TAB标记一个核心功能,TAB之间可以快速点击切换。该窗口包含2个以上的选项卡,所有选项卡可以排列在一行中,即使该用户界面被本地化后也是如此。提供平级的区域将大块内容进行收纳和展现,保持界面整洁。

何时使用

Fusion 提供了三级选项卡,分别用于不同的场景。

  • 普通选项卡,引领整页面的内容,起导航的作用。

  • 文本型选项卡。

  • 包裹型选项卡,在页面结构中,只是局部展示,需要和其他内容结合出现。

  • 胶囊型选项卡。

关于动效

如果您不想开启动效,可以通过设置 animation 属性值为 false 来关闭。

注意事项

对于 0.x 版本的 Tab 组件而言,在实现上使用了 key 作为内部标识字段,如果用户使用了 React 官方提供的类似于 React.Children.toArray 等子元素遍历方法时,会导致原始的 key 值被修改,这一行为会导致部分逻辑出错(判断当前激活的 TabPane)。为了保证兼容性,我们将会在 1.x 版本进行变更。如果你需要用到 React.Children.toArray 方法,可以使用 @alife/next-util 中提供的 children.toArray 方法。

API

选项卡

参数说明类型默认值
prefix样式前缀String'next-'
activeKey被激活的选项卡的 key(受控)Number/String-
defaultActiveKey初始化时被激活的选项卡的 key(非受控)Number/String-
type类型可选值:'bar', 'wrapped', 'text', 'capsule'Enum'bar'
animation是否开启动效Booleantrue
resDirection多余项的展现方向可选值:'horizontal', 'vertical'Enum'horizontal'
tabPosition导航选项卡的位置,只适用于包裹型(wrapped)选项卡可选值:'top', 'bottom', 'left', 'right'Enum'top'
size尺寸可选值:'small', 'medium'Enum'medium'
closeable是否可关闭选项卡,只支持 barwrapped 两种类型Booleanfalse
triggerType触发选项卡的方式可选值:'hover', 'click'Enum'click'
lazyLoad是否提前渲染好所有 TabPane 的内容Booleantrue
navStyle导航条的附加样式Object{}
contentStyle内容区的附加样式Object{}
tabBarExtraContent导航栏附加内容ReactNodenull
onChange选项卡发生切换时的事件回调签名:Function(key: String) => void参数:key: {String} 改变后的 keyFunction() => {}
onClose选项卡被关闭时的事件回调签名:Function(key: String, event: Object) => void参数:key: {String} 关闭的选项卡的 keyevent: {Object} Event 对象Function() => {}

Tab.TabPane

参数说明类型默认值
tab选项卡标题any-
closeable单个选项卡是否可关闭Booleantrue
tabStyle单个选项卡的补充样式Object-
tabClassName单个选项卡的附加样式类String-
onClick点击单个选项卡时触发的回调签名:Function(key: String) => void参数:key: {String} 选项卡的 keyFunction() => {}
onMouseEnter鼠标进入时触发的回调签名:Function(key: String) => void参数:key: {String} 选项卡的 keyFunction() => {}
onMouseLeave鼠标离开时出发的回调签名:Function(key: String) => void参数:key: {String} 选项卡的 keyFunction() => {}

代码示例

简单用法

请务必给每个 TabPane 传入一个 key 值作为每个 TabPane 的唯一标识字段。创建一个基本的选项卡,其默认类型为bar,并默认选中第一项。

Tab 选项卡 - 图1

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const tabs = [
  4. { tab: "首页", key: "home", content: "这里是首页内容" },
  5. { tab: "文档", key: "doc", content: "这里是文档内容" },
  6. { tab: "API", key: "api", content: "这里是 API 内容" }
  7. ];
  8. function handleChange(key) {
  9. console.log("change", key);
  10. }
  11. function handleClick(key) {
  12. console.log("click", key);
  13. }
  14. ReactDOM.render(
  15. <Tab onChange={handleChange}>
  16. {tabs.map(item => (
  17. <TabPane key={item.key} tab={item.tab} onClick={handleClick}>
  18. {item.content}
  19. </TabPane>
  20. ))}
  21. </Tab>,
  22. mountNode
  23. );

可关闭选项卡

此外用户还可以单独在单个 TabPane 上设置是否可关闭的属性。可关闭选项卡,可以通过控制 closable 属性设置选项卡是否可关闭。处于视觉上的考虑,目前该属性只支持包裹型选项卡(wrapped)和普通选项卡(bar)。

Tab 选项卡 - 图2

查看源码在线预览

  1. import { Tab, Button, Icon } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const panes = [
  4. { tab: "邮件", key: 1, closeable: false },
  5. { tab: "消息通知", key: 2 },
  6. { tab: "设置", key: 3 },
  7. { tab: "未读邮件", key: 4 }
  8. ];
  9. class CloseableTab extends React.Component {
  10. constructor(props) {
  11. super(props);
  12. this.state = {
  13. panes: panes,
  14. activeKey: panes[0].key
  15. };
  16. }
  17. /*eslint-disable eqeqeq */
  18. remove(targetKey) {
  19. let activeKey = this.state.activeKey;
  20. let lastIndex;
  21. this.state.panes.forEach((item, i) => {
  22. if (item.key == targetKey) {
  23. lastIndex = i - 1;
  24. }
  25. });
  26. const panes = this.state.panes.filter(pane => pane.key != targetKey);
  27. if (lastIndex >= 0 && activeKey == targetKey) {
  28. activeKey = panes[lastIndex].key;
  29. }
  30. this.setState({ panes, activeKey });
  31. }
  32. onClose(targetKey) {
  33. this.remove(targetKey);
  34. }
  35. onChange(activeKey) {
  36. this.setState({ activeKey });
  37. }
  38. addTabpane() {
  39. this.setState(prevState => {
  40. const { panes } = prevState;
  41. panes.push({ tab: "new tab", key: Math.random() });
  42. return { panes };
  43. });
  44. }
  45. render() {
  46. const state = this.state;
  47. return (
  48. <div>
  49. <Button onClick={::this.addTabpane}>
  50. <Icon type="add" /> 新建选项卡
  51. </Button>
  52. <Tab
  53. type="wrapped"
  54. activeKey={state.activeKey}
  55. closeable
  56. onChange={::this.onChange}
  57. onClose={::this.onClose}
  58. className="custom-tab"
  59. >
  60. {state.panes.map(item => (
  61. <TabPane tab={item.tab} key={item.key} closeable={item.closeable}>
  62. {item.tab}的内容区域
  63. </TabPane>
  64. ))}
  65. </Tab>
  66. </div>
  67. );
  68. }
  69. }
  70. ReactDOM.render(<CloseableTab />, mountNode);
  1. .custom-tab {
  2. margin-top: 14px;
  3. }

自定义样式

此外,某些场合下,用户可能需要在某些特定的 tab 上添加样式,为此可以在 TabPane 上使用 tabClassNametabStyle 来控制。如果需要定制导航条的样式,可以通过 navStyle 属性进行设置。如果需要定制内容区的样式,可以通过 contentStyle 属性进行设置。Tab 提供了丰富的属性让用户自定义组件的默认样式。

Tab 选项卡 - 图3

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const panes = [
  4. {
  5. tab: "未处理任务",
  6. key: 0
  7. },
  8. {
  9. tab: "已处理任务",
  10. key: 1
  11. },
  12. {
  13. tab: "未处理消息",
  14. key: 2
  15. },
  16. {
  17. tab: "已处理消息",
  18. key: 3
  19. },
  20. {
  21. tab: "过期消息",
  22. key: 4
  23. }
  24. ];
  25. const detachedContentStyle = {
  26. borderLeft: 0,
  27. borderRight: 0,
  28. borderBottom: 0
  29. };
  30. ReactDOM.render(
  31. <div className="fusion-demo">
  32. <div className="demo-item-title">
  33. 通过 contentStyle 属性移除内容区默认边框
  34. </div>
  35. <Tab type="wrapped" contentStyle={detachedContentStyle}>
  36. {panes.map(pane => (
  37. <TabPane tab={pane.tab} key={pane.key}>
  38. {pane.tab}
  39. </TabPane>
  40. ))}
  41. </Tab>
  42. <div className="demo-item-title">
  43. 搭配使用 contentStyle, navStyle, tabClassName, tabStyle 等自定义样式属性
  44. </div>
  45. <Tab
  46. type="wrapped"
  47. contentStyle={{ padding: 0 }}
  48. navStyle={{ background: "#FFF0E6" }}
  49. >
  50. {panes.map(pane => {
  51. return (
  52. <TabPane
  53. tab={pane.tab}
  54. key={pane.key}
  55. className="custom-content"
  56. tabStyle={{ background: "#FFF" }}
  57. tabClassName="custom-tabs-tab"
  58. >
  59. {pane.tab}
  60. </TabPane>
  61. );
  62. })}
  63. </Tab>
  64. <div className="demo-item-title">利用 tabClassName 实现等宽导航</div>
  65. <Tab type="capsule">
  66. {panes.map(pane => (
  67. <TabPane tab={pane.tab} key={pane.key} tabClassName="justify-tabs-tab">
  68. {pane.tab}
  69. </TabPane>
  70. ))}
  71. </Tab>
  72. </div>,
  73. mountNode
  74. );
  1. .fusion-demo .demo-item-title {
  2. font-size: 16px;
  3. background: #eee;
  4. color: #333;
  5. padding: 8px;
  6. margin: 14px 0;
  7. text-align: center;
  8. }
  9. .custom-content {
  10. color: #333;
  11. padding: 15px;
  12. }
  13. .custom-tabs-tab {
  14. margin-right: -1px !important;
  15. }
  16. .justify-tabs-tab {
  17. width: 140px;
  18. text-align: center;
  19. }

自定义选项卡

除了使用简单文本作为选项卡的标题,用户还可以传入自定义组件作为标题。

Tab 选项卡 - 图4

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const complexTab1 = (
  4. <div className="custom-tab-wrapper">
  5. <p className="tab-title">e-Checking</p>
  6. <p className="tab-desc">Transaction fee: US $15</p>
  7. </div>
  8. );
  9. const complexTab2 = (
  10. <div className="custom-tab-wrapper">
  11. <p className="tab-title">Bank Card</p>
  12. <p className="tab-desc">Transaction fee: US $26</p>
  13. </div>
  14. );
  15. const panes = [
  16. {
  17. tab: complexTab1,
  18. key: 0
  19. },
  20. {
  21. tab: complexTab2,
  22. key: 1
  23. }
  24. ];
  25. function callback(key) {
  26. console.log(key);
  27. }
  28. ReactDOM.render(
  29. <Tab onChange={callback} type="wrapped">
  30. {panes.map(pane => (
  31. <TabPane tab={pane.tab} key={pane.key} tabStyle={{ height: "60px" }}>
  32. {pane.tab}
  33. </TabPane>
  34. ))}
  35. </Tab>,
  36. mountNode
  37. );
  1. .custom-tab-wrapper {
  2. line-height: 16px;
  3. }
  4. .tab-title {
  5. margin: 10px 0 0 0;
  6. font-size: 16px;
  7. }
  8. .tab-desc {
  9. margin: 10px 0 0 0;
  10. font-size: 12px;
  11. }

禁用

可以通过 disabled 属性禁用某一个选型卡。

Tab 选项卡 - 图5

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. ReactDOM.render(
  4. <Tab>
  5. <TabPane tab="选项卡一" key="1">
  6. 选项卡一
  7. </TabPane>
  8. <TabPane tab="选项卡二" disabled key="2">
  9. 选项卡二
  10. </TabPane>
  11. <TabPane tab="选项卡三" key="3">
  12. 选项卡三
  13. </TabPane>
  14. </Tab>,
  15. mountNode
  16. );

可编辑的 Tab

此时用户只要传入自定义组件给 TabPane 即可,Tab 可以将底层事件对象传递给用户的自定义组件。Tab 允许开发者在上层进行自由的行为控制,例如用户可以基于 Tab 开发一个标题部分双击可编辑的 Tab ,

Tab 选项卡 - 图6

查看源码在线预览

  1. import { Tab, Input } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. class EditableTabPane extends React.Component {
  4. static propTypes = {
  5. defaultTitle: React.PropTypes.string
  6. };
  7. constructor(props) {
  8. super(props);
  9. this.state = {
  10. tabTitle: props.defaultTitle,
  11. editable: false
  12. };
  13. }
  14. componentWillReceiveProps(nextProps) {
  15. if (nextProps.defaultTitle !== this.state.tabTitle) {
  16. this.setState({
  17. tabTitle: nextProps.defaultTitle
  18. });
  19. }
  20. }
  21. onKeyDown(e) {
  22. const { keyCode } = e;
  23. // 由于 Tab 会监听键盘的 keyUp, keyDown, keyLeft, keyRight 四个按键用于支持键盘导航
  24. // 如果上层需要使用到键盘事件,需要在这里停止事件冒泡
  25. if (keyCode > 36 && keyCode < 41) {
  26. e.stopPropagation();
  27. }
  28. }
  29. onBlur(e) {
  30. this.setState({
  31. editable: false,
  32. tabTitle: e.target.value
  33. });
  34. }
  35. onDblClick() {
  36. this.setState({
  37. editable: true
  38. });
  39. }
  40. render() {
  41. const { tabTitle, editable } = this.state;
  42. if (editable) {
  43. return (
  44. <Input
  45. defaultValue={tabTitle}
  46. onKeyDown={this.onKeyDown.bind(this)}
  47. onBlur={this.onBlur.bind(this)}
  48. />
  49. );
  50. }
  51. return <span onDoubleClick={this.onDblClick.bind(this)}>{tabTitle}</span>;
  52. }
  53. }
  54. ReactDOM.render(
  55. <Tab defaultActiveKey="1">
  56. <TabPane tab={<EditableTabPane defaultTitle="选项卡一" />} key="1">
  57. 选项卡一
  58. </TabPane>
  59. <TabPane tab="选项卡二" key="2">
  60. 选项卡二
  61. </TabPane>
  62. </Tab>,
  63. mountNode
  64. );

附加额外内容

可以通过设置 tabBarExtraContent 为 Tab 组件附加额外的内容,确保只在有限选项卡的情况下才使用附加内容。

Tab 选项卡 - 图7

查看源码在线预览

  1. import { Tab, Button } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. function handleChange(key) {
  4. console.log(key);
  5. }
  6. function handleClick() {
  7. console.log("hello world");
  8. }
  9. const extraContent = (
  10. <Button type="primary" onClick={handleClick}>
  11. Hello world
  12. </Button>
  13. );
  14. ReactDOM.render(
  15. <div className="fusion-demo">
  16. <div className="demo-item-title">水平方向加 tabBarExtraContent</div>
  17. <Tab
  18. type="wrapped"
  19. onChange={handleChange}
  20. tabBarExtraContent={extraContent}
  21. >
  22. <TabPane tab="选项卡一" key="1">
  23. 选项卡一内容
  24. </TabPane>
  25. <TabPane tab="选项卡二" key="2">
  26. 选项卡二内容
  27. </TabPane>
  28. <TabPane tab="选项卡三" key="3">
  29. 选项卡三内容
  30. </TabPane>
  31. </Tab>
  32. <div className="demo-item-title">垂直方向加 tabBarExtraContent</div>
  33. <Tab
  34. type="wrapped"
  35. tabPosition="left"
  36. onChange={handleChange}
  37. tabBarExtraContent={extraContent}
  38. >
  39. <TabPane tab="选项卡一" key="1">
  40. 选项卡一内容
  41. </TabPane>
  42. <TabPane tab="选项卡二" key="2">
  43. 选项卡二内容
  44. </TabPane>
  45. <TabPane tab="选项卡三" key="3">
  46. 选项卡三内容
  47. </TabPane>
  48. </Tab>
  49. </div>,
  50. mountNode
  51. );
  1. .fusion-demo .demo-item-title {
  2. font-size: 16px;
  3. background: #eee;
  4. color: #333;
  5. padding: 8px;
  6. margin: 14px 0;
  7. text-align: center;
  8. }

关闭 Lazyload

如果您需要在某些时候提前渲染好所有的 Content 内容,可以使用在 Tab 上关闭 lazyLoad 属性。默认情况 Tab 不会提前渲染好所有的内容,而是根据 Tab 的激活情况依次渲染。

Tab 选项卡 - 图8

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const tabs = [
  4. { tab: "首页", key: 0, content: "这里是首页内容" },
  5. { tab: "文档", key: 1, content: "这里是文档内容" },
  6. { tab: "API", key: 2, content: "这里是 API 内容" }
  7. ];
  8. ReactDOM.render(
  9. <Tab lazyLoad={false}>
  10. {tabs.map(item => (
  11. <TabPane key={item.key} tab={item.tab}>
  12. {item.content}
  13. </TabPane>
  14. ))}
  15. </Tab>,
  16. mountNode
  17. );

选项卡嵌套

可以将不同类型的选项卡进行嵌套

Tab 选项卡 - 图9

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. function callback(key) {
  4. console.log(key);
  5. }
  6. ReactDOM.render(
  7. <Tab onChange={callback} type="wrapped">
  8. <TabPane tab="选项卡一" key="1">
  9. <Tab type="wrapped">
  10. <TabPane tab="1-1" key="11">
  11. 1-1
  12. </TabPane>
  13. <TabPane tab="1-2" key="12">
  14. 1-2
  15. </TabPane>
  16. <TabPane tab="1-3" key="13">
  17. 1-3
  18. </TabPane>
  19. </Tab>
  20. </TabPane>
  21. <TabPane tab="选项卡二" key="2">
  22. <Tab type="bar">
  23. <TabPane tab="2-1" key="21">
  24. 2-1
  25. </TabPane>
  26. <TabPane tab="2-2" key="22">
  27. 2-2
  28. </TabPane>
  29. <TabPane tab="3-3" key="23">
  30. 2-3
  31. </TabPane>
  32. </Tab>
  33. </TabPane>
  34. <TabPane tab="选项卡三" key="3">
  35. <Tab type="capsule">
  36. <TabPane tab="3-1" key="31">
  37. 3-1
  38. </TabPane>
  39. <TabPane tab="3-2" key="32">
  40. 3-2
  41. </TabPane>
  42. <TabPane tab="3-3" key="33">
  43. 3-3
  44. </TabPane>
  45. </Tab>
  46. </TabPane>
  47. <TabPane tab="选项卡三" key="4">
  48. <Tab type="text">
  49. <TabPane tab="4-1" key="41">
  50. 4-1
  51. </TabPane>
  52. <TabPane tab="4-2" key="42">
  53. 4-2
  54. </TabPane>
  55. <TabPane tab="4-3" key="43">
  56. 4-3
  57. </TabPane>
  58. </Tab>
  59. </TabPane>
  60. </Tab>,
  61. mountNode
  62. );

位置

内容区的高度将会被自动附加一个 min-height 值,该值为导航条的高度。需要注意的是,当 tabPosition="left|right" 时,并且用户没有通过 contentStyle 属性自定义内容区的最小高度时,有四个位置,tabPosition="left|right|top|bottom"。对于包裹型(type 值为 wrapped)选项卡,支持通过 tabPosition 来指定选项卡标签的位置。

Tab 选项卡 - 图10

查看源码在线预览

  1. import { Select, Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const contentStyle = {
  4. background: "#FFF"
  5. };
  6. class Demo extends React.Component {
  7. constructor(props) {
  8. super(props);
  9. this.state = {
  10. tabPosition: "bottom"
  11. };
  12. }
  13. changeTabPosition(value) {
  14. this.setState({ tabPosition: value });
  15. }
  16. render() {
  17. return (
  18. <div>
  19. <Select
  20. value={this.state.tabPosition}
  21. onChange={::this.changeTabPosition}
  22. className="tab-select-demo"
  23. >
  24. <div value="top">top</div>
  25. <div value="bottom">bottom</div>
  26. <div value="left">left</div>
  27. <div value="right">right</div>
  28. </Select>
  29. <Tab
  30. tabPosition={this.state.tabPosition}
  31. type="wrapped"
  32. contentStyle={contentStyle}
  33. >
  34. <TabPane tab="选项卡一" key="1">
  35. 选项卡一内容
  36. </TabPane>
  37. <TabPane tab="选项卡二" key="2">
  38. 选项卡二内容
  39. </TabPane>
  40. <TabPane tab="选项卡三" key="3">
  41. 选项卡三内容
  42. </TabPane>
  43. </Tab>
  44. </div>
  45. );
  46. }
  47. }
  48. ReactDOM.render(<Demo />, mountNode);
  1. .tab-select-demo {
  2. margin-bottom: 20px;
  3. }

尺寸

small尺寸的选项卡组件可以用在弹出框等较狭窄的容器内。组件尺寸,可以通过size属性设置,提供medium(默认)和small两种尺寸,

Tab 选项卡 - 图11

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const tabs = [
  4. { tab: "首页", key: "home", content: "这里是首页内容" },
  5. { tab: "文档", key: "doc", content: "这里是文档内容" },
  6. { tab: "API", key: "api", content: "这里是 API 内容" }
  7. ];
  8. ReactDOM.render(
  9. <div>
  10. <Tab size="small">
  11. {tabs.map(item => (
  12. <TabPane key={item.key} tab={item.tab}>
  13. {item.content}
  14. </TabPane>
  15. ))}
  16. </Tab>
  17. <br />
  18. <Tab size="small" type="wrapped">
  19. {tabs.map(item => (
  20. <TabPane key={item.key} tab={item.tab}>
  21. {item.content}
  22. </TabPane>
  23. ))}
  24. </Tab>
  25. <br />
  26. <Tab size="small" type="text">
  27. {tabs.map(item => (
  28. <TabPane key={item.key} tab={item.tab}>
  29. {item.content}
  30. </TabPane>
  31. ))}
  32. </Tab>
  33. <br />
  34. <Tab size="small" type="capsule">
  35. {tabs.map(item => (
  36. <TabPane key={item.key} tab={item.tab}>
  37. {item.content}
  38. </TabPane>
  39. ))}
  40. </Tab>
  41. </div>,
  42. mountNode
  43. );

自适应方向

用户可以通过 resDirection 属性进行控制该行为。当容器无法容纳所有的选项卡标签时,Tab 组件支持选项卡左右滑动选择,或者下拉选择。

Tab 选项卡 - 图12

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const tabs = [
  4. { tab: "选项卡一", key: 1 },
  5. { tab: "选项卡二", key: 2 },
  6. { tab: "选项卡三", key: 3 },
  7. { tab: "选项卡四", key: 4 },
  8. { tab: "选项卡五", key: 5 },
  9. { tab: "选项卡六", key: 6 },
  10. { tab: "选项卡七", key: 7 },
  11. { tab: "选项卡八", key: 8 },
  12. { tab: "选项卡九", key: 9 }
  13. ];
  14. function onClick(key) {
  15. console.log(key);
  16. }
  17. ReactDOM.render(
  18. <div className="fusion-demo" style={{ width: "510px" }}>
  19. <div className="demo-item-title">默认使用左右活动</div>
  20. <Tab defaultActiveKey={1}>
  21. {tabs.map(item => (
  22. <TabPane key={item.key} tab={item.tab} onClick={onClick}>
  23. {item.tab}的内容。这里可以容纳更多内容。
  24. </TabPane>
  25. ))}
  26. </Tab>
  27. <div className="demo-item-title">
  28. resDirection = "vertical" 时使用下拉框容纳多余元素
  29. </div>
  30. <Tab defaultActiveKey={1} resDirection="vertical">
  31. {tabs.map(item => (
  32. <TabPane key={item.key} tab={item.tab} onClick={onClick}>
  33. {item.tab}的内容。这里可以容纳更多内容。
  34. </TabPane>
  35. ))}
  36. </Tab>
  37. </div>,
  38. mountNode
  39. );
  1. .fusion-demo .demo-item-title {
  2. font-size: 16px;
  3. background: #eee;
  4. color: #333;
  5. padding: 8px;
  6. margin: 14px 0;
  7. text-align: center;
  8. }

在 Grid 中使用 Tab

值得注意的是,当使用 Grid 组件进行外层的布局时,由于 Gird 默认使用的是 flex 进行布局。因此,如果 Tab 组件拥有过多的选项卡时,会导致内层元素撑起整个 flex 容器。此时,需要给容器添加自定义样式 overflow: hidden

Tab 选项卡 - 图13

查看源码在线预览

  1. import { Tab, Grid } from "@icedesign/base";
  2. const { TabPane } = Tab;
  3. const { Row, Col } = Grid;
  4. const tabs = (function(length) {
  5. const arr = [];
  6. for (let i = 1; i < length; i++) {
  7. arr.push({ tab: `tab ${i}`, key: i, content: `tab ${i} 的内容` });
  8. }
  9. return arr;
  10. })(15);
  11. function handleChange(key) {
  12. console.log("change", key);
  13. }
  14. function handleClick(key) {
  15. console.log("click", key);
  16. }
  17. ReactDOM.render(
  18. <div className="custom-wrapper">
  19. <Row className="custom-row">
  20. <Col fixedSpan="12" className="custom-col-sidebar">
  21. Sidebar
  22. </Col>
  23. <Col className="custom-col-content">
  24. <Tab onChange={handleChange}>
  25. {tabs.map(item => (
  26. <TabPane key={item.key} tab={item.tab} onClick={handleClick}>
  27. {item.content}
  28. </TabPane>
  29. ))}
  30. </Tab>
  31. </Col>
  32. </Row>
  33. </div>,
  34. mountNode
  35. );
  1. .custom-row {
  2. border: 1px solid #ccc;
  3. }
  4. .custom-col-sidebar {
  5. border-right: 1px solid #ccc;
  6. height: 130px;
  7. line-height: 130px;
  8. text-align: center;
  9. }
  10. .custom-col-content {
  11. overflow: hidden;
  12. }

触发类型

Tab 支持 click 切换和 hover 切换两种触发类型,默认为 click 触发,您可以使用 triggerType 属性修改默认的触发类型。

Tab 选项卡 - 图14

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. const tabs = [
  4. { tab: "首页", key: 0, content: "这里是首页内容" },
  5. { tab: "文档", key: 1, content: "这里是文档内容" },
  6. { tab: "API", key: 2, content: "这里是 API 内容" }
  7. ];
  8. function onChange(key) {
  9. console.log("change", key);
  10. }
  11. function handleClick(key) {
  12. console.log("click", key);
  13. }
  14. function onMouseEnter(key, e) {
  15. console.log("enter", e.target, key);
  16. }
  17. function onMouseLeave(key, e) {
  18. console.log("leave", e.target, key);
  19. }
  20. ReactDOM.render(
  21. <div className="fusion-demo">
  22. <div className="demo-item-title">triggerType = click</div>
  23. <Tab triggerType="click" onChange={onChange}>
  24. {tabs.map(item => (
  25. <TabPane key={item.key} tab={item.tab} onClick={handleClick}>
  26. {item.content}
  27. </TabPane>
  28. ))}
  29. </Tab>
  30. <div className="demo-item-title">triggerType = hover</div>
  31. <Tab triggerType="hover" onChange={onChange}>
  32. {tabs.map(item => (
  33. <TabPane
  34. key={item.key}
  35. tab={item.tab}
  36. onClick={handleClick}
  37. onMouseEnter={onMouseEnter}
  38. onMouseLeave={onMouseLeave}
  39. >
  40. {item.content}
  41. </TabPane>
  42. ))}
  43. </Tab>
  44. </div>,
  45. mountNode
  46. );
  1. .fusion-demo .demo-item-title {
  2. font-size: 16px;
  3. background: #eee;
  4. color: #333;
  5. padding: 8px;
  6. margin: 14px 0;
  7. text-align: center;
  8. }

类型

capsule 胶囊型选项卡text 文本型选项卡wrapped 包裹型选项卡bar 普通选项卡(如不指定type属性,则默认使用bar型选项卡)根据使用场景及触发控件的类型,可以通过 type 属性配置选项卡的类型,主要包括:

Tab 选项卡 - 图15

查看源码在线预览

  1. import { Tab } from "@icedesign/base";
  2. const TabPane = Tab.TabPane;
  3. function onChange(key) {
  4. console.log(key);
  5. }
  6. const tabs = [
  7. { tab: "首页", key: "home", content: "这里是首页内容" },
  8. { tab: "文档", key: "doc", content: "这里是文档内容" },
  9. { tab: "API", key: "api", content: "这里是 API 内容" },
  10. { tab: "仓库", key: "repo", content: "这里是仓库内容" }
  11. ];
  12. const types = ["bar", "wrapped", "text", "capsule"];
  13. ReactDOM.render(
  14. <div className="fusion-demo">
  15. {types.map(type => (
  16. <div key={type} className="fusion-demo-item">
  17. <Tab type={type} onChange={onChange}>
  18. {tabs.map(tab => (
  19. <TabPane tab={tab.tab} key={tab.key}>
  20. {tab.content}
  21. </TabPane>
  22. ))}
  23. </Tab>
  24. </div>
  25. ))}
  26. </div>,
  27. mountNode
  28. );
  1. .fusion-demo-item {
  2. margin: 14px 0;
  3. }

相关区块

Tab 选项卡 - 图16

暂无相关区块