diff --git a/components/tabs/InkTabBar.vue b/components/tabs/InkTabBar.vue index 48dafa1d2..bab261e8e 100644 --- a/components/tabs/InkTabBar.vue +++ b/components/tabs/InkTabBar.vue @@ -8,7 +8,7 @@ export default { render (h) { const inkBarNode = this.getInkBarNode() const tabs = this.getTabs(h) - return this.getRootNode([inkBarNode, tabs]) + return this.getRootNode([inkBarNode, tabs], h) }, } diff --git a/components/tabs/ScrollableInkTabBar.vue b/components/tabs/ScrollableInkTabBar.vue index 292633176..f04450b9f 100644 --- a/components/tabs/ScrollableInkTabBar.vue +++ b/components/tabs/ScrollableInkTabBar.vue @@ -10,7 +10,7 @@ export default { const inkBarNode = this.getInkBarNode() const tabs = this.getTabs(h) const scrollbarNode = this.getScrollBarNode([inkBarNode, tabs]) - return this.getRootNode(scrollbarNode) + return this.getRootNode(scrollbarNode, h) }, } diff --git a/components/tabs/ScrollableTabBar.vue b/components/tabs/ScrollableTabBar.vue index 3a1e83071..7abc2d748 100644 --- a/components/tabs/ScrollableTabBar.vue +++ b/components/tabs/ScrollableTabBar.vue @@ -9,7 +9,7 @@ export default { const inkBarNode = this.getInkBarNode() const tabs = this.getTabs(h) const scrollbarNode = this.getScrollBarNode([inkBarNode, tabs]) - return this.getRootNode(scrollbarNode) + return this.getRootNode(scrollbarNode, h) }, } diff --git a/components/tabs/ScrollableTabBarMixin.js b/components/tabs/ScrollableTabBarMixin.js index 3f91dd48a..6df86318b 100644 --- a/components/tabs/ScrollableTabBarMixin.js +++ b/components/tabs/ScrollableTabBarMixin.js @@ -27,20 +27,8 @@ export default { this.resizeEvent = addDOMEventListener(window, 'resize', debouncedResize) }, - updated (prevProps) { - const props = this.$props - if (prevProps && prevProps.tabBarPosition !== props.tabBarPosition) { - this.setOffset(0) - return - } - const nextPrev = this.setNextPrev() - // wait next, prev show hide - if (this.isNextPrevShown(this) !== this.isNextPrevShown(nextPrev)) { - Object.assign(this, this.scrollToActiveTab) - } else if (!prevProps || props.activeKey !== prevProps.activeKey) { - // can not use props.activeKey - this.scrollToActiveTab() - } + updated () { + this.updatedCal() }, beforeDestroy () { @@ -48,9 +36,17 @@ export default { this.resizeEvent.remove() } }, + watch: { + tabBarPosition (val) { + this.setOffset(0) + }, + }, methods: { updatedCal () { - + this.setNextPrev() + this.$nextTick(() => { + this.scrollToActiveTab() + }) }, setNextPrev () { const navNode = this.$refs.nav diff --git a/components/tabs/TabBarMixin.js b/components/tabs/TabBarMixin.js index f70010914..7f148de68 100644 --- a/components/tabs/TabBarMixin.js +++ b/components/tabs/TabBarMixin.js @@ -1,3 +1,4 @@ +import Icon from '../icon' export default { props: { prefixCls: { @@ -19,6 +20,16 @@ export default { }, activeKey: String, panels: Array, + extraContent: [String, Number, Function], + hideAdd: Boolean, + removeTab: { + default: () => {}, + type: Function, + }, + createNewTab: { + default: () => {}, + type: Function, + }, }, methods: { getTabs (h) { @@ -28,33 +39,46 @@ export default { if (!child) { return } + let { disabled, closable } = child + const { tabKey, tab } = child // componentOptions.propsData中获取的值disabled没有根据类型初始化, 会出现空字符串 - child.disabled = child.disabled === '' || child.disabled - const key = child.tabKey - let cls = activeKey === key ? `${prefixCls}-tab-active` : '' + disabled = disabled === '' || disabled + let cls = activeKey === tabKey ? `${prefixCls}-tab-active` : '' cls += ` ${prefixCls}-tab` - if (child.disabled) { + if (disabled) { cls += ` ${prefixCls}-tab-disabled` } else { } const onClick = () => { - !child.disabled && this.onTabClick(key) + !disabled && this.onTabClick(tabKey) } - // const ref = {} - // if (activeKey === key) { - // ref.ref = this.saveRef('activeTab') - // } + + let tabC = typeof tab === 'function' ? child.tab(h, tabKey) : tab + if (this.$parent.type === 'editable-card') { + closable = closable === undefined ? true : closable === '' || closable + const closeIcon = closable ? ( + this.removeTab(tabKey, e)} + /> + ) : null + tabC =
+ {tabC} + {closeIcon} +
+ } + rst.push( ) }) @@ -63,23 +87,35 @@ export default { }, getRootNode (contents, createElement) { const { - prefixCls, onKeyDown, tabBarPosition, $slots, + prefixCls, onKeyDown, tabBarPosition, hideAdd, } = this + let extraContent = this.extraContent + const tabsType = this.$parent.type const cls = { [`${prefixCls}-bar`]: true, } const topOrBottom = (tabBarPosition === 'top' || tabBarPosition === 'bottom') const tabBarExtraContentStyle = topOrBottom ? { float: 'right' } : {} let children = contents - if ($slots.default) { - children = [ -
- {$slots.default} -
, - contents, - ] - children = topOrBottom ? children : children.reverse() + extraContent = typeof extraContent === 'function' ? extraContent(createElement) : extraContent + + if (tabsType === 'editable-card' && !hideAdd) { + extraContent = ( + + + {extraContent} + + ) } + + children = [ +
+ {extraContent} +
, + contents, + ] + children = topOrBottom ? children : children.reverse() + return (
- +
@@ -14,12 +14,10 @@ export default { props: { tabKey: [String, Number], tab: [String, Number, Function], - forceRender: Boolean, disabled: Boolean, - // placeholder: [Function, String, Number], + closable: Boolean, }, data () { - console.log(this.disabled) return { } }, diff --git a/components/tabs/Tabs.vue b/components/tabs/Tabs.vue index 94b61f883..e99854e27 100644 --- a/components/tabs/Tabs.vue +++ b/components/tabs/Tabs.vue @@ -45,6 +45,13 @@ export default { destroyInactiveTabPane: Boolean, activeKey: String, defaultActiveKey: String, + type: { + validator (value) { + return ['line', 'card', 'editable-card'].includes(value) + }, + }, + onChange: { type: Function, default: () => {} }, + onTabClick: { type: Function, default: () => {} }, }, data () { return { @@ -79,11 +86,8 @@ export default { } return activeKey }, - onTabClick (activeKey) { - console.log('onTabClick', activeKey) - // if (this.tabBar.props.onTabClick) { - // this.tabBar.props.onTabClick(activeKey) - // } + handleTabClick (activeKey) { + this.onTabClick(activeKey) this.setActiveKey(activeKey) }, @@ -92,11 +96,11 @@ export default { if (eventKeyCode === KeyCode.RIGHT || eventKeyCode === KeyCode.DOWN) { e.preventDefault() const nextKey = this.getNextActiveKey(true) - this.onTabClick(nextKey) + this.handleTabClick(nextKey) } else if (eventKeyCode === KeyCode.LEFT || eventKeyCode === KeyCode.UP) { e.preventDefault() const previousKey = this.getNextActiveKey(false) - this.onTabClick(previousKey) + this.handleTabClick(previousKey) } }, @@ -105,8 +109,7 @@ export default { if (!this.activeKey) { this.stateActiveKey = activeKey } - // this.stateActiveKey = activeKey - this.$emit('change', activeKey) + this.onChange(activeKey) } }, @@ -115,7 +118,7 @@ export default { const children = [] this.$slots.default.forEach(({ componentOptions = {}}) => { const c = componentOptions.propsData - if (c && !c.disabled) { + if (c && !c.disabled && c.disabled !== '') { if (next) { children.push(c) } else { @@ -145,7 +148,7 @@ export default { tabBarPosition, destroyInactiveTabPane, onNavKeyDown, - onTabClick, + handleTabClick, stateActiveKey, classes, setActiveKey, @@ -176,16 +179,14 @@ export default { prefixCls: prefixCls, onKeyDown: onNavKeyDown, tabBarPosition: tabBarPosition, - onTabClick: onTabClick, + onTabClick: handleTabClick, activeKey: stateActiveKey, key: 'tabBar', }, style: this.tabBarProps.style || {}, } const contents = [ - - {this.$slots.tabBarExtraContent} - , + , {$slots.default} , diff --git a/components/tabs/demo/card-top.vue b/components/tabs/demo/card-top.vue new file mode 100644 index 000000000..444ab42f8 --- /dev/null +++ b/components/tabs/demo/card-top.vue @@ -0,0 +1,69 @@ + + + diff --git a/components/tabs/demo/card.vue b/components/tabs/demo/card.vue new file mode 100644 index 000000000..916b8acdc --- /dev/null +++ b/components/tabs/demo/card.vue @@ -0,0 +1,25 @@ + + diff --git a/components/tabs/demo/custom-add-trigger.vue b/components/tabs/demo/custom-add-trigger.vue new file mode 100644 index 000000000..bfb7317aa --- /dev/null +++ b/components/tabs/demo/custom-add-trigger.vue @@ -0,0 +1,69 @@ + + diff --git a/components/tabs/demo/editable-card.vue b/components/tabs/demo/editable-card.vue new file mode 100644 index 000000000..ecf56dfb9 --- /dev/null +++ b/components/tabs/demo/editable-card.vue @@ -0,0 +1,61 @@ + + diff --git a/components/tabs/demo/extra.vue b/components/tabs/demo/extra.vue new file mode 100644 index 000000000..a0f206665 --- /dev/null +++ b/components/tabs/demo/extra.vue @@ -0,0 +1,21 @@ + + diff --git a/components/tabs/demo/index.vue b/components/tabs/demo/index.vue new file mode 100644 index 000000000..192a15f49 --- /dev/null +++ b/components/tabs/demo/index.vue @@ -0,0 +1,54 @@ + + diff --git a/components/tabs/demo/position.vue b/components/tabs/demo/position.vue new file mode 100644 index 000000000..e79faf24c --- /dev/null +++ b/components/tabs/demo/position.vue @@ -0,0 +1,38 @@ + + diff --git a/components/tabs/demo/size.vue b/components/tabs/demo/size.vue new file mode 100644 index 000000000..7ccecdee5 --- /dev/null +++ b/components/tabs/demo/size.vue @@ -0,0 +1,16 @@ + + diff --git a/components/tabs/demo/slide.vue b/components/tabs/demo/slide.vue index 514e7b1af..8b9158181 100644 --- a/components/tabs/demo/slide.vue +++ b/components/tabs/demo/slide.vue @@ -1,10 +1,10 @@