例子:
看上面这个例子,我们的需求是:
点击备注表格时,该表格变为可编辑状态的输入框,会出现输入框、两个按钮。
点击对勾时,会修改备注发送给后端修改请求,修改备注,变为不编辑状态,输入框、按钮消失。
失去焦点时,输入框同样变为不可编辑状态,输入框、按钮消失。
问题的关键在于,input失焦事件总是先于对勾按钮的点击事件发生的。即当我们点击按钮对勾时,已经先失去了焦点,将按钮隐藏了。因此根本不可能触发按钮的点击事件。
那么这个问题怎么解决呢?一个常用的做法是,将input输入框的失焦事件onblur的回调里设置一个定时器setTimeout,在定时器里面执行将按钮隐藏的操作。
// 失焦事件的回调
onBlurHandler() {
// 设置定时器
this.timeoutId = setTimeout(() => {
// 关闭可编辑状态
this.isEdit = false;
},100);
}
另外,如果我们不想在点击确定时隐藏按钮。我们在按钮的点击事件的回调里可以先清除这个定时器。
// 对勾按钮的点击事件
confirmEdit() {
// 清除定时器
clearTimeout(this.timeoutId);
// 触发发送更改备注的请求的事件
this.$emit('subValue', this.valueInput)
},
之所以这么做的原因是,这是一个异步的操作,setTimeout作为一个宏任务将会在同步任务执行完之后才会被执行。
有关宏任务微任务的概念及原理,下面这篇文章讲的比较易懂,看完之后你就都明白了。
https://juejin.im/post/59e85eebf265da430d571f89