3030 :placeholder =" placeholder || translate('placeholder')"
3131 :disabled =" disabled"
3232 :maxlength =" maxlength"
33- :focus =" isFocus "
33+ :focus =" focused "
3434 :confirm-type =" confirmType"
3535 :confirm-hold =" confirmHold"
3636 :cursor =" cursor"
4949 @keyboardheightchange =" handleKeyboardheightchange"
5050 />
5151 <view v-if =" readonly" class =" wd-input__readonly-mask" />
52- <view v-if =" showClear || showPassword || suffixIcon || showWordCount || useSuffixSlot " class =" wd-input__suffix" >
52+ <view v-if =" showClear || showPassword || suffixIcon || showWordCount || $slots.suffix " class =" wd-input__suffix" >
5353 <wd-icon v-if =" showClear" custom-class =" wd-input__clear" name =" error-fill" @click =" clear" />
5454 <wd-icon v-if =" showPassword" custom-class =" wd-input__icon" :name =" isPwdVisible ? 'view' : 'eye-close'" @click =" togglePwdVisible" />
5555 <view v-if =" showWordCount" class =" wd-input__count" >
@@ -85,7 +85,7 @@ export default {
8585
8686<script lang="ts" setup>
8787import { computed , onBeforeMount , ref , watch } from ' vue'
88- import { objToStyle , requestAnimationFrame } from ' ../common/util'
88+ import { isDef , objToStyle , requestAnimationFrame } from ' ../common/util'
8989import { useCell } from ' ../composables/useCell'
9090import { FORM_KEY , type FormItemRule } from ' ../wd-form/types'
9191import { useParent } from ' ../composables/useParent'
@@ -102,45 +102,64 @@ const emit = defineEmits([
102102 ' input' ,
103103 ' keyboardheightchange' ,
104104 ' confirm' ,
105- ' linechange' ,
106105 ' clicksuffixicon' ,
107106 ' clickprefixicon' ,
108107 ' click'
109108])
110109const { translate } = useTranslate (' input' )
111110
112- const showClear = ref <boolean >(false )
113- const showWordCount = ref <boolean >(false )
114111const isPwdVisible = ref <boolean >(false )
115- const clearing = ref <boolean >(false )
116- const isFocus = ref <boolean >(false ) // 是否聚焦
112+ const clearing = ref <boolean >(false ) // 是否正在清空操作,避免重复触发失焦
113+ const focused = ref <boolean >(false ) // 控制聚焦
114+ const focusing = ref <boolean >(false ) // 当前是否激活状态
117115const inputValue = ref <string | number >(' ' ) // 输入框的值
118116const cell = useCell ()
119117
120118watch (
121119 () => props .focus ,
122120 (newValue ) => {
123- isFocus .value = newValue
121+ focused .value = newValue
124122 },
125123 { immediate: true , deep: true }
126124)
127125
128126watch (
129127 () => props .modelValue ,
130128 (newValue ) => {
131- const { disabled, readonly, clearable } = props
132129 if (newValue === undefined ) {
133130 newValue = ' '
134131 console .warn (' [wot-design] warning(wd-input): value can not be undefined.' )
135132 }
136133 inputValue .value = newValue
137- showClear .value = Boolean (clearable && ! disabled && ! readonly && newValue )
138134 },
139135 { immediate: true , deep: true }
140136)
141137
142138const { parent : form } = useParent (FORM_KEY )
143139
140+ /**
141+ * 展示清空按钮
142+ */
143+ const showClear = computed (() => {
144+ const { disabled, readonly, clearable, clearTrigger } = props
145+ if (clearable && ! readonly && ! disabled && inputValue .value && (clearTrigger === ' always' || (props .clearTrigger === ' focus' && focusing .value ))) {
146+ return true
147+ } else {
148+ return false
149+ }
150+ })
151+
152+ /**
153+ * 展示字数统计
154+ */
155+ const showWordCount = computed (() => {
156+ const { disabled, readonly, maxlength, showWordLimit } = props
157+ return Boolean (! disabled && ! readonly && isDef (maxlength ) && maxlength > - 1 && showWordLimit )
158+ })
159+
160+ /**
161+ * 表单错误提示信息
162+ */
144163const errorMessage = computed (() => {
145164 if (form && props .prop && form .errorMessages && form .errorMessages [props .prop ]) {
146165 return form .errorMessages [props .prop ]
@@ -194,49 +213,58 @@ onBeforeMount(() => {
194213
195214// 状态初始化
196215function initState() {
197- const { disabled, readonly, clearable, maxlength, showWordLimit } = props
198- let newVal = ' '
199- if (showWordLimit && maxlength && inputValue .value .toString ().length > maxlength ) {
200- newVal = inputValue .value .toString ().substring (0 , maxlength )
201- }
202- showClear .value = Boolean (! disabled && ! readonly && clearable && inputValue .value )
203- showWordCount .value = Boolean (! disabled && ! readonly && maxlength && showWordLimit )
204- inputValue .value = newVal || inputValue .value
216+ inputValue .value = formatValue (inputValue .value )
205217 emit (' update:modelValue' , inputValue .value )
206218}
219+
220+ function formatValue(value : string | number ) {
221+ const { maxlength } = props
222+ if (isDef (maxlength ) && maxlength !== - 1 && String (value ).length > maxlength ) {
223+ return value .toString ().slice (0 , maxlength )
224+ }
225+ return value
226+ }
227+
207228function togglePwdVisible() {
208229 isPwdVisible .value = ! isPwdVisible .value
209230}
210231function clear() {
232+ clearing .value = true
233+ focusing .value = false
211234 inputValue .value = ' '
212- requestAnimationFrame ()
213- . then (() => requestAnimationFrame ())
214- . then (() => requestAnimationFrame ())
215- . then (() => {
216- isFocus . value = true
217- emit ( ' change ' , {
218- value: ' '
219- })
220- emit (' update:modelValue ' , inputValue . value )
221- emit ( ' clear ' )
235+ if ( props . focusWhenClear ) {
236+ focused . value = false
237+ }
238+ requestAnimationFrame (() => {
239+ if ( props . focusWhenClear ) {
240+ focused . value = true
241+ focusing . value = true
242+ }
243+ emit (' change ' , {
244+ value: ' '
222245 })
246+ emit (' update:modelValue' , inputValue .value )
247+ emit (' clear' )
248+ })
223249}
224250function handleBlur() {
225- isFocus .value = false
226- emit (' change' , {
227- value: inputValue .value
228- })
229- emit (' update:modelValue' , inputValue .value )
230- emit (' blur' , {
231- value: inputValue .value
251+ if (clearing .value ) {
252+ clearing .value = false
253+ return
254+ }
255+ requestAnimationFrame (() => {
256+ focusing .value = false
257+ emit (' blur' , {
258+ value: inputValue .value
259+ })
232260 })
233261}
234262function handleFocus({ detail }: any ) {
235263 if (clearing .value ) {
236264 clearing .value = false
237265 return
238266 }
239- isFocus .value = true
267+ focusing .value = true
240268 emit (' focus' , detail )
241269}
242270function handleInput({ detail }: any ) {
0 commit comments