pull/9/head
tjz 2018-02-24 18:12:24 +08:00
parent 1197d88798
commit 0eb2ba5864
22 changed files with 137 additions and 108 deletions

View File

@ -30,12 +30,28 @@ const getOptionProps = (instance) => {
} }
const getComponentFromProp = (instance, prop) => { const getComponentFromProp = (instance, prop) => {
if (instance.$createElement) {
const h = instance.$createElement const h = instance.$createElement
const temp = instance[prop] const temp = instance[prop]
if (temp !== undefined) { if (temp !== undefined) {
return typeof temp === 'function' ? temp(h) : temp return typeof temp === 'function' ? temp(h) : temp
} }
return instance.$slots[prop] return instance.$slots[prop]
} else {
const h = instance.context.$createElement
const temp = getPropsData(instance)[prop]
if (temp !== undefined) {
return typeof temp === 'function' ? temp(h) : temp
}
const slotsProp = []
const componentOptions = instance.componentOptions || {};
(componentOptions.children || []).forEach((child) => {
if (child.data && child.data.slot === prop) {
slotsProp.push(child)
}
})
return slotsProp.length ? slotsProp : undefined
}
} }
const getPropsData = (ele) => { const getPropsData = (ele) => {
@ -45,6 +61,9 @@ const getPropsData = (ele) => {
} }
return componentOptions ? componentOptions.propsData || {} : {} return componentOptions ? componentOptions.propsData || {} : {}
} }
const getValueByProp = (ele, prop) => {
return getPropsData(ele)[prop]
}
const getAttrs = (ele) => { const getAttrs = (ele) => {
let data = ele.data let data = ele.data
@ -61,6 +80,50 @@ const getKey = (ele) => {
} }
return key return key
} }
export function getEvents (child) {
let events = {}
if (child.componentOptions && child.componentOptions.listeners) {
events = child.componentOptions.listeners
} else if (child.data && child.data.on) {
events = child.data.on
}
return { ...events }
}
export function getClass (ele) {
let data = {}
if (ele.data) {
data = ele.data
} else if (ele.$vnode && ele.$vnode.data) {
data = ele.$vnode.data
}
return data.class || data.staticClass
}
export function getStyle (ele) {
let data = {}
if (ele.data) {
data = ele.data
} else if (ele.$vnode && ele.$vnode.data) {
data = ele.$vnode.data
}
return data.style || data.staticStyle
}
export function getComponentName (opts) {
return opts && (opts.Ctor.options.name || opts.tag)
}
export function isValidElement (ele) {
return !!ele.tag
}
export function isEmptyElement (ele) {
return !(ele.tag || ele.text.trim() !== '')
}
export function filterEmpty (children = []) {
return children.filter(c => c.tag || c.text.trim() !== '')
}
export { export {
hasProp, hasProp,
filterProps, filterProps,
@ -71,5 +134,6 @@ export {
getPropsData, getPropsData,
getKey, getKey,
getAttrs, getAttrs,
getValueByProp,
} }
export default hasProp export default hasProp

View File

@ -1,3 +1,4 @@
import { filterEmpty } from './props-util'
export function cloneVNode (vnode, deep) { export function cloneVNode (vnode, deep) {
const componentOptions = vnode.componentOptions const componentOptions = vnode.componentOptions
const data = vnode.data const data = vnode.data
@ -89,54 +90,4 @@ export function cloneElement (n, nodeProps, clone) {
} }
return node return node
} }
export function getComponentName (opts) {
return opts && (opts.Ctor.options.name || opts.tag)
}
export function isValidElement (ele) {
return !!ele.tag
}
export function isEmptyElement (ele) {
return !(ele.tag || ele.text.trim() !== '')
}
export function getClass (ele) {
let data = {}
if (ele.data) {
data = ele.data
} else if (ele.$vnode && ele.$vnode.data) {
data = ele.$vnode.data
}
return data.class || data.staticClass
}
export function getStyle (ele) {
let data = {}
if (ele.data) {
data = ele.data
} else if (ele.$vnode && ele.$vnode.data) {
data = ele.$vnode.data
}
return data.style || data.staticStyle
}
export function filterEmpty (children = []) {
return children.filter(c => c.tag || c.text.trim() !== '')
}
export function getPropsData (ele) {
return ele.componentOptions && ele.componentOptions.propsData
}
export function getValueByProp (ele, prop) {
return ele.componentOptions && ele.componentOptions.propsData && ele.componentOptions.propsData[prop]
}
export function getEvents (child) {
let events = {}
if (child.componentOptions && child.componentOptions.listeners) {
events = child.componentOptions.listeners
} else if (child.data && child.data.on) {
events = child.data.on
}
return { ...events }
}

View File

@ -1,5 +1,5 @@
<script> <script>
import { filterEmpty } from '../_util/vnode' import { filterEmpty } from '../_util/props-util'
const ButtonGroupProps = { const ButtonGroupProps = {
prefixCls: { prefixCls: {
default: 'ant-btn-group', default: 'ant-btn-group',

View File

@ -3,8 +3,7 @@
import omit from 'omit.js' import omit from 'omit.js'
import PropTypes from '../_util/vue-types' import PropTypes from '../_util/vue-types'
import addEventListener from '../_util/Dom/addEventListener' import addEventListener from '../_util/Dom/addEventListener'
import { hasProp, getComponentFromProp } from '../_util/props-util' import { hasProp, getComponentFromProp, getComponentName } from '../_util/props-util'
import { getComponentName } from '../_util/vnode'
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame' import throttleByAnimationFrame from '../_util/throttleByAnimationFrame'
import BaseMixin from '../_util/BaseMixin' import BaseMixin from '../_util/BaseMixin'

View File

@ -1,8 +1,8 @@
<script> <script>
import PropTypes from '../../_util/vue-types' import PropTypes from '../../_util/vue-types'
import BaseMixin from '../../_util/BaseMixin' import BaseMixin from '../../_util/BaseMixin'
import { hasProp } from '../../_util/props-util' import { hasProp, getPropsData, isEmptyElement } from '../../_util/props-util'
import { cloneElement, getPropsData, isEmptyElement } from '../../_util/vnode' import { cloneElement } from '../../_util/vnode'
import openAnimationFactory from './openAnimationFactory' import openAnimationFactory from './openAnimationFactory'
import { collapseProps } from './commonProps' import { collapseProps } from './commonProps'

View File

@ -3,8 +3,8 @@ import RcDropdown from './src/index'
import DropdownButton from './dropdown-button' import DropdownButton from './dropdown-button'
// import warning from '../_util/warning' // import warning from '../_util/warning'
import PropTypes from '../_util/vue-types' import PropTypes from '../_util/vue-types'
import { cloneElement, getPropsData } from '../_util/vnode' import { cloneElement } from '../_util/vnode'
import { getOptionProps } from '../_util/props-util' import { getOptionProps, getPropsData } from '../_util/props-util'
import getDropdownProps from './getDropdownProps' import getDropdownProps from './getDropdownProps'
const DropdownProps = getDropdownProps() const DropdownProps = getDropdownProps()
const Dropdown = { const Dropdown = {

View File

@ -2,9 +2,9 @@
import PropTypes from '../../_util/vue-types' import PropTypes from '../../_util/vue-types'
import Trigger from '../../trigger' import Trigger from '../../trigger'
import placements from './placements' import placements from './placements'
import { hasProp } from '../../_util/props-util' import { hasProp, getEvents } from '../../_util/props-util'
import BaseMixin from '../../_util/BaseMixin' import BaseMixin from '../../_util/BaseMixin'
import { cloneElement, getEvents, cloneVNode } from '../../_util/vnode' import { cloneElement, cloneVNode } from '../../_util/vnode'
export default { export default {
mixins: [BaseMixin], mixins: [BaseMixin],

View File

@ -15,7 +15,7 @@ export default {
}, },
methods: { methods: {
getLocale () { getLocale () {
const { componentName, defaultLocale } = this.props const { componentName, defaultLocale } = this
const { antLocale } = this const { antLocale } = this
const localeFromContext = antLocale && antLocale[componentName] const localeFromContext = antLocale && antLocale[componentName]
return { return {

View File

@ -1,6 +1,7 @@
<script> <script>
import { Item, itemProps } from '../vc-menu' import { Item, itemProps } from '../vc-menu'
import { getClass, getStyle, cloneVNodes } from '../_util/vnode' import { getClass, getStyle } from '../_util/props-util'
import { cloneVNodes } from '../_util/vnode'
import Tooltip from '../tooltip' import Tooltip from '../tooltip'
function noop () {} function noop () {}
export default { export default {

View File

@ -3,6 +3,7 @@ import PropTypes from '../_util/vue-types'
import VcSelect, { Option, OptGroup } from '../vc-select' import VcSelect, { Option, OptGroup } from '../vc-select'
import LocaleReceiver from '../locale-provider/LocaleReceiver' import LocaleReceiver from '../locale-provider/LocaleReceiver'
import defaultLocale from '../locale-provider/default' import defaultLocale from '../locale-provider/default'
import { getComponentFromProp } from '../_util/props-util'
const AbstractSelectProps = { const AbstractSelectProps = {
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
@ -85,7 +86,8 @@ export default {
this.$refs.vcSelect.blur() this.$refs.vcSelect.blur()
}, },
getNotFoundContent (locale) { getNotFoundContent (locale) {
const { notFoundContent, mode } = this.$props const { mode } = this.$props
const notFoundContent = getComponentFromProp(this, 'notFoundContent')
const isCombobox = mode === 'combobox' const isCombobox = mode === 'combobox'
if (isCombobox) { if (isCombobox) {
// AutoComplete don't have notFoundContent defaultly // AutoComplete don't have notFoundContent defaultly
@ -117,17 +119,22 @@ export default {
tags: mode === 'tags', tags: mode === 'tags',
combobox: isCombobox, combobox: isCombobox,
} }
const selectProps = {
props: {
...restProps,
...modeConfig,
prefixCls,
optionLabelProp: optionLabelProp || 'children',
notFoundContent: this.getNotFoundContent(locale),
maxTagPlaceholder: getComponentFromProp(this, 'maxTagPlaceholder'),
},
on: this.$listeners,
class: cls,
ref: 'vcSelect',
}
return ( return (
<VcSelect <VcSelect {...selectProps}>
{...restProps}
{...modeConfig}
prefixCls={prefixCls}
class={cls}
optionLabelProp={optionLabelProp || 'children'}
notFoundContent={this.getNotFoundContent(locale)}
ref='vcSelect'
>
{this.$slots.default} {this.$slots.default}
</VcSelect> </VcSelect>
) )

View File

@ -2,7 +2,7 @@
import PropTypes from '../_util/vue-types' import PropTypes from '../_util/vue-types'
import BaseMixin from '../_util/BaseMixin' import BaseMixin from '../_util/BaseMixin'
import isCssAnimationSupported from '../_util/isCssAnimationSupported' import isCssAnimationSupported from '../_util/isCssAnimationSupported'
import { filterEmpty } from '../_util/vnode' import { filterEmpty } from '../_util/props-util'
import getTransitionProps from '../_util/getTransitionProps' import getTransitionProps from '../_util/getTransitionProps'
export default { export default {

View File

@ -1,8 +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, getComponentFromProp } from '../_util/props-util' import { hasProp, getComponentFromProp, getComponentName, isEmptyElement } from '../_util/props-util'
import { getComponentName, isEmptyElement } from '../_util/vnode'
import warning from '../_util/warning' import warning from '../_util/warning'
export default { export default {
props: { props: {

View File

@ -36,7 +36,6 @@ export default {
}, },
tagStyle () { tagStyle () {
const { color, isPresetColor } = this const { color, isPresetColor } = this
console.log(color, isPresetColor)
return { return {
backgroundColor: (color && !isPresetColor) ? color : null, backgroundColor: (color && !isPresetColor) ? color : null,
} }

View File

@ -1,9 +1,9 @@
<script> <script>
import { cloneElement, isValidElement, getClass, getStyle } from '../_util/vnode' import { cloneElement } from '../_util/vnode'
import RcTooltip from './src/Tooltip' import RcTooltip from './src/Tooltip'
import getPlacements from './placements' import getPlacements from './placements'
import PropTypes from '../_util/vue-types' import PropTypes from '../_util/vue-types'
import { hasProp, getComponentFromProp } from '../_util/props-util' import { hasProp, getComponentFromProp, getClass, getStyle, isValidElement } from '../_util/props-util'
import abstractTooltipProps from './abstractTooltipProps' import abstractTooltipProps from './abstractTooltipProps'
const splitObject = (obj, keys) => { const splitObject = (obj, keys) => {

View File

@ -2,14 +2,14 @@
import Vue from 'vue' import Vue from 'vue'
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, getComponentFromProp } from '../_util/props-util' import { hasProp, getComponentFromProp, getEvents, filterEmpty } from '../_util/props-util'
import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout' import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout'
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'
import { getAlignFromPlacement, getPopupClassNameFromAlign, noop } from './utils' import { getAlignFromPlacement, getPopupClassNameFromAlign, noop } from './utils'
import BaseMixin from '../_util/BaseMixin' import BaseMixin from '../_util/BaseMixin'
import { cloneElement, filterEmpty, getEvents, cloneVNode } from '../_util/vnode' import { cloneElement, cloneVNode } from '../_util/vnode'
function returnEmptyString () { function returnEmptyString () {
return '' return ''

View File

@ -1,8 +1,8 @@
import hasProp from '../_util/props-util' import { hasProp, getComponentName } from '../_util/props-util'
import KeyCode from '../_util/KeyCode' import KeyCode from '../_util/KeyCode'
import scrollIntoView from 'dom-scroll-into-view' import scrollIntoView from 'dom-scroll-into-view'
import { getKeyFromChildrenIndex, loopMenuItem } from './util' import { getKeyFromChildrenIndex, loopMenuItem } from './util'
import { cloneElement, getComponentName } from '../_util/vnode' import { cloneElement } from '../_util/vnode'
import DOMWrap from './DOMWrap' import DOMWrap from './DOMWrap'
import warning from '../_util/warning' import warning from '../_util/warning'

View File

@ -1,6 +1,6 @@
<script> <script>
import PropTypes from '../_util/vue-types' import PropTypes from '../_util/vue-types'
import { getStyle } from '../_util/vnode' import { getStyle } from '../_util/props-util'
import BaseMixin from '../_util/BaseMixin' import BaseMixin from '../_util/BaseMixin'
export default { export default {

View File

@ -1,7 +1,7 @@
<script> <script>
import Vue from 'vue' import Vue from 'vue'
import PropTypes from '../_util/vue-types' import PropTypes from '../_util/vue-types'
import { getStyle } from '../_util/vnode' import { getStyle } from '../_util/props-util'
import BaseMixin from '../_util/BaseMixin' import BaseMixin from '../_util/BaseMixin'
import createChainedFunction from '../_util/createChainedFunction' import createChainedFunction from '../_util/createChainedFunction'
import getTransitionProps from '../_util/getTransitionProps' import getTransitionProps from '../_util/getTransitionProps'

View File

@ -6,9 +6,9 @@ import classes from 'component-classes'
import { Item as MenuItem, ItemGroup as MenuItemGroup } from '../vc-menu' import { Item as MenuItem, ItemGroup as MenuItemGroup } from '../vc-menu'
import warning from 'warning' import warning from 'warning'
import Option from './Option' import Option from './Option'
import { hasProp, getSlotOptions } from '../_util/props-util' import { hasProp, getSlotOptions, getPropsData, getValueByProp as getValue, getComponentFromProp, getEvents, getClass } from '../_util/props-util'
import getTransitionProps from '../_util/getTransitionProps' import getTransitionProps from '../_util/getTransitionProps'
import { cloneElement, getClass, getPropsData, getValueByProp as getValue, getEvents } from '../_util/vnode' import { cloneElement } from '../_util/vnode'
import BaseMixin from '../_util/BaseMixin' import BaseMixin from '../_util/BaseMixin'
import { import {
getPropValue, getPropValue,
@ -195,7 +195,7 @@ export default {
}, },
updateLabelAndTitleMap (children = []) { updateLabelAndTitleMap (children = []) {
children.forEach(child => { children.forEach(child => {
if (!child) { if (!child || (child.data && child.data.slot !== undefined)) {
return return
} }
if (getSlotOptions(child).isSelectOptGroup) { if (getSlotOptions(child).isSelectOptGroup) {
@ -435,7 +435,7 @@ export default {
} else if (isMultipleOrTags(props) && inputValue) { } else if (isMultipleOrTags(props) && inputValue) {
this.inputValue = this.getInputDOMNode().value = '' this.inputValue = this.getInputDOMNode().value = ''
} }
this.__emit('blur', this.getVLForOnChange(sValue)) this.$emit('blur', this.getVLForOnChange(sValue))
this.setOpenState(false) this.setOpenState(false)
}, 10) }, 10)
}, },
@ -472,7 +472,7 @@ export default {
values = [value] values = [value]
} }
children.forEach(child => { children.forEach(child => {
if (!child) { if (!child || (child.data && child.data.slot !== undefined)) {
return return
} }
if (getSlotOptions(child).isSelectOptGroup) { if (getSlotOptions(child).isSelectOptGroup) {
@ -526,7 +526,7 @@ export default {
} }
let label = null let label = null
children.forEach(child => { children.forEach(child => {
if (!child) { if (!child || (child.data && child.data.slot !== undefined)) {
return return
} }
if (getSlotOptions(child).isSelectOptGroup) { if (getSlotOptions(child).isSelectOptGroup) {
@ -547,7 +547,7 @@ export default {
} }
let value = null let value = null
children.forEach(child => { children.forEach(child => {
if (!child) { if (!child || (child.data && child.data.slot !== undefined)) {
return return
} }
if (getSlotOptions(child).isSelectOptGroup) { if (getSlotOptions(child).isSelectOptGroup) {
@ -675,7 +675,7 @@ export default {
} else if (isMultipleOrTags(props) && inputValue) { } else if (isMultipleOrTags(props) && inputValue) {
this.inputValue = this.getInputDOMNode().value = '' this.inputValue = this.getInputDOMNode().value = ''
} }
this.__emit('blur', this.getVLForOnChange(sValue)) this.$emit('blur', this.getVLForOnChange(sValue))
this.setOpenState(false) this.setOpenState(false)
}, 10) }, 10)
}, },
@ -786,7 +786,7 @@ export default {
inputValue, inputValue,
}) })
if (fireSearch) { if (fireSearch) {
this.__emit('search', inputValue) this.$emit('search', inputValue)
} }
} }
}, },
@ -861,7 +861,7 @@ export default {
this.focusTimer = setTimeout(() => { this.focusTimer = setTimeout(() => {
this._focused = true this._focused = true
this.updateFocusClassName() this.updateFocusClassName()
this.__emit('focus') this.$emit('focus')
}, 10) }, 10)
}, },
@ -973,7 +973,7 @@ export default {
label, label,
} }
} }
this.__emit('deselect', event, this.getSingleOptionByValueKey(selectedKey)) this.$emit('deselect', event, this.getSingleOptionByValueKey(selectedKey))
} }
this.fireChange(value) this.fireChange(value)
}, },
@ -986,7 +986,7 @@ export default {
}, },
fireSelect (value) { fireSelect (value) {
const { labelInValue } = this const { labelInValue } = this
this.__emit('select', labelInValue ? value : value.key, this.getSingleOptionByValueKey(value.key)) this.$emit('select', labelInValue ? value : value.key, this.getSingleOptionByValueKey(value.key))
}, },
fireChange (value) { fireChange (value) {
if (!hasProp(this, 'value')) { if (!hasProp(this, 'value')) {
@ -997,7 +997,7 @@ export default {
const vls = this.getVLForOnChange(value) const vls = this.getVLForOnChange(value)
const options = this.getOptionsByValue(value) const options = this.getOptionsByValue(value)
this._valueOptions = options this._valueOptions = options
this.__emit('change', vls, isMultipleOrTags(this.$props) ? options : options[0]) this.$emit('change', vls, isMultipleOrTags(this.$props) ? options : options[0])
}, },
isChildDisabled (key) { isChildDisabled (key) {
@ -1159,7 +1159,7 @@ export default {
const { inputValue } = this const { inputValue } = this
const tags = props.tags const tags = props.tags
children.forEach(child => { children.forEach(child => {
if (!child) { if (!child || (child.data && child.data.slot !== undefined)) {
return return
} }
if (getSlotOptions(child).isSelectOptGroup) { if (getSlotOptions(child).isSelectOptGroup) {
@ -1169,7 +1169,7 @@ export default {
menuItems, menuItems,
) )
if (innerItems.length) { if (innerItems.length) {
let label = getValue(child, 'label') let label = getComponentFromProp(child, 'label')
let key = child.key let key = child.key
if (!key && typeof label === 'string') { if (!key && typeof label === 'string') {
key = label key = label

View File

@ -20,7 +20,8 @@ export default {
style={{ width: '500px' }} style={{ width: '500px' }}
onChange={this.onChange} onChange={this.onChange}
> >
<OptGroup label='manager'> <OptGroup>
<span slot='label'>manager</span>
<Option value='jack'> <Option value='jack'>
<b <b
style={{ style={{

View File

@ -1,4 +1,4 @@
import { getPropsData, getSlotOptions, getKey, getAttrs } from '../_util/props-util' import { getPropsData, getSlotOptions, getKey, getAttrs, getComponentFromProp } from '../_util/props-util'
import { cloneVNodes } from '../_util/vnode' import { cloneVNodes } from '../_util/vnode'
export function getValuePropValue (child) { export function getValuePropValue (child) {
const props = getPropsData(child) const props = getPropsData(child)
@ -8,11 +8,14 @@ export function getValuePropValue (child) {
if (getKey(child) !== undefined) { if (getKey(child) !== undefined) {
return getKey(child) return getKey(child)
} }
if (getSlotOptions(child).isSelectOptGroup && props.label) { if (getSlotOptions(child).isSelectOptGroup) {
return props.label const label = getComponentFromProp(child, 'label')
if (label) {
return label
}
} }
throw new Error( throw new Error(
`Need at least a key or a value or a label (only for OptGroup) for ${child}` `Need at least a key or a value or a label(slot) (only for OptGroup) for ${child}`
) )
} }

5
package-lock.json generated
View File

@ -8020,6 +8020,11 @@
} }
} }
}, },
"moment": {
"version": "2.20.1",
"resolved": "http://registry.npm.taobao.org/moment/download/moment-2.20.1.tgz",
"integrity": "sha1-1usaRsvMFKKy+UNBEsH/iQfzE/0="
},
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",