fix select
							parent
							
								
									832d13eb0c
								
							
						
					
					
						commit
						c44c425a67
					
				|  | @ -9,7 +9,6 @@ import { hasProp, getSlotOptions } from '../_util/props-util' | |||
| import getTransitionProps from '../_util/getTransitionProps' | ||||
| import { cloneElement, getClass, getPropsData, getValueByProp as getValue, getEvents } from '../_util/vnode' | ||||
| import BaseMixin from '../_util/BaseMixin' | ||||
| 
 | ||||
| import { | ||||
|   getPropValue, | ||||
|   getValuePropValue, | ||||
|  | @ -62,7 +61,7 @@ export default { | |||
|     dropdownMenuStyle: PropTypes.object.def({}), | ||||
|     optionFilterProp: SelectPropTypes.optionFilterProp.def('value'), | ||||
|     optionLabelProp: SelectPropTypes.optionLabelProp.def('value'), | ||||
|     notFoundContent: PropTypes.string.def('Not Found'), | ||||
|     notFoundContent: PropTypes.any.def('Not Found'), | ||||
|     backfill: PropTypes.bool.def(false), | ||||
|     showAction: SelectPropTypes.showAction.def(['click']), | ||||
|     combobox: PropTypes.bool.def(false), | ||||
|  | @ -83,7 +82,7 @@ export default { | |||
|       sValue = toArray(defaultValue) | ||||
|     } | ||||
|     sValue = this.addLabelToValue(sValue) | ||||
|     sValue = this.addTitleToValue($slots, sValue) | ||||
|     sValue = this.addTitleToValue($slots.default, sValue) | ||||
|     let inputValue = '' | ||||
|     if (combobox) { | ||||
|       inputValue = sValue.length | ||||
|  | @ -115,7 +114,7 @@ export default { | |||
|           const { combobox, $slots } = this | ||||
|           let value = toArray(this.value) | ||||
|           value = this.addLabelToValue(value) | ||||
|           value = this.addTitleToValue($slots, value) | ||||
|           value = this.addTitleToValue($slots.default, value) | ||||
|           this.setState({ | ||||
|             sValue: value, | ||||
|           }) | ||||
|  | @ -127,9 +126,7 @@ export default { | |||
|             }) | ||||
|           } | ||||
|         } | ||||
|         // this.adjustOpenState() | ||||
|       }, | ||||
|       deep: true, | ||||
|     }, | ||||
|   }, | ||||
|   updated () { | ||||
|  | @ -413,7 +410,7 @@ export default { | |||
|         if (sValue.length) { | ||||
|           this.fireChange([]) | ||||
|         } | ||||
|         // this.setOpenState(false, true) | ||||
|         this.setOpenState(false, true) | ||||
|         if (inputValue) { | ||||
|           this.setInputValue('') | ||||
|         } | ||||
|  | @ -555,21 +552,51 @@ export default { | |||
|     }, | ||||
|     inputBlur (e) { | ||||
|       this.clearBlurTime() | ||||
|       this.blurTimer = setTimeout(() => { | ||||
|         if (!this.disabled) { | ||||
|           this._focused = false | ||||
|           this.setOpenState(false, false) | ||||
|       if (this.disabled) { | ||||
|         return | ||||
|       } | ||||
|       this.blurTimer = setTimeout(() => { | ||||
|         this._focused = false | ||||
|         this.updateFocusClassName() | ||||
|         const props = this.$props | ||||
|         let { sValue } = this | ||||
|         const { inputValue } = this | ||||
|         if ( | ||||
|           isSingleMode(props) && | ||||
|         props.showSearch && | ||||
|         inputValue && | ||||
|         props.defaultActiveFirstOption | ||||
|         ) { | ||||
|           const options = this._options || [] | ||||
|           if (options.length) { | ||||
|             const firstOption = findFirstMenuItem(options) | ||||
|             if (firstOption) { | ||||
|               sValue = [ | ||||
|                 { | ||||
|                   key: firstOption.key, | ||||
|                   label: this.getLabelFromOption(firstOption), | ||||
|                 }, | ||||
|               ] | ||||
|               this.fireChange(sValue) | ||||
|             } | ||||
|           } | ||||
|         } else if (isMultipleOrTags(props) && inputValue) { | ||||
|           this.inputValue = this.getInputDOMNode().value = '' | ||||
|         } | ||||
|         this.__emit('blur', this.getVLForOnChange(sValue)) | ||||
|         this.setOpenState(false) | ||||
|       }, 10) | ||||
|     }, | ||||
|     inputFocus (e) { | ||||
|       this.clearBlurTime() | ||||
|       this.clearFocusTime() | ||||
|       this.timeoutFocus() | ||||
|     }, | ||||
|     _getInputElement () { | ||||
|       const props = this.$props | ||||
|       const inputElement = props.getInputElement | ||||
|         ? props.getInputElement() | ||||
|         : <input id={props.id} autoComplete='off' value='1111'/> | ||||
|         : <input id={props.id} autoComplete='off'/> | ||||
|       const inputCls = classnames(getClass(inputElement), { | ||||
|         [`${props.prefixCls}-search__field`]: true, | ||||
|       }) | ||||
|  | @ -638,9 +665,9 @@ export default { | |||
|       return this.$refs.selectTriggerRef.getInnerMenu() | ||||
|     }, | ||||
| 
 | ||||
|     setOpenState (open, needFocus, forceSet) { | ||||
|     setOpenState (open, needFocus) { | ||||
|       const { $props: props, openStatus } = this | ||||
|       if (!forceSet && openStatus === open) { | ||||
|       if (openStatus === open) { | ||||
|         this.maybeFocus(open, needFocus) | ||||
|         return | ||||
|       } | ||||
|  | @ -785,6 +812,7 @@ export default { | |||
|             this._focused = true | ||||
|           } | ||||
|         } else { | ||||
|           console.log(activeElement) | ||||
|           if (activeElement !== this.$refs.selectionRef) { | ||||
|             this.$refs.selectionRef.focus() | ||||
|             this._focused = true | ||||
|  | @ -810,15 +838,15 @@ export default { | |||
|       return value | ||||
|     }, | ||||
| 
 | ||||
|     addTitleToValue ($slots, values) { | ||||
|     addTitleToValue (children = [], values) { | ||||
|       let nextValues = values | ||||
|       const keys = values.map(v => v.key) | ||||
|       $slots.default.forEach(child => { | ||||
|       children.forEach(child => { | ||||
|         if (!child) { | ||||
|           return | ||||
|         } | ||||
|         if (getSlotOptions(child).isSelectOptGroup) { | ||||
|           nextValues = this.addTitleToValue(child.$slots, nextValues) | ||||
|           nextValues = this.addTitleToValue(child.$slots.default, nextValues) | ||||
|         } else { | ||||
|           const value = getValuePropValue(child) | ||||
|           const valueIndex = keys.indexOf(value) | ||||
|  | @ -1048,7 +1076,7 @@ export default { | |||
|       return options | ||||
|     }, | ||||
| 
 | ||||
|     renderFilterOptionsFromChildren (children, childrenKeys, menuItems) { | ||||
|     renderFilterOptionsFromChildren (children = [], childrenKeys, menuItems) { | ||||
|       const sel = [] | ||||
|       const props = this.$props | ||||
|       const { inputValue } = this | ||||
|  | @ -1320,11 +1348,14 @@ export default { | |||
|       if (!this.disabled) { | ||||
|         if (this._focused && this.openStatus) { | ||||
|           this._focused = false | ||||
|           this.setOpenState(false, false, true) | ||||
|           this.setOpenState(false, false) | ||||
|           this.getInputDOMNode().blur() | ||||
|         } else { | ||||
|           // this._focused = true | ||||
|           // this.updateFocusClassName() | ||||
|           // this.timeoutFocus() | ||||
|           this._focused = true | ||||
|           this.setOpenState(true, true, true) | ||||
|           this.setOpenState(true, true) | ||||
|           this.getInputDOMNode().focus() | ||||
|         } | ||||
|       } | ||||
|  | @ -1338,12 +1369,25 @@ export default { | |||
|     const { disabled, prefixCls, inputValue, sValue, $listeners } = this | ||||
|     const { mouseenter = noop, mouseleave = noop, popupScroll = noop } = $listeners | ||||
|     const ctrlNode = this.renderTopControlNode(openStatus) | ||||
|     let extraSelectionProps = {} | ||||
|     if (!isMultipleOrTagsOrCombobox(props)) { | ||||
|       extraSelectionProps = { | ||||
|         onKeyDown: this.onKeyDown, | ||||
|         tabIndex: props.disabled ? -1 : 0, | ||||
|     const selectionProps = { | ||||
|       props: {}, | ||||
|       attrs: { | ||||
|         role: 'combobox', | ||||
|         'aria-autocomplete': 'list', | ||||
|         'aria-haspopup': 'true', | ||||
|         'aria-expanded': openStatus.toString(), | ||||
|       }, | ||||
|       on: { | ||||
|         click: this.selectionRefClick, | ||||
|       }, | ||||
|       class: `${prefixCls}-selection ${prefixCls}-selection--${multiple ? 'multiple' : 'single'}`, | ||||
|       ref: 'selectionRef', | ||||
|       key: 'selection', | ||||
| 
 | ||||
|     } | ||||
|     if (!isMultipleOrTagsOrCombobox(props)) { | ||||
|       selectionProps.on.keydown = this.onKeyDown | ||||
|       selectionProps.attrs.tabIndex = props.disabled ? -1 : 0 | ||||
|     } | ||||
|     const rootCls = { | ||||
|       [prefixCls]: 1, | ||||
|  | @ -1389,22 +1433,9 @@ export default { | |||
|           ref='rootRef' | ||||
|           // onBlur={this.onOuterBlur} | ||||
|           // onFocus={this.onOuterFocus} | ||||
|           // onClick={this.rootRefClick} | ||||
|           class={classnames(rootCls)} | ||||
|           // tabindex='-1' | ||||
|         > | ||||
|           <div | ||||
|             ref='selectionRef' | ||||
|             key='selection' | ||||
|             class={`${prefixCls}-selection | ||||
|             ${prefixCls}-selection--${multiple ? 'multiple' : 'single'}`} | ||||
|             role='combobox' | ||||
|             aria-autocomplete='list' | ||||
|             aria-haspopup='true' | ||||
|             aria-expanded={openStatus} | ||||
|             {...extraSelectionProps} | ||||
|             onClick={this.selectionRefClick} | ||||
|         > | ||||
|           <div {...selectionProps}> | ||||
|             {ctrlNode} | ||||
|             {this.renderClear()} | ||||
|             {multiple || !props.showArrow ? null : ( | ||||
|  |  | |||
|  | @ -0,0 +1,46 @@ | |||
| <script> | ||||
| import Select, { Option } from '../index' | ||||
| import '../assets/index.less' | ||||
| 
 | ||||
| export default { | ||||
|   data () { | ||||
|     return { | ||||
|       disabled: false, | ||||
|       options: [], | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     onChange (value) { | ||||
|       console.log('onChange', value) | ||||
|       let options = [] | ||||
|       if (value) { | ||||
|         if (value.indexOf('@') >= 0) { | ||||
|           options = <Option key={value}>{value}</Option> | ||||
|         } else { | ||||
|           options = ['gmail.com', 'yahoo.com', 'outlook.com'].map((domain) => { | ||||
|             const email = `${value}@${domain}` | ||||
|             return <Option key={email}>{email}</Option> | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|       this.options = options | ||||
|     }, | ||||
|     onSelect (v) { | ||||
|       console.log('onSelect', v) | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     return (<Select | ||||
|       combobox | ||||
|       notFoundContent={false} | ||||
|       style='width: 200px' | ||||
|       onChange={this.onChange} | ||||
|       onSelect={this.onSelect} | ||||
|       placeholder='请输入账户名' | ||||
|     > | ||||
|       {this.options} | ||||
|     </Select>) | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | @ -0,0 +1,64 @@ | |||
| <script> | ||||
| import Select, { Option } from '../index' | ||||
| import { fetch } from './tbFetchSuggest' | ||||
| import '../assets/index.less' | ||||
| 
 | ||||
| export default { | ||||
|   data () { | ||||
|     return { | ||||
|       disabled: false, | ||||
|       data: [], | ||||
|       value: undefined, | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     onChange (value) { | ||||
|       console.log('select ', value) | ||||
|       // value.label = value.key | ||||
|       this.value = value | ||||
|     }, | ||||
|     fetchData (value) { | ||||
|       if (value) { | ||||
|         fetch(value, (data) => { | ||||
|           this.data = data | ||||
|         }) | ||||
|       } else { | ||||
|         this.data = [] | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     toggleDisabled () { | ||||
|       this.disabled = !this.disabled | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     const data = this.data | ||||
|     const options = data.map((d) => { | ||||
|       return <Option key={d.value}><i>{d.text}</i></Option> | ||||
|     }) | ||||
|     return (<div> | ||||
|       <h2>force suggest</h2> | ||||
|       <p> | ||||
|         <button onClick={this.toggleDisabled}>toggle disabled</button> | ||||
|       </p> | ||||
|       <div> | ||||
|         <Select | ||||
|           labelInValue | ||||
|           onSearch={this.fetchData} | ||||
|           disabled={this.disabled} | ||||
|           value={this.value} | ||||
|           optionLabelProp='children' | ||||
|           placeholder='placeholder' | ||||
|           defaultActiveFirstOption | ||||
|           style={{ width: '500px' }} | ||||
|           onChange={this.onChange} | ||||
|           filterOption={false} | ||||
|         > | ||||
|           {options} | ||||
|         </Select> | ||||
|       </div> | ||||
|     </div>) | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | @ -0,0 +1,35 @@ | |||
| 
 | ||||
| import jsonp from 'jsonp' | ||||
| import querystring from 'querystring' | ||||
| let timeout | ||||
| let currentValue | ||||
| 
 | ||||
| export function fetch (value, callback) { | ||||
|   if (timeout) { | ||||
|     clearTimeout(timeout) | ||||
|     timeout = null | ||||
|   } | ||||
|   currentValue = value | ||||
| 
 | ||||
|   function fake () { | ||||
|     const str = querystring.encode({ | ||||
|       code: 'utf-8', | ||||
|       q: value, | ||||
|     }) | ||||
|     jsonp(`http://suggest.taobao.com/sug?${str}`, (err, d) => { // eslint-disable-line
 | ||||
|       if (currentValue === value) { | ||||
|         const result = d.result | ||||
|         const data = [] | ||||
|         result.forEach((r) => { | ||||
|           data.push({ | ||||
|             value: r[0], | ||||
|             text: r[0], | ||||
|           }) | ||||
|         }) | ||||
|         callback(data) | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   timeout = setTimeout(fake, 300) | ||||
| } | ||||
|  | @ -19,7 +19,14 @@ export function getPropValue (child, prop) { | |||
|   if (prop === 'value') { | ||||
|     return getValuePropValue(child) | ||||
|   } | ||||
|   return child.props[prop] | ||||
|   if (prop === 'children') { | ||||
|     if (child.$slots) { | ||||
|       return child.$slots.default | ||||
|     } else { | ||||
|       return child.componentOptions.children | ||||
|     } | ||||
|   } | ||||
|   return getPropsData(child)[prop] | ||||
| } | ||||
| 
 | ||||
| export function isMultiple (props) { | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ const AsyncComp = () => { | |||
|   const hashs = window.location.hash.split('/') | ||||
|   const d = hashs[hashs.length - 1] | ||||
|   return { | ||||
|     component: import(`../components/spin/demo/index.vue`), | ||||
|     component: import(`../components/vc-select/demo/${d}.vue`), | ||||
|   } | ||||
| } | ||||
| export default [ | ||||
|  |  | |||
|  | @ -51,6 +51,7 @@ | |||
|     "highlight.js": "^9.12.0", | ||||
|     "html-webpack-plugin": "^2.30.1", | ||||
|     "istanbul-instrumenter-loader": "^3.0.0", | ||||
|     "jsonp": "^0.2.1", | ||||
|     "karma": "^1.4.1", | ||||
|     "karma-coverage": "^1.1.1", | ||||
|     "karma-coverage-istanbul-reporter": "^1.3.0", | ||||
|  | @ -67,6 +68,7 @@ | |||
|     "marked": "^0.3.7", | ||||
|     "mocha": "^3.2.0", | ||||
|     "pre-commit": "^1.2.2", | ||||
|     "querystring": "^0.2.0", | ||||
|     "selenium-server": "^3.0.1", | ||||
|     "semver": "^5.3.0", | ||||
|     "sinon": "^4.0.2", | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou