我们在项目开发中,通常会遇到这样的问题:当input隐藏之后通过修改属性再显示时,我们想让input自动获取焦点,于是在修改完属性之后这样写:
点击编辑:
展示如下:
代码如下:
//html
<div>
//<input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"></input>//选中和取消选中的checkbox
<span v-show="!todo.isEdit">{{todo.title}}</span>
<input
ref="inputTitle"
v-show="todo.isEdit"
:value="todo.title"
@blur="handleBlur(todo,$event)"
>
<button class="btn btn-danger" @click="handleEdit(todo)">编辑</button>
<button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>
</div>
//js
export default {
methods:{
//点击编辑按钮
handleEdit(todo){
this.todo.edit = true;
this.$refs.inputTitle.focus();//获取焦点
}
}
}
上面这段代码,看似没有任何毛病,但点击编辑时,输入框仍旧没有获取到焦点,这是为什么呢?我们来分析一下!
当我们点击编辑按钮之后,handleEdit
函数执行,那么
this.$refs.inputTitle.focus();
这行代码势必会执行,既然执行了页面却没有变化,那就只有这一种可能了,这里我们就发现一个问题,就是我们在修改了isEdit属性之后,vue并没有立刻帮我们去重新解析模板,而是把handleEdit
函数中的代码执行完之后才去重新解析的模板,所以当我们执行this.$refs.inputTitle.focus()
的时候,页面上的input
输入框还没有被渲染出来,因此我们在页面上必然看不到获取焦点的效果,既然知道原因了,我们就对症下药,最简单粗暴的办法就是定时器:
export default {
methods:{
//点击编辑按钮
handleEdit(todo){
this.todo.edit = true;
setTimeout(()=>{
//函数体
this.$refs.inputTitle.focus();//获取焦点
},200);
}
}
}
当然我们还有更简单更合适更推荐的办法,借助vue官方提供的api $nextTick()
用法:
用法:
推迟在下一个 DOM 更新周期后执行的回调。在您更改一些数据以等待 DOM 更新后立即使用它。
官方用法说的很清楚了,this.$nextTick()
的回调函数会在下一次dom节点更新完毕之后再执行,所以我们只需要把获取焦点的代码放入$nextTick()
的回调中就行了!
handleEdit(todo){
this.todo.edit = true;
this.$nextTick(function(){
this.$refs.inputTitle.focus();//获取焦点
});
}
完美解决!