Bootstrap

Vue数据修改,页面没有改变 $nextTick()

我们在项目开发中,通常会遇到这样的问题:当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();//获取焦点
	});
		}

在这里插入图片描述
完美解决!

;