doc.md 13.5 KB
Newer Older
O
oasis-cloud 已提交
1
# Tabs 选项卡切换
2 3 4 5 6 7 8 9

### 介绍

常用于平级区域大块内容的的收纳和展现,支持内嵌标签形式和渲染循环数据形式

### 安装

```ts
10
// react
11
import { Tabs, TabPane } from '@nutui/nutui-react';
O
oasis-cloud 已提交
12

13 14 15 16 17
```

## 代码演示

### 基础用法
O
oasis-cloud 已提交
18

19
:::demo
O
oasis-cloud 已提交
20

21
```tsx
O
oasis-cloud 已提交
22 23
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';
24 25

const App = () => {
O
oasis-cloud 已提交
26 27 28 29 30 31
  const [tab1value, setTab1value] = useState('0');
  return (
    <>
      <Tabs value={tab1value} onChange={({ paneKey }) => {
        setTab1value(paneKey)
      }}>
32 33 34 35 36 37
        <TabPane title="Tab 1"> Tab 1 </TabPane>
        <TabPane title="Tab 2"> Tab 2 </TabPane>
        <TabPane title="Tab 3"> Tab 3 </TabPane>
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
38
};
39 40
export default App;
```
O
oasis-cloud 已提交
41

42 43 44
:::

### 基础用法-微笑曲线
O
oasis-cloud 已提交
45

46
:::demo
O
oasis-cloud 已提交
47

48
```tsx
O
oasis-cloud 已提交
49 50
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';
51 52

const App = () => {
O
oasis-cloud 已提交
53 54 55 56 57 58 59 60 61 62
  const [tab1value, setTab1value] = useState('0');
  return (
    <>
      <Tabs value={tab1value} onChange={({ paneKey }) => {
        setTab1value(paneKey)
      }} type="smile">
        <TabPane title="Tab 1"> Tab 1 </TabPane>
        <TabPane title="Tab 2"> Tab 2 </TabPane>
        <TabPane title="Tab 3"> Tab 3 </TabPane>
      </Tabs>
63 64
    </>
  );
O
oasis-cloud 已提交
65
};
66 67
export default App;
```
O
oasis-cloud 已提交
68

69 70
:::

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
### 基础用法-Title 左对齐

:::demo

```tsx
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';

const App = () => {
  const [tab1value, setTab1value] = useState('0');
  return (
    <>
      <Tabs value={tab1value} onChange={({ paneKey }) => {
        setTab1value(paneKey)
      }} leftAlign>
        <TabPane title="Tab 1"> Tab 1 </TabPane>
        <TabPane title="Tab 2"> Tab 2 </TabPane>
        <TabPane title="Tab 3"> Tab 3 </TabPane>
      </Tabs>
    </>
  );
};
export default App;
```

:::

### 通过 paneKey 匹配
99 100

:::demo
O
oasis-cloud 已提交
101

102
```tsx
O
oasis-cloud 已提交
103 104
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';
105 106

const App = () => {
O
oasis-cloud 已提交
107 108 109 110 111 112
  const [tab2value, setTab2value] = useState('0');
  return (
    <>
      <Tabs value={tab2value} onChange={({ paneKey }) => {
        setTab2value(paneKey)
      }}>
113 114 115
        <TabPane title="Tab 1" paneKey="0"> Tab 1 </TabPane>
        <TabPane title="Tab 2" paneKey="1" disabled> Tab 2 </TabPane>
        <TabPane title="Tab 3" paneKey="2"> Tab 3 </TabPane>
116 117 118
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
119
};
120 121
export default App;
```
O
oasis-cloud 已提交
122

123 124
:::

125
### CSS 粘性布局
126

127
通过设置tab的style 例如:`tabStyle={{ position: 'sticky', top: '0px', zIndex: 1 }}` ,来实现Css的粘性布局,注意:在微信小程序里组件外层元素不能存在 overflow为 hidden、auto、scroll的设置。
128 129 130 131 132 133 134 135 136 137 138 139 140 141

:::demo

```tsx
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';

const App = () => {
  const [tab2value, setTab2value] = useState('0');
  return (
    <>
      <Tabs value={tab2value} tabStyle={{ position: 'sticky', top: '0px', zIndex: 1 }} onChange={({ paneKey }) => {
        setTab2value(paneKey)
      }}>
142
        <TabPane title="Tab 1" paneKey="0">
143 144 145 146 147 148 149 150 151
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
        </TabPane>
152
        <TabPane title="Tab 2" paneKey="1">
153 154 155 156 157 158 159 160 161
            <p>Tab 2</p>
            <p>Tab 2</p>
            <p>Tab 2</p>
            <p>Tab 2</p>
            <p>Tab 2</p>
            <p>Tab 2</p>
            <p>Tab 2</p>
            <p>Tab 2</p>
        </TabPane>
162
        <TabPane title="Tab 3" paneKey="2"> Tab 3 </TabPane>
163 164 165 166 167 168 169 170
      </Tabs>
    </>
  );
};
export default App;
```

:::
171 172
### Tabpane 自动高度

Y
yangjinjun3 已提交
173 174
自动高度。设置为 true 时,nut-tabs 和 nut-tabs__content 会随着当前 nut-tabpane 的高度而发生变化。

175 176 177 178 179 180 181 182 183 184 185 186 187
:::demo

```tsx
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';

const App = () => {
  const [tab2value, setTab2value] = useState('0');
  return (
    <>
      <Tabs value={tab2value} autoHeight onChange={({ paneKey }) => {
        setTab2value(paneKey)
      }}>
188
        <TabPane title="Tab 1" paneKey="0">
189 190 191 192 193
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
            <p>Tab 1</p>
        </TabPane>
194 195
        <TabPane title="Tab 2" paneKey="1"> Tab 2 </TabPane>
        <TabPane title="Tab 3" paneKey="2"> Tab 3 </TabPane>
196 197 198 199 200 201 202 203 204
      </Tabs>
    </>
  );
};
export default App;
```

:::

205 206 207
### 数据异步渲染 3s

:::demo
O
oasis-cloud 已提交
208

209
```tsx
210
import React, { useState, useEffect } from "react";
O
oasis-cloud 已提交
211
import { Tabs, TabPane } from '@nutui/nutui-react';
212 213 214

const App = () => {
  const [tab3value, setTab3value] = useState('0');
O
oasis-cloud 已提交
215
  const [list3, setList3] = useState(Array.from(new Array(2).keys()));
216 217 218 219 220 221 222
  useEffect(() => {
    setTimeout(() => {
      list3.push(999);
      setTab3value('2');
      setList3(list3)
    }, 3000)
  }, [])
O
oasis-cloud 已提交
223 224 225 226 227 228 229
  return (
    <>
      <Tabs value={tab3value} onChange={({ paneKey }) => {
        setTab3value(paneKey)
      }}>
        {list3.map(item => <TabPane key={item}
          title={`Tab ${item}`}> Tab {item} </TabPane>)}
230 231 232
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
233
};
234 235
export default App;
```
O
oasis-cloud 已提交
236

237 238 239 240 241
:::

### 数量多,滚动操作

:::demo
O
oasis-cloud 已提交
242

243
```tsx
O
oasis-cloud 已提交
244 245
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';
246 247 248 249

const App = () => {
  const [tab4value, setTab4value] = useState('0');
  const list4 = Array.from(new Array(10).keys());
O
oasis-cloud 已提交
250 251 252 253 254 255 256
  return (
    <>
      <Tabs value={tab4value} onChange={({ paneKey }) => {
        setTab4value(paneKey)
      }} titleScroll titleGutter="10">
        {list4.map(item => <TabPane key={item}
          title={`Tab ${item}`}> Tab {item} </TabPane>)}
257 258 259
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
260
};
261 262
export default App;
```
O
oasis-cloud 已提交
263

264 265 266 267 268
:::

### 左右布局

:::demo
O
oasis-cloud 已提交
269

270
```tsx
O
oasis-cloud 已提交
271 272
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';
273 274 275 276

const App = () => {
  const [tab5value, setTab5value] = useState('0');
  const list5 = Array.from(new Array(2).keys());
O
oasis-cloud 已提交
277 278
  return (
    <>
279
      <Tabs style={{ height: '300px' }} value={tab5value} onChange={({ paneKey }) => {
O
oasis-cloud 已提交
280 281 282 283
        setTab5value(paneKey)
      }} titleScroll direction="vertical">
        {list5.map(item => <TabPane key={item}
          title={`Tab ${  item}`}> Tab {item} </TabPane>)}
284 285 286
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
287
};
288 289
export default App;
```
O
oasis-cloud 已提交
290

291 292 293 294 295
:::

### 左右布局-微笑曲线

:::demo
O
oasis-cloud 已提交
296

297
```tsx
O
oasis-cloud 已提交
298 299
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';
300 301 302 303

const App = () => {
  const [tab6value, setTab6value] = useState('0');
  const list5 = Array.from(new Array(2).keys());
O
oasis-cloud 已提交
304 305
  return (
    <>
306
      <Tabs style={{ height: '300px' }} value={tab6value} onChange={({ paneKey }) => {
O
oasis-cloud 已提交
307 308 309 310
        setTab6value(paneKey)
      }} type="smile" titleScroll direction="vertical">
        {list5.map(item => <TabPane key={item}
          title={`Tab ${item}`}> Tab {item} </TabPane>)}
311 312 313
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
314
};
315 316
export default App;
```
O
oasis-cloud 已提交
317

318 319 320
:::

### 标签栏字体尺寸 large normal small
O
oasis-cloud 已提交
321

322
:::demo
O
oasis-cloud 已提交
323

324
```tsx
O
oasis-cloud 已提交
325 326
import React, { useState } from "react";
import { Tabs, TabPane } from '@nutui/nutui-react';
327 328

const App = () => {
O
oasis-cloud 已提交
329 330 331 332 333 334
  const [tab1value, setTab1value] = useState('0');
  return (
    <>
      <Tabs value={tab1value} onChange={({ paneKey }) => {
        setTab1value(paneKey)
      }} size="large">
335 336 337 338
        <TabPane title="Tab 1"> Tab 1 </TabPane>
        <TabPane title="Tab 2"> Tab 2 </TabPane>
        <TabPane title="Tab 3"> Tab 3 </TabPane>
      </Tabs>
O
oasis-cloud 已提交
339 340 341
      <Tabs value={tab1value} onChange={({ paneKey }) => {
        setTab1value(paneKey)
      }} size="normal">
342 343 344 345
        <TabPane title="Tab 1"> Tab 1 </TabPane>
        <TabPane title="Tab 2"> Tab 2 </TabPane>
        <TabPane title="Tab 3"> Tab 3 </TabPane>
      </Tabs>
O
oasis-cloud 已提交
346 347 348
      <Tabs value={tab1value} onChange={({ paneKey }) => {
        setTab1value(paneKey)
      }} size="small">
349 350 351 352 353 354
        <TabPane title="Tab 1"> Tab 1 </TabPane>
        <TabPane title="Tab 2"> Tab 2 </TabPane>
        <TabPane title="Tab 3"> Tab 3 </TabPane>
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
355
};
356 357
export default App;
```
O
oasis-cloud 已提交
358

359 360 361
:::

### 自定义标签栏
O
oasis-cloud 已提交
362

363
:::demo
O
oasis-cloud 已提交
364

365
```tsx
O
oasis-cloud 已提交
366 367
import React, { useState } from "react";
import { Tabs, TabPane, Icon } from '@nutui/nutui-react';
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386

const App = () => {
  const [tab7value, setTab7value] = useState('c1');
  const list6 = [
    {
      title: '自定义 1',
      paneKey: 'c1',
      icon: 'dongdong'
    },
    {
      title: '自定义 2',
      paneKey: 'c2',
      icon: 'JD'
    },
    {
      title: '自定义 3',
      paneKey: 'c3'
    }
  ]
O
oasis-cloud 已提交
387 388
  return (
    <>
389 390 391 392
      <Tabs value={tab7value} titleNode={() => {
        return list6.map(item => (
          <div
            onClick={() => setTab7value(item.paneKey)}
O
oasis-cloud 已提交
393
            className={`nut-tabs__titles-item ${tab7value == item.paneKey ? 'active' : ''}`}
394 395 396
            key={item.paneKey}
          >
            {item.icon && <Icon name={item.icon} />}
O
oasis-cloud 已提交
397 398
            <span className="nut-tabs__titles-item__text">{item.title}</span>
            <span className="nut-tabs__titles-item__line" />
399
          </div>
O
oasis-cloud 已提交
400 401 402
        ))
      }

403 404
      }>
        {list6.map(item => (
O
oasis-cloud 已提交
405 406 407 408
          <TabPane key={item.paneKey} paneKey={item.paneKey}>
            {item.title}
          </TabPane>
        ))}
409 410 411
      </Tabs>
    </>
  );
O
oasis-cloud 已提交
412
};
413 414 415
export default App;
```

O
oasis-cloud 已提交
416
:::
417 418 419 420 421

## API

### Tabs Props

O
oasis-cloud 已提交
422 423 424 425 426 427 428 429 430 431 432 433 434
| 参数             | 说明                                          | 类型                  | 默认值     |
|----------------|-----------------------------------------------|---------------------|------------|
| value          | 绑定当前选中标签的标识符                      | number,string       | 0          |
| color          | 标签选中色                                    | string              | #1a1a1a    |
| background     | 标签栏背景颜色                                | string              | #f5f5f5    |
| direction      | 使用横纵方向 可选值 horizontal、vertical      | string              | horizontal |
| type           | 选中底部展示样式 可选值 line、smile           | string              | line       |
| titleScroll    | 标签栏是否可以滚动                            | boolean             | false      |
| ellipsis       | 是否省略过长的标题文字                        | boolean             | true       |
| animatedTime   | 切换动画时长,单位 ms 0 代表无动画              | number,string       | 300        |
| titleGutter    | 标签间隙                                      | number,string       | 0          |
| titleNode      | 自定义导航区域                                 | `() => JSX.Element[]` | 0          |
| size           | 标签栏字体尺寸大小 可选值 large normal small | string              | normal     |
435
| leftAlign`v1.4.8` | 标题左对齐 | boolean | false |
O
oasis-cloud 已提交
436 437
| autoHeight`v1.2.1` | 自动高度。设置为 true 时,nut-tabs 和 nut-tabs__content 会随着当前 nut-tabpane 的高度而发生变化。 | boolean             | false     |
| tabStyle`v1.3.8` | 标签栏样式 | React.CSSProperties | {}     |
438 439 440 441 442 443 444 445 446

## Tabs Children

| 名称    | 说明           |
|---------|----------------|
| default | 自定义内容     |

### Tabpane Props

447 448 449 450 451
| 参数                | 说明              | 类型    | 默认值           |
|-------------------|-----------------|---------|------------------|
| title             | 标题              | string  |                  |
| paneKey           | 标签 Key , 匹配的标识符 | string  | 默认索引0,1,2... |
| disabled          | 是否禁用标签          | boolean | false            |
452 453 454 455 456

### Tabs Events

| 事件名 | 说明                     | 回调参数                 |
|--------|--------------------------|--------------------------|
Y
yangjinjun3 已提交
457 458
| onClick  | 点击标签时触发           | {title,paneKey,disabled} |
| onChange | 当前激活的标签改变时触发 | {title,paneKey,disabled} |
459 460 461 462 463 464 465 466 467 468 469


## 主题定制

### 样式变量

组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider 组件](#/zh-CN/component/configprovider)

| 名称 | 默认值 |
| --- | --- |
| --nutui-tabs-tab-smile-color | `  $primary-color` |
470
| --nutui-tabs-titles-background-color | `  $background-color` |
471 472 473 474 475 476
| --nutui-tabs-titles-border-radius | ` 0` |
| --nutui-tabs-titles-item-large-font-size | `  $font-size-3` |
| --nutui-tabs-titles-item-font-size | `  $font-size-2` |
| --nutui-tabs-titles-item-small-font-size | `  $font-size-1` |
| --nutui-tabs-titles-item-color | `  $title-color` |
| --nutui-tabs-titles-item-active-color | `  $title-color` |
477 478
| --nutui-tabs-titles-item-active-font-weight`v1.4.9` | ` 600` |
| --nutui-tabs-horizontal-tab-line-color`v1.4.9` | `linear-gradient(90deg, $primary-color 0%, rgba(#fa2c19, 0.15) 100%)`|
479 480
| --nutui-tabs-horizontal-line-bottom`v1.4.8` | ` 15%` |
| --nutui-tabs-horizontal-line-border-radius`v1.4.8` |` 0px`|
481
| --nutui-tabs-horizontal-tab-line-opacity`v1.4.9` | ` 1`|
482 483
| --nutui-tabs-horizontal-titles-height | `  46px` |
| --nutui-tabs-horizontal-titles-item-min-width | `  50px` |
484
| --nutui-tabs-horizontal-titles-item-active-background-color`v1.4.9` | ` $background-color3` |
485
| --nutui-tabs-horizontal-titles-item-active-line-width | `  40px` |
486 487
| --nutui-tabs-horizontal-titles-item-active-line-height`v1.4.9` | `  3px` |
| --nutui-tabs-vertical-tab-line-color`v1.4.9` | `linear-gradient(180deg, $primary-color 0%, rgba(#fa2c19, 0.15) 100%)`|
488
| --nutui-tabs-vertical-titles-item-height | `  40px` |
489
| --nutui-tabs-vertical-titles-item-active-line-width`v1.4.9` | `  3px` |
490 491
| --nutui-tabs-vertical-titles-item-active-line-height | `  14px` |
| --nutui-tabs-vertical-titles-width | `  100px` |
492 493
| --nutui-tabs-titles-item-line-border-radius`v1.4.9 废弃` | `  0` |
| --nutui-tabs-titles-item-line-opacity`v1.4.9 废弃` | `  1` |