From 2c7aa93bd64b8658d0b07210dc9e10e09c490b51 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Thu, 7 Jun 2018 14:40:10 +0800 Subject: [PATCH] fix: cascader autoFocus not work --- components/cascader/index.jsx | 38 +++++++++++++++++++++++------ components/input/Input.jsx | 7 +++++- components/trigger/Trigger.jsx | 6 ++++- components/vc-cascader/Cascader.jsx | 4 ++- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/components/cascader/index.jsx b/components/cascader/index.jsx index b73dd7213..bafcf07e2 100644 --- a/components/cascader/index.jsx +++ b/components/cascader/index.jsx @@ -53,7 +53,7 @@ const CascaderProps = { disabled: PropTypes.bool.def(false), /** 是否支持清除*/ allowClear: PropTypes.bool.def(true), - showSearch: PropTypes.oneOfType([PropTypes.bool, ShowSearchType]), + showSearch: PropTypes.oneOfType([Boolean, ShowSearchType]), notFoundContent: PropTypes.any.def('Not Found'), loadData: PropTypes.func, /** 次级菜单的展开方式,可选 'click' 和 'hover' */ @@ -66,6 +66,7 @@ const CascaderProps = { inputPrefixCls: PropTypes.string.def('ant-input'), getPopupContainer: PropTypes.func, popupVisible: PropTypes.bool, + autoFocus: PropTypes.bool, } function defaultFilterOption (inputValue, path) { @@ -102,6 +103,13 @@ export default { flattenOptions: showSearch && flattenTree(options, changeOnSelect), } }, + mounted () { + this.$nextTick(() => { + if (this.autoFocus && !this.showSearch && !this.disabled) { + this.$refs.picker.focus() + } + }) + }, watch: { value (val) { this.setState({ sValue: val || [] }) @@ -119,7 +127,7 @@ export default { highlightKeyword (str, keyword, prefixCls) { return str.split(keyword) .map((node, index) => index === 0 ? node : [ - {keyword}, + {keyword}, node, ]) }, @@ -152,11 +160,15 @@ export default { } this.$emit('popupVisibleChange', popupVisible) }, + handleInputFocus (e) { + this.$emit('focus', e) + }, - handleInputBlur () { + handleInputBlur (e) { this.setState({ inputFocused: false, }) + this.$emit('blur', e) }, handleInputClick (e) { @@ -164,7 +176,7 @@ export default { // Prevent `Trigger` behaviour. if (inputFocused || sPopupVisible) { e.stopPropagation() - e.nativeEvent.stopImmediatePropagation() + e.nativeEvent && e.nativeEvent.stopImmediatePropagation() } }, @@ -249,16 +261,24 @@ export default { }, focus () { - this.$refs.input.focus() + if (this.showSearch) { + this.$refs.input.focus() + } else { + this.$refs.picker.focus() + } }, blur () { - this.$refs.input.blur() + if (this.showSearch) { + this.$refs.input.blur() + } else { + this.$refs.picker.blur() + } }, }, render () { - const { $slots, sValue: value, sPopupVisible, inputValue } = this + const { $slots, sValue: value, sPopupVisible, inputValue, $listeners } = this const props = getOptionProps(this) const { prefixCls, inputPrefixCls, placeholder, size, disabled, @@ -329,6 +349,7 @@ export default { if (resultListMatchInputWidth && inputValue && this.input) { dropdownMenuColumnStyle.width = this.input.input.offsetWidth } + // showSearch时,focus、blur在input上触发,反之在ref='picker'上触发 const inputProps = { props: { ...tempInputProps, @@ -342,6 +363,7 @@ export default { class: `${prefixCls}-input ${sizeCls}`, ref: 'input', on: { + focus: showSearch ? this.handleInputFocus : noop, click: showSearch ? this.handleInputClick : noop, blur: showSearch ? this.handleInputBlur : noop, keydown: this.handleKeyDown, @@ -354,6 +376,7 @@ export default { { showSearch ? {this.getLabel()} @@ -375,6 +398,7 @@ export default { dropdownMenuColumnStyle: dropdownMenuColumnStyle, }, on: { + ...$listeners, popupVisibleChange: this.handlePopupVisibleChange, change: this.handleChange, }, diff --git a/components/input/Input.jsx b/components/input/Input.jsx index befe70e8c..2364f58aa 100644 --- a/components/input/Input.jsx +++ b/components/input/Input.jsx @@ -27,7 +27,12 @@ export default { stateValue: fixControlledValue(!hasProp(this, 'value') ? defaultValue : value), } }, - computed: { + mounted () { + this.$nextTick(() => { + if (this.autoFocus) { + this.focus() + } + }) }, watch: { value (val) { diff --git a/components/trigger/Trigger.jsx b/components/trigger/Trigger.jsx index a990b6967..6efe389d6 100644 --- a/components/trigger/Trigger.jsx +++ b/components/trigger/Trigger.jsx @@ -524,7 +524,11 @@ export default { newChildProps.on.blur = this.onBlur } else { newChildProps.on.focus = this.createTwoChains('focus') - newChildProps.on.blur = this.createTwoChains('blur') + newChildProps.on.blur = (e) => { + if (!e.relatedTarget || !contains(e.target, e.relatedTarget)) { + this.createTwoChains('blur')(e) + } + } } const { sPopupVisible, forceRender } = this const trigger = cloneElement(child, newChildProps) diff --git a/components/vc-cascader/Cascader.jsx b/components/vc-cascader/Cascader.jsx index bb122b32e..176c4e6b7 100644 --- a/components/vc-cascader/Cascader.jsx +++ b/components/vc-cascader/Cascader.jsx @@ -257,7 +257,7 @@ export default { render () { const { $props, $slots, sValue, sActiveValue, handleMenuSelect, - sPopupVisible, handlePopupVisibleChange, handleKeyDown, + sPopupVisible, handlePopupVisibleChange, handleKeyDown, $listeners, } = this const { prefixCls, transitionName, popupClassName, options, disabled, @@ -274,6 +274,7 @@ export default { visible: sPopupVisible, }, on: { + ...$listeners, select: handleMenuSelect, }, } @@ -298,6 +299,7 @@ export default { popupClassName: popupClassName + emptyMenuClassName, }, on: { + ...$listeners, popupVisibleChange: handlePopupVisibleChange, }, ref: 'trigger',