宿州住房和城乡建设局网站,宁波建站推广技术公司,网站开发的客户群体,qq是哪个公司开发的地址前两天在封装组件的时候#xff0c;发现el-select 单选时#xff0c;选择后输入框的is-focus状态并没有取消#xff0c;需要手动点其它地方才会取消#xff0c;于是想着找找为什么
一、通过调试源码发现#xff0c;输入框在点击选项后触发blur#xff0c;紧接着又触发了…前两天在封装组件的时候发现el-select 单选时选择后输入框的is-focus状态并没有取消需要手动点其它地方才会取消于是想着找找为什么
一、通过调试源码发现输入框在点击选项后触发blur紧接着又触发了一次focus
1.状态样式由计算属性wrapperKls控制又与“isFocused”相关且handleFocus和isFocused都由useFocusController提供 2.因此找到useFocusController的具体实现加入console.log就能观察到focus触发情况 查看控制台
二、有devTools也可以观察到点击选项后isFocused先变成false又变成true实际上还是上方useFocusController中的handleFocus改变了其值 三、找一下点击选项后发生了什么
深扒一下干了4件事
ctx.emit(UPDATE_MODEL_EVENT, option.value) // ctx.emit(update:modelValue, val) 更新双向绑定的值
emitChange(option.value) // 值改变的情况下调用 ctx.emit(change, val) 触发el-select的change事件
states.visible false // 那么这时又发生了什么呢
setSoftFocus() /* 看起来像是这个方法导致的const _input input.value || reference.valueif (_input) {_input?.focus()}
*/四、经过我的排除大法有两种情况会触发的focus事件
由states.visible改变触发由setSoftFocus()方法触发 如果想在点击选项后不触发focus那么就需要同时注释这两行代码才行 在不破坏代码功能的情况下加入一个方法setSoftBlur和一个prop 用户在单选时如果传入了autoBlur那么 const setSoftBlur () {const _input input.value || reference.valueif (_input) {_input?.blur()}}/*** description when select one item, click option will let input blur*/autoBlur: Boolean,tip:使用setTimeout涉及js任务队列与事件循环将在下方执行setSoftFocus之后调用setSoftBlur()
五、效果如图 总结
前前后后花了两天多刚开始以为是某个内部组件的事件冒泡导致的源码拉下来找得头都晕了input、popper、tooltip、focus-trap、useFocusController等等后面又从头开始一边写博客一边找这样清晰很多再加上联想起focus事件没有冒泡那么问题就在input身上只需要弄清点了选项之后发生了什么就真相大白了。
上面其实只是找到了一半的原因除了setSoftFocus方法外将states.visible改为false也会让input触发focus如下 注释掉setSoftFocus()与新加的代码后延后1秒执行state.visible false 可以明显看到输入框先blur在visible变为false后又focus了
注释了对states.visible的watch也没用 有点不解搞不清楚为什么visible改变会触发输入框的focus事件可能是浏览器更底层的一些机制导致的道行太浅后面在慢慢看了