背景
工作中遇到使用vue遇到获取不到页面数据的情况,探究原理发现更新data的数据后,vue并不是实时更新的,从数据更新到显示到页面有时间差。在时间差内调用页面数据,当然获取不到。
Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
nextTick只需了解这么多
- 修改data数据后,数据不是实时更新的。
- 当你需要在数据更新dom后执行某个操作,该操作需要放在nextTick中。
当你设置 vm.someData = ‘new value’,该组件不会立即重新渲染。当刷新队列时,组件会在下一个事件循环“tick”中更新。如果你想基于更新后的 DOM 状态来做点什么,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。例如:
示例1:watch中使用nexttick
watch: {
contacts(newValue, oldValue) {
----------- 处理过程省略----
this.list = arr;
this.$nextTick(function() {
var list = document.getElementById('list');
$(".mui-indexed-list-bar").height(document.body.offsetHeight-list.offsetHeight);
window.indexedList = new mui.IndexedList(list);
//关闭等待框
//显示当前页面
mui.currentWebview.show();
plus.nativeUI.closeWaiting();
});
}
},
contacts 通讯录数据变化时,触发watch的函数执行。经过格式处理后,我将结果赋值给
list ,该list(几百个电话号码)会用于渲染页面。
为什么这里nexttick是必须的
- 设置mui-indexed-list-bar的高度依赖list表单的高度,页面更新前数据时空的,list高度是0。所以必须在页面渲染完成后才能取得真实的高度。
- plus.nativeUI.closeWaiting();用来关闭等待窗口。1000个号码可能处理和渲染 过程需要3秒(假设),在渲染之前调用了 plus.nativeUI.closeWaiting(),页面会有空白期。所以需要在页面渲染完成后在关闭等待窗口。
以上,如果没有nexttick就没办法满足业务。
示例2:VUE外部使用nexttick
mui.post(prefix + '', {
brokerId: brokerId,
}, function(data) {
_this.app1.list = arr;
_this.app1.sortshow();
Vue.nextTick(function() {
$(".star").raty({
score: function() {
return $(this).attr("data-num");
},
starOn: 'imgs/star-on1.png',
starOff: 'imgs/star-off1.png',
starHalf: 'imgs/star-half1.png',
readOnly: true,
halfShow: true,
size: 15,
});
});
}, 'json');
这里使用nextTick的理由是,等页面渲染完后获取标签的data-num,从而给评分赋值。raty是一个评分的插件。
Vue.nextTick 和$nextTick差别
Vue.nextTick是全局方法,vm.$nextTick( [callback] ) 是实例方法。一个页面有多个实例,后者可以精确到某个示例上。 本质上两个是一样的,Vue中也有很多类似的情况。
例如:this就代表了当前实例。
nextTick的使用还有个小小的技巧,我们在生命周期mounted里面渲染的时候,不能百分百保证所有的自组件都能被渲染,所以我们可以在mounted里面使用 vm.$nextTick,这样就能确保所有的子组件都能被渲染到了。
(mounted钩子在服务器端渲染期间不被调用。)
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
参考
- https://www.cnblogs.com/cczlovexw/p/9560215.html
- https://www.jianshu.com/p/46c9d777cab1