This commit is contained in:
tangjinzhou 2018-01-19 11:47:06 +08:00
parent aebed8b169
commit c4bc2bf7e5
12 changed files with 50 additions and 57 deletions

View File

@ -12,7 +12,6 @@ export default {
attr: $attrs, attr: $attrs,
on: $listeners, on: $listeners,
props: childProps, props: childProps,
addChildren: $slots.addChildren,
}) })
return children return children
}, },

View File

@ -46,7 +46,7 @@ export function cloneVNodes (vnodes, deep) {
export function cloneElement (n, nodeProps, clone) { export function cloneElement (n, nodeProps, clone) {
const node = clone ? cloneVNode(n, true) : n const node = clone ? cloneVNode(n, true) : n
const { props = {}, key, on = {}, addChildren } = nodeProps const { props = {}, key, on = {}} = nodeProps
const data = node.data || {} const data = node.data || {}
const { style = data.style, const { style = data.style,
class: cls = data.class, class: cls = data.class,
@ -59,10 +59,7 @@ export function cloneElement (n, nodeProps, clone) {
node.componentOptions.listeners = node.componentOptions.listeners || {} node.componentOptions.listeners = node.componentOptions.listeners || {}
node.componentOptions.propsData = { ...node.componentOptions.propsData, ...props } node.componentOptions.propsData = { ...node.componentOptions.propsData, ...props }
node.componentOptions.listeners = { ...node.componentOptions.listeners, ...on } node.componentOptions.listeners = { ...node.componentOptions.listeners, ...on }
node.componentOptions.children = node.componentOptions.children.filter(c => c.key !== '_ANT_PORTAL')
addChildren && node.componentOptions.children.push(...addChildren)
} else { } else {
addChildren && (node.children = [...(node.children || []), ...addChildren])
node.data.on = { ...(node.data.on || {}), ...on } node.data.on = { ...(node.data.on || {}), ...on }
} }

View File

@ -15,9 +15,7 @@
<Icon type="appstore" />Navigation Two <Icon type="appstore" />Navigation Two
</MenuItem> </MenuItem>
<SubMenu> <SubMenu>
<template slot="title"> <span slot="title"><Icon type="setting" />Navigation Three - Submenu</span>
<span><Icon type="setting" />Navigation Three - Submenu</span>
</template>
<MenuItemGroup title="Item 1"> <MenuItemGroup title="Item 1">
<MenuItem key="setting:1">Option 1</MenuItem> <MenuItem key="setting:1">Option 1</MenuItem>
<MenuItem key="setting:2">Option 2</MenuItem> <MenuItem key="setting:2">Option 2</MenuItem>

View File

@ -29,18 +29,14 @@
<span>Option 3</span> <span>Option 3</span>
</MenuItem> </MenuItem>
<SubMenu key="sub1"> <SubMenu key="sub1">
<template slot="title"> <span slot="title"><Icon type="mail" /><span>Navigation One</span></span>
<span><Icon type="mail" /><span>Navigation One</span></span>
</template>
<MenuItem key="5">Option 5</MenuItem> <MenuItem key="5">Option 5</MenuItem>
<MenuItem key="6">Option 6</MenuItem> <MenuItem key="6">Option 6</MenuItem>
<MenuItem key="7">Option 7</MenuItem> <MenuItem key="7">Option 7</MenuItem>
<MenuItem key="8">Option 8</MenuItem> <MenuItem key="8">Option 8</MenuItem>
</SubMenu> </SubMenu>
<SubMenu key="sub2"> <SubMenu key="sub2">
<template slot="title"> <span slot="title"><Icon type="appstore" /><span>Navigation Two</span></span>
<span><Icon type="appstore" /><span>Navigation Two</span></span>
</template>
<MenuItem key="9">Option 9</MenuItem> <MenuItem key="9">Option 9</MenuItem>
<MenuItem key="10">Option 10</MenuItem> <MenuItem key="10">Option 10</MenuItem>
<SubMenu key="sub3" title="Submenu"> <SubMenu key="sub3" title="Submenu">

View File

@ -1,26 +1,26 @@
<template> <template>
<div> <div>
<Tabs defaultActiveKey="2"> <Tabs defaultActiveKey="2">
<TabPane :tab="(h, tabKey) => renderTab(h, tabKey, 'apple')" key="1"> <TabPane :tab="(h) => renderTab(h, '1', 'apple')" key="1">
Tab 1 Tab 1
</TabPane> </TabPane>
<TabPane :tab="(h, tabKey) => renderTab(h, tabKey, 'android')" key="2"> <TabPane :tab="(h) => renderTab(h, '2', 'android')" key="2">
Tab 2 Tab 2
</TabPane> </TabPane>
</Tabs> </Tabs>
<Tabs defaultActiveKey="2"> <Tabs defaultActiveKey="2">
<span slot="tab_1">
<Icon type="apple" />
Tab 1
</span>
<TabPane key="1"> <TabPane key="1">
<span slot="tab">
<Icon type="apple" />
Tab 1
</span>
Tab 1 Tab 1
</TabPane> </TabPane>
<span slot="tab_2">
<Icon type="android" />
Tab 2
</span>
<TabPane key="2"> <TabPane key="2">
<span slot="tab">
<Icon type="android" />
Tab 2
</span>
Tab 2 Tab 2
</TabPane> </TabPane>
</Tabs> </Tabs>

View File

@ -1,7 +1,7 @@
<script> <script>
import Tabs from './src/Tabs' import Tabs from './src/Tabs'
import isFlexSupported from '../_util/isFlexSupported' import isFlexSupported from '../_util/isFlexSupported'
import hasProp from '../_util/props-util' import { hasProp, getComponentFromProp } from '../_util/props-util'
export default { export default {
props: { props: {
prefixCls: { type: String, default: 'ant-tabs' }, prefixCls: { type: String, default: 'ant-tabs' },
@ -83,7 +83,6 @@ export default {
defaultActiveKey, defaultActiveKey,
$slots, $slots,
} = this } = this
let { tabBarExtraContent } = this.$props
let { inkBarAnimated, tabPaneAnimated } = typeof animated === 'object' ? { // eslint-disable-line let { inkBarAnimated, tabPaneAnimated } = typeof animated === 'object' ? { // eslint-disable-line
inkBarAnimated: !!animated.inkBar, tabPaneAnimated: !!animated.tabPane, inkBarAnimated: !!animated.inkBar, tabPaneAnimated: !!animated.tabPane,
} : { } : {
@ -101,15 +100,11 @@ export default {
[`${prefixCls}-${type}`]: true, [`${prefixCls}-${type}`]: true,
[`${prefixCls}-no-animation`]: !tabPaneAnimated, [`${prefixCls}-no-animation`]: !tabPaneAnimated,
} }
tabBarExtraContent = tabBarExtraContent === undefined && $slots.tabBarExtraContent const tabBarExtraContent = getComponentFromProp(this, 'tabBarExtraContent')
? $slots.tabBarExtraContent : tabBarExtraContent
tabBarExtraContent = typeof tabBarExtraContent === 'function'
? tabBarExtraContent(createElement) : tabBarExtraContent
$slots.default && $slots.default.forEach(({ componentOptions, key: tabKey }) => { $slots.default && $slots.default.forEach(({ componentOptions, key: tabKey }) => {
if (componentOptions && componentOptions.propsData.tab === undefined) { if (componentOptions && componentOptions.propsData.tab === undefined) {
componentOptions.propsData.tab = $slots[`tab_${tabKey}`] const tab = (componentOptions.children || []).filter(({ data = {}}) => data.slot === 'tab')
? $slots[`tab_${tabKey}`] componentOptions.propsData.tab = tab
: null
} }
}) })
const tabBarProps = { const tabBarProps = {

View File

@ -29,13 +29,13 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| defaultActiveKey | 初始化选中面板的 key如果没有设置 activeKey | string | 第一个面板 | | defaultActiveKey | 初始化选中面板的 key如果没有设置 activeKey | string | 第一个面板 |
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | | hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false |
| size | 大小,提供 `default``small` 两种大小,仅当 `type="line"` 时生效。 | string | 'default' | | size | 大小,提供 `default``small` 两种大小,仅当 `type="line"` 时生效。 | string | 'default' |
| tabBarExtraContent | tab bar 上额外的元素 | string\|number\|Function | 无 | | tabBarExtraContent | tab bar 上额外的元素 | string\|Function\|slot | 无 |
| tabBarStyle | tab bar 的样式对象 | object | - | | tabBarStyle | tab bar 的样式对象 | object | - |
| tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | 'top' | | tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | 'top' |
| type | 页签的基本样式,可选 `line`、`card` `editable-card` 类型 | string | 'line' | | type | 页签的基本样式,可选 `line`、`card` `editable-card` 类型 | string | 'line' |
### 事件 ### 事件 emit
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| change | 切换面板的回调 | Function | 无 | | change | 切换面板的回调 | Function | 无 |
| edit | 新增和删除页签的回调,在 `type="editable-card"` 时有效 | (targetKey, action): void | 无 | | edit | 新增和删除页签的回调,在 `type="editable-card"` 时有效 | (targetKey, action): void | 无 |
@ -49,4 +49,4 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| --- | --- | --- | --- | | --- | --- | --- | --- |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false | | forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |
| key | 对应 activeKey | string | 无 | | key | 对应 activeKey | string | 无 |
| tab | 选项卡头显示文字 | string\|Function | 无 | | tab | 选项卡头显示文字 | string\|Function\|slot | 无 |

View File

@ -46,7 +46,7 @@ export default {
!disabled && this.__emit('tabClick', tabKey) !disabled && this.__emit('tabClick', tabKey)
} }
let tabC = typeof tab === 'function' ? child.tab(h, tabKey) : tab let tabC = typeof tab === 'function' ? child.tab(h) : tab
if (this.$parent.type === 'editable-card') { if (this.$parent.type === 'editable-card') {
closable = closable === undefined ? true : closable === '' || closable closable = closable === undefined ? true : closable === '' || closable
const closeIcon = closable ? ( const closeIcon = closable ? (

View File

@ -1,18 +1,8 @@
<template>
<div
role="tabpanel"
:aria-hidden="active ? 'false' : 'true'"
:class="classes"
>
<slot v-if="isRender || forceRender">
</slot>
</div>
</template>
<script> <script>
export default { export default {
name: 'TabPane', name: 'TabPane',
props: { props: {
tab: [String, Number, Function, Array], tab: [String, Number, Function, Array, Object],
disabled: Boolean, disabled: Boolean,
closable: Boolean, closable: Boolean,
forceRender: Boolean, forceRender: Boolean,
@ -47,5 +37,17 @@ export default {
}, },
methods: { methods: {
}, },
render () {
const { active, classes, $slots, isRender, forceRender } = this
return (
<div
role='tabpanel'
aria-hidden={active ? 'false' : 'true'}
class={classes}
>
{isRender || forceRender ? $slots.default : null}
</div>
)
},
} }
</script> </script>

View File

@ -162,9 +162,8 @@ export default {
$slots.default && $slots.default.forEach(({ componentOptions, key: tabKey }) => { $slots.default && $slots.default.forEach(({ componentOptions, key: tabKey }) => {
if (componentOptions) { if (componentOptions) {
if (componentOptions.propsData.tab === undefined) { if (componentOptions.propsData.tab === undefined) {
componentOptions.propsData.tab = $slots[`tab_${tabKey}`] const tab = (componentOptions.children || []).filter(({ data = {}}) => data.slot === 'tab')
? $slots[`tab_${tabKey}`] componentOptions.propsData.tab = tab
: null
} }
panels.push({ ...componentOptions.propsData, tabKey }) panels.push({ ...componentOptions.propsData, tabKey })
} }

View File

@ -1,7 +1,7 @@
<script> <script>
import PropTypes from '../_util/vue-types' import PropTypes from '../_util/vue-types'
import contains from '../_util/Dom/contains' import contains from '../_util/Dom/contains'
import hasProp from '../_util/props-util' import { hasProp, getComponentFromProp } from '../_util/props-util'
import addEventListener from '../_util/Dom/addEventListener' import addEventListener from '../_util/Dom/addEventListener'
import warning from '../_util/warning' import warning from '../_util/warning'
import Popup from './Popup' import Popup from './Popup'
@ -297,7 +297,7 @@ export default {
popupStyle, popupClassName, action, popupStyle, popupClassName, action,
popupAnimation, handleGetPopupClassFromAlign, getRootDomNode, popupAnimation, handleGetPopupClassFromAlign, getRootDomNode,
mask, zIndex, popupTransitionName, getPopupAlign, mask, zIndex, popupTransitionName, getPopupAlign,
maskAnimation, maskTransitionName, popup, $slots, getContainer } = this maskAnimation, maskTransitionName, getContainer } = this
const popupProps = { const popupProps = {
props: { props: {
prefixCls, prefixCls,
@ -328,8 +328,7 @@ export default {
<Popup <Popup
{...popupProps} {...popupProps}
> >
{typeof popup === 'function' ? popup(h) : popup} {getComponentFromProp(this, 'popup')}
{popup === undefined ? $slots.popup : null}
</Popup> </Popup>
) )
}, },
@ -513,7 +512,15 @@ export default {
} else { } else {
this._component = null this._component = null
} }
this._component && (newChildProps.addChildren = [this._component]) if (child.componentOptions) {
child.componentOptions.children = child.componentOptions.children || []
child.componentOptions.children = child.componentOptions.children.filter(c => c.key !== '_ANT_PORTAL')
this._component && child.componentOptions.children.push(this._component)
} else {
child.children = child.children || []
child.children = child.children.filter(c => c.key !== '_ANT_PORTAL')
this._component && child.children.push(this._component)
}
const trigger = cloneElement(child, newChildProps) const trigger = cloneElement(child, newChildProps)
return trigger return trigger
}, },

View File

@ -3,7 +3,7 @@ const AsyncComp = () => {
const com = pathnameArr[1] || 'button' const com = pathnameArr[1] || 'button'
const demo = pathnameArr[2] || 'index' const demo = pathnameArr[2] || 'index'
return { return {
component: import(`../components/menu/demo/${demo}.vue`), component: import(`../components/tabs/demo/${demo}.vue`),
} }
} }
export default [ export default [