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 : [
- ,
+ ,
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',