场景
Vue 在更新 DOM 时是异步执行的。
当数据发生变化时,Vue将开启一个异步更新队列,页面视图需要等队列中所有数据变化完成之后,再统一进行更新视图。
也就是说,在视图上做了某些操作,该操作触发数据A的更新,此时,如果要获取A或者用A赋值给其他变量B,有可能是获取到的还是未更新的A,即便你在页面上已经做了修改A的操作。
使用
如果想要在修改数据后,得到更新后的A数据,或者用更新后的A数据进行赋值操作,思路就是把这些操作放在数据变化完成,且视图更新过后。
这就是nextTick的意义:延迟执行某个操作,把该操作的执行延迟到下次DOM更新之后。
nextTick前、后的函数都会在nextTick的回调函数之前执行。
举例
<div>
<el-select
v-model="orderForm.image.imgVersion"
placeholder="请选择镜像版本"
ref="imgSelectRef"
@change="getImgData()"
>
<el-option
v-for="item in imgData"
:key="item.imgId"
:label="item.opSystem + '-' + item.imgVersion"
:value="item.imgId"
/></el-select>
</div>
// 假设原值为:aosp11-aosp11-byteos_master_sim2_1056
// 修改后新值为:aosp11-1.0.1_726
function getImgData() {
console.log('111',imgSelectRef.value.selectedLabel)
nextTick(() => {
console.log('222',imgSelectRef.value.selectedLabel)
// 此时,imgSelectRef.value.selectedLabel已经是更新后的值,可以用来赋值
transmitData.imgVersion = imgSelectRef.value.selectedLabel
})
console.log('333',imgSelectRef.value.selectedLabel)
}
// 打印输出:
// 111 aosp11-1.0.1_726
// 333 aosp11-1.0.1_726
// 222 aosp11-aosp11-byteos_master_sim2_1056
// 通过nextTick延迟回调,页面上transmitData.imgVersion拿到的就是更新后的imgSelectRef.value.selectedLabel数据
注意:在ElementPlus的el-select
组件中,selectedLabel
是一个实例属性,它代表了当前选中的el-option
的标签(label)。
实践
实践发现,nextTick() 经常在涉及到表单的场景中使用到,通过表单的ref取值时,常常取不到更新后的值,需要在nextTick() 的回调函数中才能拿到表单ref的更新值。如上例。
备注:在数据变化后要执行某个回调函数,而这个回调函数的操作需要使用随数据变化而改变的DOM结构的时候(如通过refs取更新后的表单值), 这个操作都应该放进Vue.nextTick () 回调函数中。