feat: update tabs
parent
132a1e58bf
commit
8ce8e9a821
|
@ -1,12 +1,12 @@
|
|||
import { inject } from 'vue';
|
||||
import omit from 'omit.js';
|
||||
import Tabs from '../tabs';
|
||||
import Row from '../row';
|
||||
import Col from '../col';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { getComponent, getSlotOptions, filterEmpty, getListeners } from '../_util/props-util';
|
||||
import { getComponent, filterEmpty, getSlot } from '../_util/props-util';
|
||||
import BaseMixin from '../_util/BaseMixin';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
import isPlainObject from 'lodash/isPlainObject';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
export default {
|
||||
|
@ -54,7 +54,7 @@ export default {
|
|||
isContainGrid(obj = []) {
|
||||
let containGrid;
|
||||
obj.forEach(element => {
|
||||
if (element && getSlotOptions(element).__ANT_CARD_GRID) {
|
||||
if (element && isPlainObject(element.type) && element.type.__ANT_CARD_GRID) {
|
||||
containGrid = true;
|
||||
}
|
||||
});
|
||||
|
@ -75,18 +75,17 @@ export default {
|
|||
activeTabKey,
|
||||
defaultActiveTabKey,
|
||||
} = this.$props;
|
||||
|
||||
const children = getSlot(this);
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('card', customizePrefixCls);
|
||||
|
||||
const { $slots, $scopedSlots } = this;
|
||||
const tabBarExtraContent = getComponent(this, 'tabBarExtraContent');
|
||||
const classString = {
|
||||
[`${prefixCls}`]: true,
|
||||
[`${prefixCls}-loading`]: loading,
|
||||
[`${prefixCls}-bordered`]: bordered,
|
||||
[`${prefixCls}-hoverable`]: !!hoverable,
|
||||
[`${prefixCls}-contain-grid`]: this.isContainGrid($slots.default),
|
||||
[`${prefixCls}-contain-grid`]: this.isContainGrid(children),
|
||||
[`${prefixCls}-contain-tabs`]: tabList && tabList.length,
|
||||
[`${prefixCls}-${size}`]: size !== 'default',
|
||||
[`${prefixCls}-type-${type}`]: !!type,
|
||||
|
@ -142,16 +141,12 @@ export default {
|
|||
|
||||
const hasActiveTabKey = activeTabKey !== undefined;
|
||||
const tabsProps = {
|
||||
props: {
|
||||
size: 'large',
|
||||
[hasActiveTabKey ? 'activeKey' : 'defaultActiveKey']: hasActiveTabKey
|
||||
? activeTabKey
|
||||
: defaultActiveTabKey,
|
||||
tabBarExtraContent,
|
||||
},
|
||||
on: {
|
||||
change: this.onTabChange,
|
||||
},
|
||||
size: 'large',
|
||||
[hasActiveTabKey ? 'activeKey' : 'defaultActiveKey']: hasActiveTabKey
|
||||
? activeTabKey
|
||||
: defaultActiveTabKey,
|
||||
tabBarExtraContent,
|
||||
onChange: this.onTabChange,
|
||||
class: `${prefixCls}-head-tabs`,
|
||||
};
|
||||
|
||||
|
@ -160,10 +155,9 @@ export default {
|
|||
tabList && tabList.length ? (
|
||||
<Tabs {...tabsProps}>
|
||||
{tabList.map(item => {
|
||||
const { tab: temp, scopedSlots = {} } = item;
|
||||
const name = scopedSlots.tab;
|
||||
const tab =
|
||||
temp !== undefined ? temp : $scopedSlots[name] ? $scopedSlots[name](item) : null;
|
||||
const { tab: temp, children = {} } = item;
|
||||
const name = children.tab;
|
||||
const tab = temp !== undefined ? temp : children[name] ? children[name](item) : null;
|
||||
return <TabPane tab={tab} key={item.key} disabled={item.disabled} />;
|
||||
})}
|
||||
</Tabs>
|
||||
|
@ -182,7 +176,6 @@ export default {
|
|||
);
|
||||
}
|
||||
|
||||
const children = $slots.default;
|
||||
const cover = getComponent(this, 'cover');
|
||||
const coverDom = cover ? <div class={`${prefixCls}-cover`}>{cover}</div> : null;
|
||||
const body = (
|
||||
|
@ -190,18 +183,14 @@ export default {
|
|||
{loading ? loadingBlock : children}
|
||||
</div>
|
||||
);
|
||||
const actions = filterEmpty(this.$slots.actions);
|
||||
const actions = filterEmpty(getComponent(this, 'action'));
|
||||
const actionDom =
|
||||
actions && actions.length ? (
|
||||
<ul class={`${prefixCls}-actions`}>{this.getAction(actions)}</ul>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<div
|
||||
class={classString}
|
||||
ref="cardContainerRef"
|
||||
{...{ on: omit(getListeners(this), ['tabChange', 'tab-change']) }}
|
||||
>
|
||||
<div class={classString} ref="cardContainerRef">
|
||||
{head}
|
||||
{coverDom}
|
||||
{children ? body : null}
|
||||
|
|
|
@ -5,7 +5,7 @@ import RightOutlined from '@ant-design/icons-vue/RightOutlined';
|
|||
import ScrollableInkTabBar from '../vc-tabs/src/ScrollableInkTabBar';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { getListeners } from '../_util/props-util';
|
||||
|
||||
const TabBar = {
|
||||
name: 'TabBar',
|
||||
inheritAttrs: false,
|
||||
|
@ -55,25 +55,22 @@ const TabBar = {
|
|||
)}
|
||||
</span>
|
||||
);
|
||||
|
||||
// Additional className for style usage
|
||||
const cls = {
|
||||
[this.$attrs.class]: this.$attrs.class,
|
||||
[`${prefixCls}-${tabPosition}-bar`]: true,
|
||||
[`${prefixCls}-${size}-bar`]: !!size,
|
||||
[`${prefixCls}-card-bar`]: type && type.indexOf('card') >= 0,
|
||||
};
|
||||
|
||||
const renderProps = {
|
||||
props: {
|
||||
...this.$props,
|
||||
...this.$attrs,
|
||||
inkBarAnimated,
|
||||
extraContent: tabBarExtraContent,
|
||||
prevIcon,
|
||||
nextIcon,
|
||||
},
|
||||
...this.$props,
|
||||
...this.$attrs,
|
||||
inkBarAnimated,
|
||||
extraContent: tabBarExtraContent,
|
||||
prevIcon,
|
||||
nextIcon,
|
||||
style: tabBarStyle,
|
||||
on: getListeners(this),
|
||||
class: cls,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
import ref from 'vue-ref';
|
||||
import Vue from 'vue';
|
||||
import Tabs from './tabs';
|
||||
import TabPane from '../vc-tabs/src/TabPane';
|
||||
import TabContent from '../vc-tabs/src/TabContent';
|
||||
import Base from '../base';
|
||||
|
||||
Tabs.TabPane = { ...TabPane, name: 'ATabPane', __ANT_TAB_PANE: true };
|
||||
Tabs.TabContent = { ...TabContent, name: 'ATabContent' };
|
||||
Vue.use(ref, { name: 'ant-ref' });
|
||||
|
||||
/* istanbul ignore next */
|
||||
Tabs.install = function(Vue) {
|
||||
Vue.use(Base);
|
||||
Vue.component(Tabs.name, Tabs);
|
||||
Vue.component(Tabs.TabPane.name, Tabs.TabPane);
|
||||
Vue.component(Tabs.TabContent.name, Tabs.TabContent);
|
||||
Tabs.install = function(app) {
|
||||
app.component(Tabs.name, Tabs);
|
||||
app.component(Tabs.TabPane.name, Tabs.TabPane);
|
||||
app.component(Tabs.TabContent.name, Tabs.TabContent);
|
||||
};
|
||||
|
||||
export default Tabs;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { inject } from 'vue';
|
||||
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
|
||||
import PlusOutlined from '@ant-design/icons-vue/PlusOutlined';
|
||||
import VcTabs, { TabPane } from '../vc-tabs/src';
|
||||
|
@ -5,10 +6,12 @@ import TabContent from '../vc-tabs/src/TabContent';
|
|||
import { isFlexSupported } from '../_util/styleChecker';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import {
|
||||
getComponentFromProp,
|
||||
getComponent,
|
||||
getOptionProps,
|
||||
filterEmpty,
|
||||
getListeners,
|
||||
findDOMNode,
|
||||
getPropsData,
|
||||
getSlot,
|
||||
} from '../_util/props-util';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import isValid from '../_util/isValid';
|
||||
|
@ -37,12 +40,14 @@ export default {
|
|||
tabBarGutter: PropTypes.number,
|
||||
renderTabBar: PropTypes.func,
|
||||
},
|
||||
inject: {
|
||||
configProvider: { default: () => ConfigConsumerProps },
|
||||
setup() {
|
||||
return {
|
||||
configProvider: inject('configProvider', ConfigConsumerProps),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const NO_FLEX = ' no-flex';
|
||||
const tabNode = this.$el;
|
||||
const tabNode = findDOMNode(this);
|
||||
if (tabNode && !isFlexSupported && tabNode.className.indexOf(NO_FLEX) === -1) {
|
||||
tabNode.className += NO_FLEX;
|
||||
}
|
||||
|
@ -55,6 +60,7 @@ export default {
|
|||
}
|
||||
},
|
||||
handleChange(activeKey) {
|
||||
this.$emit('update:activeKey', activeKey);
|
||||
this.$emit('change', activeKey);
|
||||
},
|
||||
createNewTab(targetKey) {
|
||||
|
@ -82,11 +88,12 @@ export default {
|
|||
hideAdd,
|
||||
renderTabBar,
|
||||
} = props;
|
||||
const { class: className, style, ...restProps } = this.$attrs;
|
||||
const getPrefixCls = this.configProvider().getPrefixCls;
|
||||
const prefixCls = getPrefixCls('tabs', customizePrefixCls);
|
||||
const children = filterEmpty(this.$slots.default);
|
||||
const children = filterEmpty(getSlot(this));
|
||||
|
||||
let tabBarExtraContent = getComponentFromProp(this, 'tabBarExtraContent');
|
||||
let tabBarExtraContent = getComponent(this, 'tabBarExtraContent');
|
||||
let tabPaneAnimated = typeof animated === 'object' ? animated.tabPane : animated;
|
||||
|
||||
// card tabs should not have animation
|
||||
|
@ -94,6 +101,7 @@ export default {
|
|||
tabPaneAnimated = 'animated' in props ? tabPaneAnimated : false;
|
||||
}
|
||||
const cls = {
|
||||
[className]: className,
|
||||
[`${prefixCls}-vertical`]: tabPosition === 'left' || tabPosition === 'right',
|
||||
[`${prefixCls}-${size}`]: !!size,
|
||||
[`${prefixCls}-card`]: type.indexOf('card') >= 0,
|
||||
|
@ -105,7 +113,7 @@ export default {
|
|||
if (type === 'editable-card') {
|
||||
childrenWithClose = [];
|
||||
children.forEach((child, index) => {
|
||||
const props = getOptionProps(child);
|
||||
const props = getPropsData(child);
|
||||
let closable = props.closable;
|
||||
closable = typeof closable === 'undefined' ? true : closable;
|
||||
const closeIcon = closable ? (
|
||||
|
@ -116,14 +124,12 @@ export default {
|
|||
) : null;
|
||||
childrenWithClose.push(
|
||||
cloneElement(child, {
|
||||
props: {
|
||||
tab: (
|
||||
<div class={closable ? undefined : `${prefixCls}-tab-unclosable`}>
|
||||
{getComponentFromProp(child, 'tab')}
|
||||
{closeIcon}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
tab: (
|
||||
<div class={closable ? undefined : `${prefixCls}-tab-unclosable`}>
|
||||
{getComponent(child, 'tab')}
|
||||
{closeIcon}
|
||||
</div>
|
||||
),
|
||||
key: child.key || index,
|
||||
}),
|
||||
);
|
||||
|
@ -143,40 +149,33 @@ export default {
|
|||
<div class={`${prefixCls}-extra-content`}>{tabBarExtraContent}</div>
|
||||
) : null;
|
||||
|
||||
const renderTabBarSlot = renderTabBar || this.$scopedSlots.renderTabBar;
|
||||
const listeners = getListeners(this);
|
||||
const renderTabBarSlot = renderTabBar || this.$slots.renderTabBar;
|
||||
const tabBarProps = {
|
||||
props: {
|
||||
...this.$props,
|
||||
prefixCls,
|
||||
tabBarExtraContent,
|
||||
renderTabBar: renderTabBarSlot,
|
||||
},
|
||||
on: listeners,
|
||||
...this.$props,
|
||||
prefixCls,
|
||||
tabBarExtraContent,
|
||||
renderTabBar: renderTabBarSlot,
|
||||
...restProps,
|
||||
};
|
||||
const contentCls = {
|
||||
[`${prefixCls}-${tabPosition}-content`]: true,
|
||||
[`${prefixCls}-card-content`]: type.indexOf('card') >= 0,
|
||||
};
|
||||
const tabsProps = {
|
||||
props: {
|
||||
...getOptionProps(this),
|
||||
prefixCls,
|
||||
tabBarPosition: tabPosition,
|
||||
// https://github.com/vueComponent/ant-design-vue/issues/2030
|
||||
// 如仅传递 tabBarProps 会导致,第二次执行 renderTabBar 时,丢失 on 属性,
|
||||
// 添加key之后,会在babel jsx 插件中做一次merge,最终TabBar接收的是一个新的对象,而不是 tabBarProps
|
||||
renderTabBar: () => <TabBar key="tabBar" {...tabBarProps} />,
|
||||
renderTabContent: () => (
|
||||
<TabContent class={contentCls} animated={tabPaneAnimated} animatedWithMargin />
|
||||
),
|
||||
children: childrenWithClose.length > 0 ? childrenWithClose : children,
|
||||
__propsSymbol__: Symbol(),
|
||||
},
|
||||
on: {
|
||||
...listeners,
|
||||
change: this.handleChange,
|
||||
},
|
||||
...getOptionProps(this),
|
||||
prefixCls,
|
||||
tabBarPosition: tabPosition,
|
||||
// https://github.com/vueComponent/ant-design-vue/issues/2030
|
||||
// 如仅传递 tabBarProps 会导致,第二次执行 renderTabBar 时,丢失 on 属性,
|
||||
// 添加key之后,会在babel jsx 插件中做一次merge,最终TabBar接收的是一个新的对象,而不是 tabBarProps
|
||||
renderTabBar: () => <TabBar key="tabBar" {...tabBarProps} />,
|
||||
renderTabContent: () => (
|
||||
<TabContent class={contentCls} animated={tabPaneAnimated} animatedWithMargin />
|
||||
),
|
||||
children: childrenWithClose.length > 0 ? childrenWithClose : children,
|
||||
__propsSymbol__: Symbol(),
|
||||
...restProps,
|
||||
onChange: this.handleChange,
|
||||
class: cls,
|
||||
};
|
||||
return <VcTabs {...tabsProps} />;
|
||||
|
|
|
@ -2,6 +2,7 @@ import { cloneElement } from '../../_util/vnode';
|
|||
import PropTypes from '../../_util/vue-types';
|
||||
import BaseMixin from '../../_util/BaseMixin';
|
||||
import createRefHooks from '../../_util/createRefHooks';
|
||||
import { getSlot } from '../../_util/props-util';
|
||||
function noop() {}
|
||||
export default {
|
||||
name: 'TabBarRootNode',
|
||||
|
@ -26,7 +27,7 @@ export default {
|
|||
};
|
||||
const topOrBottom = tabBarPosition === 'top' || tabBarPosition === 'bottom';
|
||||
const tabBarExtraContentStyle = topOrBottom ? { float: 'right' } : {};
|
||||
const children = this.$slots.default;
|
||||
const children = getSlot(this);
|
||||
let newChildren = children;
|
||||
if (extraContent) {
|
||||
newChildren = [
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import warning from 'warning';
|
||||
import PropTypes from '../../_util/vue-types';
|
||||
import BaseMixin from '../../_util/BaseMixin';
|
||||
import { getOptionProps, getComponentFromProp } from '../../_util/props-util';
|
||||
import { getComponent, getPropsData } from '../../_util/props-util';
|
||||
import { isVertical } from './utils';
|
||||
import createRefHooks from '../../_util/createRefHooks';
|
||||
function noop() {}
|
||||
export default {
|
||||
name: 'TabBarTabsNode',
|
||||
|
@ -30,32 +31,25 @@ export default {
|
|||
direction,
|
||||
} = this.$props;
|
||||
const rst = [];
|
||||
const renderTabBarNode = this.renderTabBarNode || this.$scopedSlots.renderTabBarNode;
|
||||
const renderTabBarNode = this.renderTabBarNode || this.$slots.renderTabBarNode;
|
||||
children.forEach((child, index) => {
|
||||
if (!child) {
|
||||
return;
|
||||
}
|
||||
const props = getOptionProps(child);
|
||||
const props = getPropsData(child);
|
||||
const key = child.key;
|
||||
let cls = activeKey === key ? `${prefixCls}-tab-active` : '';
|
||||
cls += ` ${prefixCls}-tab`;
|
||||
const events = { on: {} };
|
||||
const disabled = props.disabled || props.disabled === '';
|
||||
const events = {};
|
||||
const disabled = props.disabled;
|
||||
if (disabled) {
|
||||
cls += ` ${prefixCls}-tab-disabled`;
|
||||
} else {
|
||||
events.on.click = () => {
|
||||
events.onClick = () => {
|
||||
this.__emit('tabClick', key);
|
||||
};
|
||||
}
|
||||
const directives = [];
|
||||
if (activeKey === key) {
|
||||
directives.push({
|
||||
name: 'ant-ref',
|
||||
value: saveRef('activeTab'),
|
||||
});
|
||||
}
|
||||
const tab = getComponentFromProp(child, 'tab');
|
||||
const tab = getComponent(child, 'tab');
|
||||
let gutter = tabBarGutter && index === children.length - 1 ? 0 : tabBarGutter;
|
||||
gutter = typeof gutter === 'number' ? `${gutter}px` : gutter;
|
||||
const marginProperty = direction === 'rtl' ? 'marginLeft' : 'marginRight';
|
||||
|
@ -72,7 +66,7 @@ export default {
|
|||
class={cls}
|
||||
key={key}
|
||||
style={style}
|
||||
{...{ directives }}
|
||||
{...createRefHooks(activeKey === key ? saveRef('activeTab') : noop)}
|
||||
>
|
||||
{tab}
|
||||
</div>
|
||||
|
@ -84,19 +78,6 @@ export default {
|
|||
rst.push(node);
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
{...{
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: this.saveRef('navTabsContainer'),
|
||||
},
|
||||
],
|
||||
}}
|
||||
>
|
||||
{rst}
|
||||
</div>
|
||||
);
|
||||
return <div {...createRefHooks(this.saveRef('navTabsContainer'))}>{rst}</div>;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -6,17 +6,15 @@ import {
|
|||
getTransformPropValue,
|
||||
getMarginStyle,
|
||||
} from './utils';
|
||||
import { getSlot } from '../../_util/props-util';
|
||||
export default {
|
||||
name: 'TabContent',
|
||||
props: {
|
||||
animated: { type: Boolean, default: true },
|
||||
animatedWithMargin: { type: Boolean, default: true },
|
||||
prefixCls: {
|
||||
default: 'ant-tabs',
|
||||
type: String,
|
||||
},
|
||||
animated: PropTypes.bool.def(true),
|
||||
animatedWithMargin: PropTypes.bool.def(true),
|
||||
prefixCls: PropTypes.string.def('ant-tabs'),
|
||||
activeKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
tabBarPosition: String,
|
||||
tabBarPosition: PropTypes.string,
|
||||
direction: PropTypes.string,
|
||||
destroyInactiveTabPane: PropTypes.bool,
|
||||
},
|
||||
|
@ -30,10 +28,9 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
getTabPanes() {
|
||||
getTabPanes(children) {
|
||||
const props = this.$props;
|
||||
const activeKey = props.activeKey;
|
||||
const children = this.$slots.default || [];
|
||||
const newChildren = [];
|
||||
|
||||
children.forEach(child => {
|
||||
|
@ -44,11 +41,9 @@ export default {
|
|||
const active = activeKey === key;
|
||||
newChildren.push(
|
||||
cloneElement(child, {
|
||||
props: {
|
||||
active,
|
||||
destroyInactiveTabPane: props.destroyInactiveTabPane,
|
||||
rootPrefixCls: props.prefixCls,
|
||||
},
|
||||
active,
|
||||
destroyInactiveTabPane: props.destroyInactiveTabPane,
|
||||
rootPrefixCls: props.prefixCls,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
@ -59,8 +54,9 @@ export default {
|
|||
render() {
|
||||
const { activeKey, tabBarPosition, animated, animatedWithMargin, direction, classes } = this;
|
||||
let style = {};
|
||||
if (animated && this.$slots.default) {
|
||||
const activeIndex = getActiveIndex(this.$slots.default, activeKey);
|
||||
const children = getSlot(this);
|
||||
if (animated && children) {
|
||||
const activeIndex = getActiveIndex(children, activeKey);
|
||||
if (activeIndex !== -1) {
|
||||
const animatedStyle = animatedWithMargin
|
||||
? getMarginStyle(activeIndex, tabBarPosition)
|
||||
|
@ -74,7 +70,7 @@ export default {
|
|||
}
|
||||
return (
|
||||
<div class={classes} style={style}>
|
||||
{this.getTabPanes()}
|
||||
{this.getTabPanes(children || [])}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { inject } from 'vue';
|
||||
import PropTypes from '../../_util/vue-types';
|
||||
import { getComponentFromProp } from '../../_util/props-util';
|
||||
import { getComponent, getSlot } from '../../_util/props-util';
|
||||
import Sentinel from './Sentinel';
|
||||
|
||||
export default {
|
||||
|
@ -14,13 +15,16 @@ export default {
|
|||
closable: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
},
|
||||
inject: {
|
||||
sentinelContext: { default: () => ({}) },
|
||||
setup() {
|
||||
return {
|
||||
_isActived: undefined,
|
||||
sentinelContext: inject('sentinelContext', {}),
|
||||
};
|
||||
},
|
||||
render() {
|
||||
const { destroyInactiveTabPane, active, forceRender, rootPrefixCls } = this.$props;
|
||||
const children = this.$slots.default;
|
||||
const placeholder = getComponentFromProp(this, 'placeholder');
|
||||
const children = getSlot(this);
|
||||
const placeholder = getComponent(this, 'placeholder');
|
||||
this._isActived = this._isActived || active;
|
||||
const prefixCls = `${rootPrefixCls}-tabpane`;
|
||||
const cls = {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import omit from 'omit.js';
|
||||
import { provide } from 'vue';
|
||||
import BaseMixin from '../../_util/BaseMixin';
|
||||
import PropTypes from '../../_util/vue-types';
|
||||
import raf from 'raf';
|
||||
import KeyCode from './KeyCode';
|
||||
import { getOptionProps, getListeners } from '../../_util/props-util';
|
||||
import { getOptionProps } from '../../_util/props-util';
|
||||
import { cloneElement } from '../../_util/vnode';
|
||||
import Sentinel from './Sentinel';
|
||||
import isValid from '../../_util/isValid';
|
||||
|
@ -28,10 +28,7 @@ function activeKeyIsValid(props, key) {
|
|||
export default {
|
||||
name: 'Tabs',
|
||||
mixins: [BaseMixin],
|
||||
model: {
|
||||
prop: 'activeKey',
|
||||
event: 'change',
|
||||
},
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
destroyInactiveTabPane: PropTypes.bool,
|
||||
renderTabBar: PropTypes.func.isRequired,
|
||||
|
@ -47,6 +44,7 @@ export default {
|
|||
tabBarGutter: PropTypes.number,
|
||||
},
|
||||
data() {
|
||||
provide('sentinelContext', this);
|
||||
const props = getOptionProps(this);
|
||||
let activeKey;
|
||||
if ('activeKey' in props) {
|
||||
|
@ -60,11 +58,6 @@ export default {
|
|||
_activeKey: activeKey,
|
||||
};
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
sentinelContext: this,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
__propsSymbol__() {
|
||||
const nextProps = getOptionProps(this);
|
||||
|
@ -86,12 +79,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
onTabClick(activeKey, e) {
|
||||
if (
|
||||
this.tabBar.componentOptions &&
|
||||
this.tabBar.componentOptions.listeners &&
|
||||
this.tabBar.componentOptions.listeners.tabClick
|
||||
) {
|
||||
this.tabBar.componentOptions.listeners.tabClick(activeKey, e);
|
||||
if (this.tabBar.props && this.tabBar.props.onTabClick) {
|
||||
this.tabBar.props.onTabClick(activeKey, e);
|
||||
}
|
||||
this.setActiveKey(activeKey);
|
||||
},
|
||||
|
@ -146,6 +135,7 @@ export default {
|
|||
_activeKey: activeKey,
|
||||
});
|
||||
}
|
||||
this.$emit('update:activeKey', activeKey);
|
||||
this.__emit('change', activeKey);
|
||||
}
|
||||
},
|
||||
|
@ -197,7 +187,9 @@ export default {
|
|||
direction,
|
||||
tabBarGutter,
|
||||
} = props;
|
||||
const { class: className, onChange, ...restProps } = this.$attrs;
|
||||
const cls = {
|
||||
[className]: className,
|
||||
[prefixCls]: 1,
|
||||
[`${prefixCls}-${tabBarPosition}`]: 1,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
|
@ -205,32 +197,24 @@ export default {
|
|||
|
||||
this.tabBar = renderTabBar();
|
||||
const tabBar = cloneElement(this.tabBar, {
|
||||
props: {
|
||||
prefixCls,
|
||||
navWrapper,
|
||||
tabBarPosition,
|
||||
panels: props.children,
|
||||
activeKey: this.$data._activeKey,
|
||||
direction,
|
||||
tabBarGutter,
|
||||
},
|
||||
on: {
|
||||
keydown: this.onNavKeyDown,
|
||||
tabClick: this.onTabClick,
|
||||
},
|
||||
prefixCls,
|
||||
navWrapper,
|
||||
tabBarPosition,
|
||||
panels: props.children,
|
||||
activeKey: this.$data._activeKey,
|
||||
direction,
|
||||
tabBarGutter,
|
||||
onKeydown: this.onNavKeyDown,
|
||||
onTabClick: this.onTabClick,
|
||||
key: 'tabBar',
|
||||
});
|
||||
const tabContent = cloneElement(renderTabContent(), {
|
||||
props: {
|
||||
prefixCls,
|
||||
tabBarPosition,
|
||||
activeKey: this.$data._activeKey,
|
||||
destroyInactiveTabPane,
|
||||
direction,
|
||||
},
|
||||
on: {
|
||||
change: this.setActiveKey,
|
||||
},
|
||||
prefixCls,
|
||||
tabBarPosition,
|
||||
activeKey: this.$data._activeKey,
|
||||
destroyInactiveTabPane,
|
||||
direction,
|
||||
onChange: this.setActiveKey,
|
||||
children: props.children,
|
||||
key: 'tabContent',
|
||||
});
|
||||
|
@ -257,10 +241,11 @@ export default {
|
|||
} else {
|
||||
contents.push(tabBar, sentinelStart, tabContent, sentinelEnd);
|
||||
}
|
||||
const listeners = {
|
||||
...omit(getListeners(this), ['change']),
|
||||
scroll: this.onScroll,
|
||||
const p = {
|
||||
...restProps,
|
||||
onScroll: this.onScroll,
|
||||
class: cls,
|
||||
};
|
||||
return <div {...{ on: listeners, class: cls }}>{contents}</div>;
|
||||
return <div {...p}>{contents}</div>;
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue