fix: tabs activeKey 表达式支持问题;增加defaultKey属性 (#6084)

* fix: tabs activeKey 表达式支持问题;增加defaultKey属性

* 添加版本限制提示

* 再跑下单测
This commit is contained in:
sansiro 2023-02-08 12:58:05 +08:00 committed by GitHub
parent 446bdeebb9
commit 84a528f16f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 138 additions and 30 deletions

View File

@ -555,32 +555,110 @@ order: 68
```schema
{
"type": "page",
"type": "page",
"data": {
"key": "tab2"
},
"body": [
"key": 2
},
"body": [
{
"type": "radios",
"name": "key",
"mode": "inline",
"label": "激活的选项卡",
"options": [
{
"type": "tabs",
"activeKey": "${key}",
"tabs": [
{
"title": "Tab 1",
"hash": "tab1",
"tab": "Content 1"
},
{
"title": "Tab 2",
"hash": "tab2",
"tab": "Content 2"
}
]
"label": "Tab 1",
"value": 0
},
{
"label": "Tab 2",
"value": 1
},
{
"label": "Tab 3",
"value": 2
}
]
]
},
{
"type": "tabs",
"activeKey": "${key|toInt}",
"tabs": [
{
"title": "Tab 1",
"tab": "Content 1"
},
{
"title": "Tab 2",
"tab": "Content 2"
},
{
"title": "Tab 3",
"tab": "Content 3"
}
]
}
]
}
```
### 初始化设置默认选项卡
> 2.7.1 以上版本
```schema
{
"type": "page",
"data": {
"defaultKey": 1,
"activeKey": 2
},
"body": [
{
"type": "radios",
"name": "key",
"mode": "inline",
"label": "激活的选项卡",
"options": [
{
"label": "Tab 1",
"value": 0
},
{
"label": "Tab 2",
"value": 1
},
{
"label": "Tab 3",
"value": 2
}
]
},
{
"type": "tabs",
"activeKey": "${activeKey|toInt}",
"defaultKey": "${defaultKey|toInt}",
"tabs": [
{
"title": "Tab 1",
"tab": "Content 1"
},
{
"title": "Tab 2",
"tab": "Content 2"
},
{
"title": "Tab 3",
"tab": "Content 3"
}
]
}
]
}
```
> 初始化组件时 `defaultKey` 优先级高于 `activeKey`,但 `defaultKey` 仅作用于组件初始化时,不会响应上下文数据变化。
## 图标
通过 icon 可以设置 tab 的图标,可以是 fontawesome 或 URL 地址。
@ -679,6 +757,8 @@ order: 68
| 属性名 | 类型 | 默认值 | 说明 |
| --------------------- | --------------------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| type | `string` | `"tabs"` | 指定为 Tabs 渲染器 |
| defaultKey | `string` / `number` | | 组件初始化时激活的选项卡hash 值或索引值,支持使用表达式 `2.7.1 以上版本` |
| activeKey | `string` / `number` | | 激活的选项卡hash 值或索引值,支持使用表达式,可响应上下文数据变化 |
| className | `string` | | 外层 Dom 的类名 |
| tabsMode | `string` | | 展示模式,取值可以是 `line`、`card`、`radio`、`vertical`、`chrome`、`simple`、`strong`、`tiled`、`sidebar` |
| tabsClassName | `string` | | Tabs Dom 的类名 |

View File

@ -493,6 +493,11 @@ export class Tabs extends React.Component<TabsProps, any> {
this.scroll = true;
}
// 处理 hash 作为 key 时重复的问题
generateTabKey(hash: any, eventKey: any, index: number) {
return (hash === eventKey ? 'hash-' : '') + (eventKey ?? index);
}
renderNav(child: any, index: number, showClose: boolean) {
if (!child) {
return;
@ -517,7 +522,8 @@ export class Tabs extends React.Component<TabsProps, any> {
title,
toolbar,
tabClassName,
closable: tabClosable
closable: tabClosable,
hash
} = child.props;
const {editingIndex, editInputText} = this.state;
@ -573,7 +579,7 @@ export class Tabs extends React.Component<TabsProps, any> {
disabled ? 'is-disabled' : '',
tabClassName
)}
key={eventKey ?? index}
key={this.generateTabKey(hash, eventKey, index)}
onClick={() => (disabled ? '' : this.handleSelect(eventKey))}
onDoubleClick={() => {
editable && this.handleStartEdit(index, title);
@ -623,14 +629,15 @@ export class Tabs extends React.Component<TabsProps, any> {
return;
}
const {hash, eventKey} = child?.props || {};
const {activeKey: activeKeyProp, classnames} = this.props;
const eventKey = child.props.eventKey;
const activeKey =
activeKeyProp === undefined && index === 0 ? eventKey : activeKeyProp;
return React.cloneElement(child, {
...child.props,
key: eventKey,
key: this.generateTabKey(hash, eventKey, index),
classnames: classnames,
activeKey: activeKey
});

View File

@ -194,9 +194,14 @@ export interface TabsSchema extends BaseSchema {
addBtnText?: string;
/**
* hash值或索引值使
* hash值或索引值使
*/
activeKey?: SchemaExpression;
defaultKey?: SchemaExpression | number;
/**
* hash值或索引值使
*/
activeKey?: SchemaExpression | number;
/**
*
@ -213,6 +218,7 @@ export interface TabsProps
extends RendererProps,
Omit<TabsSchema, 'className' | 'contentClassName' | 'activeKey'> {
activeKey?: string | number;
defaultKey?: string | number;
location?: any;
tabRender?: (tab: TabSchema, props: TabsProps, index: number) => JSX.Element;
}
@ -258,8 +264,16 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
if (tab) {
activeKey = tab.hash;
} else if (props.defaultKey !== undefined) {
activeKey =
typeof props.defaultKey === 'string'
? resolveVariableAndFilter(props.defaultKey, props.data)
: props.defaultKey;
} else if (props.defaultActiveKey) {
activeKey = tokenize(props.defaultActiveKey, props.data);
activeKey = resolveVariableAndFilter(
props.defaultActiveKey,
props.data
);
}
activeKey = activeKey || (tabs[0] && tabs[0].hash) || 0;
@ -340,8 +354,14 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
componentDidUpdate(preProps: TabsProps, prevState: any) {
const props = this.props;
let localTabs = this.state.localTabs;
const prevActiveKey = tokenize(preProps.defaultActiveKey, preProps.data);
const activeKey = tokenize(props.defaultActiveKey, props.data);
const prevActiveKey = resolveVariableAndFilter(
preProps.defaultActiveKey,
preProps.data
);
const activeKey = resolveVariableAndFilter(
props.defaultActiveKey,
props.data
);
// 响应外部修改 tabs
const isTabsModified = isObjectShallowModified(
@ -438,7 +458,8 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
newActivedKey = activeKey;
}
if (newActivedKey) {
// newActivedKey 可以为 0
if (newActivedKey !== null) {
this.setState({
prevKey: prevActiveKey,
activeKey: (this.activeKey = newActivedKey)