【Vue实践】Vue中Input框失焦事件无效问题解决
记录在做项目中遇到的以西Input输入框失焦事件无效问题及解决思路文章目录问题场景演示代码片段问题简单描述解决思路问题出现的原因分析解决办法两种解决思路1.定时器 setTimeout()2.nextTick()效果演示源码参考问题场景演示代码片段<div class="flex items-center"><span>昵称:</span><spanv-i
记录在做项目中遇到的Input输入框失焦事件无效问题及解决思路
问题
场景演示

从动图可以看到,当第一次点击文本时,文本变为可编辑状态,但点击文本框以外的地方,文本框并没有关闭编辑状态。而需要重新点击文本框,再点击外面才有效果。
代码片段
<div class="flex items-center">
<span>昵称:</span>
<span
v-if="isEditName"
class="cursor-pointer font-bold"
@click="handleEditName"
>
{{ name }}
</span>
<input
class="ring-2"
v-else
v-model="name"
type="text"
@blur="submitEditName"
@keyup.enter="submitEditName"
/>
</div>
export default {
data() {
return {
isEditName: true,
name: "LynnHg",
};
},
methods: {
handleEditName() {
this.isEditName = false;
},
async submitEditName() {
this.isEditName = true;
// 发请求保存修改后的数据
// ...
},
},
};
问题简单描述
需求是做一个文本展示,点击文本切换为可编辑的输入框,点击输入框以外的地方保存修改后的内容。
遇到的问题是:点击输入框以外的地方并没有触发失焦事件。只有再次点击并聚焦输入框,再点击输入框以外的地方,失焦事件才能触发。
解决思路
问题出现的原因分析
我们通过if else来控制文本和输入框的切换,当点击文本时触发handleEditName函数,将isEditName = false,达到else条件,从而渲染inout框。
而blur表示对象失去焦点时触发,而我们的input框是通过条件渲染生成的,并不是通过聚焦事件focus触发的。
因此,当我们点击输入框以外的地方并没有触发blur事件。
解决办法
我们要在input框渲染出来的时候,聚焦到input框上。
为input 加上ref属性。
<input
class="ring-2"
ref="nameInput"
v-else
v-model="name"
type="text"
@blur="submitEditName"
@keyup.enter="submitEditName"
/>
在handleEditName函数中增加以下代码:
handleEditName() {
this.isEditName = false;
this.$refs.nameInput.focus();
},
保存代码,再次运行回到界面。
结果问题还是没有解决,而且会报以下错误。怎么回事呢?
Error in v-on handler: "TypeError: Cannot read property 'focus' of undefined"
这里就涉及到Vue的响应式原理了,大概就是我们通过this.isEditName = false来切换input显示,但是这一行代码不会立即让组件重新渲染,而我们又近接着在下一行代码中通过this.$refs去获取input的实例,其实是拿不到的。
详细原理请参考深入响应式原理-异步更新队列。
应该怎么办呢?
两种解决思路
1.定时器 setTimeout()
handleEditName() {
this.isEditName = false;
setTimeout(() => {
this.$refs.nameInput.focus();
});
},
2.nextTick()
handleEditName() {
this.isEditName = false;
this.$nextTick(function () {
this.$refs.nameInput.focus();
});
},
效果演示
忽略光标显示问题,应该是录制gif时卡了。
问题完美解决,nice!!!
源码参考
更多推荐



所有评论(0)