add select demo
							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() | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|  |  | |||
|  | @ -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> | ||||
|  | @ -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> | ||||
|  | @ -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> | ||||
|  | @ -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> | ||||
|  | @ -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> | ||||
|  | @ -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
	
	 tangjinzhou
						tangjinzhou