mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-16 01:41:15 +08:00
add select demo
This commit is contained in:
parent
c0f892c002
commit
5dcc6678fa
@ -22,7 +22,7 @@ const getSlotOptions = (ele) => {
|
||||
if (ele.$vnode) {
|
||||
componentOptions = ele.$vnode.componentOptions
|
||||
}
|
||||
return componentOptions.Ctor.options
|
||||
return componentOptions ? componentOptions.Ctor.options || {} : {}
|
||||
}
|
||||
const getOptionProps = (instance) => {
|
||||
const { $options = {}, $props = {}} = instance
|
||||
@ -43,8 +43,17 @@ const getPropsData = (ele) => {
|
||||
if (ele.$vnode) {
|
||||
componentOptions = ele.$vnode.componentOptions
|
||||
}
|
||||
return componentOptions && componentOptions.propsData
|
||||
return componentOptions ? componentOptions.propsData || {} : {}
|
||||
}
|
||||
|
||||
const getAttrs = (ele) => {
|
||||
let data = ele.data
|
||||
if (ele.$vnode) {
|
||||
data = ele.$vnode.data
|
||||
}
|
||||
return data ? data.attrs || {} : {}
|
||||
}
|
||||
|
||||
const getKey = (ele) => {
|
||||
let key = ele.key
|
||||
if (ele.$vnode) {
|
||||
@ -52,5 +61,15 @@ const getKey = (ele) => {
|
||||
}
|
||||
return key
|
||||
}
|
||||
export { hasProp, filterProps, getOptionProps, getComponentFromProp, getSlotOptions, slotHasProp, getPropsData, getKey }
|
||||
export {
|
||||
hasProp,
|
||||
filterProps,
|
||||
getOptionProps,
|
||||
getComponentFromProp,
|
||||
getSlotOptions,
|
||||
slotHasProp,
|
||||
getPropsData,
|
||||
getKey,
|
||||
getAttrs,
|
||||
}
|
||||
export default hasProp
|
||||
|
@ -128,7 +128,7 @@ export function getPropsData (ele) {
|
||||
return ele.componentOptions && ele.componentOptions.propsData
|
||||
}
|
||||
export function getValueByProp (ele, prop) {
|
||||
return ele.componentOptions && ele.componentOptions.propsData[prop]
|
||||
return ele.componentOptions && ele.componentOptions.propsData && ele.componentOptions.propsData[prop]
|
||||
}
|
||||
|
||||
export function getEvents (child) {
|
||||
|
@ -1,5 +1,9 @@
|
||||
<script>
|
||||
import PropTypes from '../_util/vue-types'
|
||||
export default {
|
||||
props: {
|
||||
label: PropTypes.any,
|
||||
},
|
||||
isSelectOptGroup: true,
|
||||
}
|
||||
</script>
|
||||
|
@ -8,6 +8,7 @@ export default {
|
||||
PropTypes.number,
|
||||
]),
|
||||
disabled: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
},
|
||||
isSelectOption: true,
|
||||
}
|
||||
|
@ -113,25 +113,32 @@ export default {
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
'$props': {
|
||||
handler: function (nextProps) {
|
||||
if (hasProp(this, 'value')) {
|
||||
const { combobox, $slots } = this
|
||||
let value = toArray(this.value)
|
||||
value = this.addLabelToValue(value)
|
||||
value = this.addTitleToValue($slots.default, value)
|
||||
this.setState({
|
||||
sValue: value,
|
||||
})
|
||||
if (combobox) {
|
||||
this.setState({
|
||||
inputValue: value.length
|
||||
? this.getLabelFromProps(value[0].key)
|
||||
: '',
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
// '$props': {
|
||||
// handler: function (nextProps) {
|
||||
// if (hasProp(this, 'value')) {
|
||||
// console.log('nextProps', nextProps)
|
||||
// const { combobox, $slots } = this
|
||||
// let value = toArray(this.value)
|
||||
// value = this.addLabelToValue(value)
|
||||
// value = this.addTitleToValue($slots.default, value)
|
||||
// this.setState({
|
||||
// sValue: value,
|
||||
// })
|
||||
// if (combobox) {
|
||||
// this.setState({
|
||||
// inputValue: value.length
|
||||
// ? this.getLabelFromProps(value[0].key)
|
||||
// : '',
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
value (val) {
|
||||
this.updateState()
|
||||
},
|
||||
combobox () {
|
||||
this.updateState()
|
||||
},
|
||||
},
|
||||
updated () {
|
||||
@ -148,10 +155,6 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
beforeUpdate () {
|
||||
// console.log('beforeUpdate')
|
||||
// this.adjustOpenState()
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.clearFocusTime()
|
||||
this.clearBlurTime()
|
||||
@ -163,6 +166,22 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateState () {
|
||||
const { combobox, $slots } = this
|
||||
let value = toArray(this.value)
|
||||
value = this.addLabelToValue(value)
|
||||
value = this.addTitleToValue($slots.default, value)
|
||||
this.setState({
|
||||
sValue: value,
|
||||
})
|
||||
if (combobox) {
|
||||
this.setState({
|
||||
inputValue: value.length
|
||||
? this.getLabelFromProps(value[0].key)
|
||||
: '',
|
||||
})
|
||||
}
|
||||
},
|
||||
onInputChange (event) {
|
||||
const { tokenSeparators } = this
|
||||
const val = event.target.value
|
||||
@ -437,7 +456,7 @@ export default {
|
||||
},
|
||||
|
||||
onChoiceAnimationLeave () {
|
||||
this.$refs.selectTriggerRef.triggerRef.forcePopupAlign()
|
||||
this.$refs.selectTriggerRef.$refs.triggerRef.forcePopupAlign()
|
||||
},
|
||||
getOptionsFromChildren (value, children = [], options = []) {
|
||||
let values = value
|
||||
@ -535,6 +554,7 @@ export default {
|
||||
},
|
||||
|
||||
getLabelFromOption (child) {
|
||||
console.log(child, this.optionLabelProp)
|
||||
return getPropValue(child, this.optionLabelProp)
|
||||
},
|
||||
|
||||
@ -635,14 +655,12 @@ export default {
|
||||
if (options.length) {
|
||||
const firstOption = findFirstMenuItem(options)
|
||||
if (firstOption) {
|
||||
console.log('pre', this.sValue)
|
||||
sValue = [
|
||||
{
|
||||
key: firstOption.key,
|
||||
label: this.getLabelFromOption(firstOption),
|
||||
},
|
||||
]
|
||||
console.log('new', this.sValue, sValue)
|
||||
this.fireChange(sValue)
|
||||
}
|
||||
}
|
||||
@ -833,6 +851,8 @@ export default {
|
||||
this.clearFocusTime()
|
||||
}
|
||||
this.focusTimer = setTimeout(() => {
|
||||
this._focused = true
|
||||
this.updateFocusClassName()
|
||||
this.__emit('focus')
|
||||
}, 10)
|
||||
},
|
||||
@ -911,7 +931,7 @@ export default {
|
||||
return
|
||||
}
|
||||
if (getSlotOptions(child).isSelectOptGroup) {
|
||||
nextValues = this.addTitleToValue(child.$slots.default, nextValues)
|
||||
nextValues = this.addTitleToValue(child.componentOptions.children, nextValues)
|
||||
} else {
|
||||
const value = getValuePropValue(child)
|
||||
const valueIndex = keys.indexOf(value)
|
||||
@ -961,7 +981,7 @@ export default {
|
||||
this.__emit('select', labelInValue ? value : value.key, this.getSingleOptionByValueKey(value.key))
|
||||
},
|
||||
fireChange (value) {
|
||||
if (hasProp(this, 'value')) {
|
||||
if (!hasProp(this, 'value')) {
|
||||
this.setState({
|
||||
sValue: value,
|
||||
})
|
||||
@ -975,7 +995,7 @@ export default {
|
||||
isChildDisabled (key) {
|
||||
return this.$slots.default.some(child => {
|
||||
const childValue = getValuePropValue(child)
|
||||
return childValue === key && getValue(child, 'title')
|
||||
return childValue === key && getValue(child, 'disabled')
|
||||
})
|
||||
},
|
||||
|
||||
@ -1304,6 +1324,7 @@ export default {
|
||||
}
|
||||
if (isMultipleOrTags(props)) {
|
||||
selectedValueNodes = limitedCountValue.map(singleValue => {
|
||||
console.log('singleValue', singleValue)
|
||||
let content = singleValue.label
|
||||
const title = singleValue.title || content
|
||||
if (
|
||||
@ -1353,29 +1374,25 @@ export default {
|
||||
if (isMultipleOrTags(props) && choiceTransitionName) {
|
||||
const transitionProps = getTransitionProps(choiceTransitionName, {
|
||||
tag: 'ul',
|
||||
// beforeEnter: this.onChoiceAnimationLeave,
|
||||
afterLeave: this.onChoiceAnimationLeave,
|
||||
})
|
||||
innerNode = (
|
||||
<transition-group
|
||||
// onLeave={this.onChoiceAnimationLeave}
|
||||
// component='ul'
|
||||
// transitionName={choiceTransitionName}
|
||||
{...transitionProps}
|
||||
onClick={this.muitipleContainerClick}
|
||||
>
|
||||
{selectedValueNodes}
|
||||
</transition-group>
|
||||
)
|
||||
} else {
|
||||
innerNode = (
|
||||
<ul onClick={this.muitipleContainerClick}>
|
||||
<ul>
|
||||
{selectedValueNodes}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div class={className} ref='topCtrlRef'>
|
||||
<div class={className} ref='topCtrlRef' onClick={this.muitipleContainerClick}>
|
||||
{this.getPlaceholderElement()}
|
||||
{innerNode}
|
||||
</div>
|
||||
@ -1426,17 +1443,18 @@ export default {
|
||||
e.stopPropagation()
|
||||
this.clearBlurTime()
|
||||
if (!this.disabled) {
|
||||
const input = this.getInputDOMNode()
|
||||
if (this._focused && this.openStatus) {
|
||||
this._focused = false
|
||||
this.setOpenState(false, false)
|
||||
this.getInputDOMNode().blur()
|
||||
input && input.blur()
|
||||
} else {
|
||||
// this._focused = true
|
||||
// this.updateFocusClassName()
|
||||
// this.timeoutFocus()
|
||||
this._focused = true
|
||||
this.setOpenState(true, true)
|
||||
this.getInputDOMNode().focus()
|
||||
input && input.focus()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
56
components/vc-select/demo/mul-tag-suggest.vue
Normal file
56
components/vc-select/demo/mul-tag-suggest.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<script>
|
||||
import Select, { Option } from '../index'
|
||||
import '../assets/index.less'
|
||||
import { fetch } from './tbFetchSuggest'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
data: [],
|
||||
value: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange ', value)
|
||||
this.value = value
|
||||
},
|
||||
onSelect (value) {
|
||||
console.log('select ', value)
|
||||
},
|
||||
fetchData (value) {
|
||||
fetch(value, (data) => {
|
||||
this.data = data
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const data = this.data
|
||||
const options = data.map((d) => {
|
||||
return <Option key={d.value}><i>{d.text}</i></Option>
|
||||
})
|
||||
return (<div>
|
||||
<h2>multiple suggest</h2>
|
||||
|
||||
<div>
|
||||
<Select
|
||||
style={{ width: '500px' }}
|
||||
labelInValue
|
||||
optionLabelProp='children'
|
||||
value={this.value}
|
||||
onChange={this.onChange}
|
||||
tags
|
||||
placeholder='placeholder'
|
||||
notFoundContent=''
|
||||
onSearch={this.fetchData}
|
||||
onSelect={this.onSelect}
|
||||
filterOption={false}
|
||||
>
|
||||
{options}
|
||||
</Select>
|
||||
</div>
|
||||
</div>)
|
||||
},
|
||||
}
|
||||
</script>
|
58
components/vc-select/demo/multiple-readonly.vue
Normal file
58
components/vc-select/demo/multiple-readonly.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<script>
|
||||
import Select, { Option } from '../index'
|
||||
import '../assets/index.less'
|
||||
import { fetch } from './tbFetchSuggest'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
data: [],
|
||||
value: ['b11'],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
console.log('onChange ', value)
|
||||
this.value = value
|
||||
},
|
||||
onSelect (value) {
|
||||
console.log('select ', value)
|
||||
},
|
||||
fetchData (value) {
|
||||
fetch(value, (data) => {
|
||||
this.data = data
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const children = []
|
||||
for (let i = 10; i < 36; i++) {
|
||||
// 11 => readonly selected item
|
||||
children.push(<Option disabled={i === 11} key={i.toString(36) + i}>中文{i}</Option>)
|
||||
}
|
||||
const dropdownMenuStyle = {
|
||||
maxHeight: '200px',
|
||||
}
|
||||
return (<div>
|
||||
<h2>multiple readonly default selected item</h2>
|
||||
<div>
|
||||
<Select
|
||||
multiple
|
||||
value={this.value}
|
||||
animation='slide-up'
|
||||
choiceTransitionName='rc-select-selection__choice-zoom'
|
||||
dropdownMenuStyle={dropdownMenuStyle}
|
||||
style={{ width: '500px' }}
|
||||
optionFilterProp='children'
|
||||
optionLabelProp='children'
|
||||
placeholder='please select'
|
||||
onChange={this.onChange}
|
||||
>
|
||||
{children}
|
||||
</Select>
|
||||
</div>
|
||||
</div>)
|
||||
},
|
||||
}
|
||||
</script>
|
74
components/vc-select/demo/multiple.vue
Normal file
74
components/vc-select/demo/multiple.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<script>
|
||||
import Select, { Option } from '../index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
useAnim: 0,
|
||||
value: ['a10'],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value, options) {
|
||||
console.log('onChange', value, options)
|
||||
this.value = value
|
||||
},
|
||||
onSelect (...args) {
|
||||
console.log('select ', args)
|
||||
},
|
||||
onDeselect (...args) {
|
||||
console.log('deselect ', args)
|
||||
},
|
||||
useAnimation (e) {
|
||||
this.useAnim = e.target.checked
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const children = []
|
||||
for (let i = 10; i < 36; i++) {
|
||||
children.push(
|
||||
<Option key={i.toString(36) + i} disabled={i === 10} title={`中文${i}`}>
|
||||
中文{i}
|
||||
</Option>
|
||||
)
|
||||
}
|
||||
const dropdownMenuStyle = {
|
||||
maxHeight: '200px',
|
||||
}
|
||||
return (<div>
|
||||
<h2>multiple select(scroll the menu)</h2>
|
||||
|
||||
<p>
|
||||
<label>
|
||||
anim
|
||||
<input checked={this.useAnim} type='checkbox' onChange={this.useAnimation} />
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
value={this.value}
|
||||
animation={this.useAnim ? 'slide-up' : null}
|
||||
choiceTransitionName='rc-select-selection__choice-zoom'
|
||||
dropdownMenuStyle={dropdownMenuStyle}
|
||||
style={{ width: '500px' }}
|
||||
multiple
|
||||
allowClear
|
||||
optionFilterProp='children'
|
||||
optionLabelProp='children'
|
||||
onSelect={this.onSelect}
|
||||
onDeselect={this.onDeselect}
|
||||
placeholder='please select'
|
||||
onChange={this.onChange}
|
||||
onFocus={() => console.log('focus')}
|
||||
tokenSeparators={[' ', ',']}
|
||||
>
|
||||
{children}
|
||||
</Select>
|
||||
</div>
|
||||
</div>)
|
||||
},
|
||||
}
|
||||
</script>
|
43
components/vc-select/demo/optgroup.vue
Normal file
43
components/vc-select/demo/optgroup.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<script>
|
||||
import Select, { Option, OptGroup } from '../index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
onChange (value, options) {
|
||||
console.log(`selected ${value}`)
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
return (<div>
|
||||
<h2>Select OptGroup</h2>
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
placeholder='placeholder'
|
||||
defaultValue='lucy'
|
||||
showSearch={false}
|
||||
style={{ width: '500px' }}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<OptGroup label='manager'>
|
||||
<Option value='jack'>
|
||||
<b
|
||||
style={{
|
||||
color: 'red',
|
||||
}}
|
||||
>
|
||||
jack
|
||||
</b>
|
||||
</Option>
|
||||
<Option value='lucy'>lucy</Option>
|
||||
</OptGroup>
|
||||
<OptGroup label='engineer'>
|
||||
<Option value='yiminghe'>yiminghe</Option>
|
||||
</OptGroup>
|
||||
</Select>
|
||||
</div>
|
||||
</div>)
|
||||
},
|
||||
}
|
||||
</script>
|
31
components/vc-select/demo/optionFilterProp.vue
Normal file
31
components/vc-select/demo/optionFilterProp.vue
Normal file
@ -0,0 +1,31 @@
|
||||
<script>
|
||||
import Select, { Option } from '../index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
onChange (value, options) {
|
||||
console.log(`selected ${value}`)
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
return (<div>
|
||||
<h2>Select optionFilterProp</h2>
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
defaultValue='张三'
|
||||
style={{ width: '500px' }}
|
||||
placeholder='placeholder'
|
||||
optionFilterProp='desc'
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<Option value='张三' desc='张三 zhang san'>ddd</Option>
|
||||
<Option value='李四' desc='李四 li si'>李四</Option>
|
||||
<Option value='王五' desc='王五 wang wu'>王五</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</div>)
|
||||
},
|
||||
}
|
||||
</script>
|
30
components/vc-select/demo/optionLabelProp.vue
Normal file
30
components/vc-select/demo/optionLabelProp.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<script>
|
||||
import Select, { Option } from '../index'
|
||||
import '../assets/index.less'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
onChange (value, options) {
|
||||
console.log(`selected ${value}`)
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const cases = {
|
||||
0: { name: 'Case 1' },
|
||||
1: { name: 'Case 2' },
|
||||
2: { name: 'Case 3' },
|
||||
}
|
||||
return (<div>
|
||||
<h2>Select optionLabelProp</h2>
|
||||
<Select style={{ width: '500px' }} optionLabelProp='children' multiple allowClear>
|
||||
{
|
||||
Object.keys(cases).map(key => (
|
||||
<Option key={key} value={key}>{cases[key].name}</Option>
|
||||
))
|
||||
}
|
||||
</Select>
|
||||
</div>)
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,4 +1,4 @@
|
||||
import { getPropsData, getSlotOptions, getKey } from '../_util/props-util'
|
||||
import { getPropsData, getSlotOptions, getKey, getAttrs } from '../_util/props-util'
|
||||
export function getValuePropValue (child) {
|
||||
const props = getPropsData(child)
|
||||
if ('value' in props) {
|
||||
@ -26,7 +26,12 @@ export function getPropValue (child, prop) {
|
||||
return child.componentOptions.children
|
||||
}
|
||||
}
|
||||
return getPropsData(child)[prop]
|
||||
const data = getPropsData(child)
|
||||
if (prop in data) {
|
||||
return data[prop]
|
||||
} else {
|
||||
return getAttrs(child)[prop]
|
||||
}
|
||||
}
|
||||
|
||||
export function isMultiple (props) {
|
||||
@ -150,7 +155,12 @@ export function defaultFilterFn (input, child) {
|
||||
if (props.disabled) {
|
||||
return false
|
||||
}
|
||||
const value = String(getPropValue(child, this.optionFilterProp))
|
||||
let value = getPropValue(child, this.optionFilterProp)
|
||||
if (value.length && value[0].text) {
|
||||
value = value[0].text
|
||||
} else {
|
||||
value = String(value)
|
||||
}
|
||||
return (
|
||||
value.toLowerCase().indexOf(input.toLowerCase()) > -1
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user