fix: 🐛 修复 Input、Textarea、Search 组件设置清空后不聚焦时无法触发失焦事件的问题 (#1046)

This commit is contained in:
不如摸鱼去 2025-05-13 13:26:14 +08:00 committed by GitHub
parent 817797801d
commit 33b556546a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 52 deletions

View File

@ -236,10 +236,10 @@ function togglePwdVisible() {
isPwdVisible.value = !isPwdVisible.value isPwdVisible.value = !isPwdVisible.value
} }
async function handleClear() { async function handleClear() {
clearing.value = true
focusing.value = false focusing.value = false
inputValue.value = '' inputValue.value = ''
if (props.focusWhenClear) { if (props.focusWhenClear) {
clearing.value = true
focused.value = false focused.value = false
} }
await pause() await pause()

View File

@ -7,24 +7,24 @@
<wd-icon name="search" custom-class="wd-search__search-icon"></wd-icon> <wd-icon name="search" custom-class="wd-search__search-icon"></wd-icon>
<text :class="`wd-search__placeholder-txt ${placeholderClass}`">{{ placeholder || translate('search') }}</text> <text :class="`wd-search__placeholder-txt ${placeholderClass}`">{{ placeholder || translate('search') }}</text>
</view> </view>
<wd-icon v-if="showInput || str || placeholderLeft" name="search" custom-class="wd-search__search-left-icon"></wd-icon> <wd-icon v-if="showInput || inputValue || placeholderLeft" name="search" custom-class="wd-search__search-left-icon"></wd-icon>
<input <input
v-if="showInput || str || placeholderLeft" v-if="showInput || inputValue || placeholderLeft"
:placeholder="placeholder || translate('search')" :placeholder="placeholder || translate('search')"
:placeholder-class="`wd-search__placeholder-txt ${placeholderClass}`" :placeholder-class="`wd-search__placeholder-txt ${placeholderClass}`"
:placeholder-style="placeholderStyle" :placeholder-style="placeholderStyle"
confirm-type="search" confirm-type="search"
v-model="str" v-model="inputValue"
:class="['wd-search__input', customInputClass]" :class="['wd-search__input', customInputClass]"
@focus="searchFocus" @focus="handleFocus"
@input="inputValue" @input="handleInput"
@blur="searchBlur" @blur="handleBlur"
@confirm="search" @confirm="handleConfirm"
:disabled="disabled" :disabled="disabled"
:maxlength="maxlength" :maxlength="maxlength"
:focus="isFocused" :focus="isFocused"
/> />
<wd-icon v-if="str" custom-class="wd-search__clear wd-search__clear-icon" name="error-fill" @click="clearSearch" /> <wd-icon v-if="inputValue" custom-class="wd-search__clear wd-search__clear-icon" name="error-fill" @click="handleClear" />
</view> </view>
</view> </view>
@ -61,14 +61,14 @@ const { translate } = useTranslate('search')
const isFocused = ref<boolean>(false) // const isFocused = ref<boolean>(false) //
const showInput = ref<boolean>(false) // hack const showInput = ref<boolean>(false) // hack
const str = ref('') const inputValue = ref<string>('') //
const showPlaceHolder = ref<boolean>(true) const showPlaceHolder = ref<boolean>(true)
const clearing = ref<boolean>(false) const clearing = ref<boolean>(false)
watch( watch(
() => props.modelValue, () => props.modelValue,
(newValue) => { (newValue) => {
str.value = newValue inputValue.value = newValue
if (newValue) { if (newValue) {
showInput.value = true showInput.value = true
} }
@ -98,7 +98,7 @@ const rootClass = computed(() => {
const coverStyle = computed(() => { const coverStyle = computed(() => {
const coverStyle: CSSProperties = { const coverStyle: CSSProperties = {
display: str.value === '' && showPlaceHolder.value ? 'flex' : 'none' display: inputValue.value === '' && showPlaceHolder.value ? 'flex' : 'none'
} }
return objToStyle(coverStyle) return objToStyle(coverStyle)
@ -116,27 +116,22 @@ async function closeCover() {
showPlaceHolder.value = false showPlaceHolder.value = false
hackFocus(true) hackFocus(true)
} }
/**
* @description input的input事件handle function handleInput(event: any) {
* @param value inputValue.value = event.detail.value
*/
function inputValue(event: any) {
str.value = event.detail.value
emit('update:modelValue', event.detail.value) emit('update:modelValue', event.detail.value)
emit('change', { emit('change', {
value: event.detail.value value: event.detail.value
}) })
} }
/**
* @description 点击清空icon的handle async function handleClear() {
*/ inputValue.value = ''
async function clearSearch() {
str.value = ''
clearing.value = true
if (props.focusWhenClear) { if (props.focusWhenClear) {
clearing.value = true
isFocused.value = false isFocused.value = false
} }
await pause(100) await pause()
if (props.focusWhenClear) { if (props.focusWhenClear) {
showPlaceHolder.value = false showPlaceHolder.value = false
hackFocus(true) hackFocus(true)
@ -150,49 +145,40 @@ async function clearSearch() {
emit('update:modelValue', '') emit('update:modelValue', '')
emit('clear') emit('clear')
} }
/**
* @description 点击搜索按钮时的handle function handleConfirm({ detail: { value } }: any) {
* @param value
*/
function search({ detail: { value } }: any) {
// search // search
emit('search', { emit('search', {
value value
}) })
} }
/**
* @description 输入框聚焦时的handle function handleFocus() {
*/ showPlaceHolder.value = false
function searchFocus() { emit('focus', {
value: inputValue.value
})
}
async function handleBlur() {
// 150clear
await pause(150)
if (clearing.value) { if (clearing.value) {
clearing.value = false clearing.value = false
return return
} }
showPlaceHolder.value = false
emit('focus', {
value: str.value
})
}
/**
* @description 输入框失焦的handle
*/
function searchBlur() {
if (clearing.value) return
// blur // blur
showPlaceHolder.value = !str.value showPlaceHolder.value = !inputValue.value
showInput.value = !showPlaceHolder.value showInput.value = !showPlaceHolder.value
isFocused.value = false isFocused.value = false
emit('blur', { emit('blur', {
value: str.value value: inputValue.value
}) })
} }
/**
* @description 点击取消搜索按钮的handle
*/
function handleCancel() { function handleCancel() {
// cancel
emit('cancel', { emit('cancel', {
value: str.value value: inputValue.value
}) })
} }
</script> </script>

View File

@ -233,10 +233,10 @@ function formatValue(value: string | number) {
} }
async function handleClear() { async function handleClear() {
clearing.value = true
focusing.value = false focusing.value = false
inputValue.value = '' inputValue.value = ''
if (props.focusWhenClear) { if (props.focusWhenClear) {
clearing.value = true
focused.value = false focused.value = false
} }
await pause() await pause()