await this.$nextTick()和this.$nextTick(callback)有什么区别?记一次bug调试
背景
需要实现一个需求,一个小区业务详情页面,在左侧菜单栏切换了小区后,详情页跟着切换。
这个详情页面是根据url上的/:id来确定小区id的,所以切换了小区后,应该切换路由。
于是这样实现:
watch: {
// 监听小区号变化
neighNo(newVal) {
if (newVal) {
// 切换路由
this.$router.replace(`/base/business/${newVal}`)
}
}
},
问题
但是实际运行后发现,整个页面的表格数据都变成空了。查看控制台,表格数据是正确的。但是不显示。
这个代码实际也只是重新打开了一个页面,为什么表格数据无法渲染了呢?
调试
打印数据是正确的,却没有渲染,也就是说,是Vue没有监听到数据的变化。
这个页面本来工作是正常的,只是重新打开了,为什么不正常了呢?
如果是不能监听数组和对象的改变的话,这个表格数据是直接赋值的,也就是数组的引用直接改变,那应该是可以监测到数组变化的。
于是用$set尝试去赋值,发现无效。同时发现,不光是这个表格的数组失去了响应性,整个data里的变量,都失去了响应性。
于是我在每个生命周期函数里进行了打印,也在watch里打印,发现先执行watch,然后destroyed,然后路由改变,然后created,然后是请求接口。因为小区切换时,当前路由本身会自动刷新一遍,所以destroyed、created会执行两次,顺序每次执行会略有不同。
那就很有可能是切换路由的时机不对,尝试nextTick之后再切换路由。
解决
this.$nextTick(()=>{
this.$router.replace(`/base/business/${newVal}`)
}
无效。
尝试用setTimeout。setTimout是宏任务,那肯定比$nextTick执行的时机更晚。
setTimeout(() => {
this.$router.replace(`/base/business/${newVal}`)
}, 0)
无效。
把delay从0改成500,有效果了。但是loading的时间略久,而且肉眼仔细观察会发现其实是先加载了原先页面然后快速地开始加载切换的页面。多切换几个小区,有概率失效。
这就有点奇怪了,连setTimeout都无法解决。setTimeout本身是不彻底的解决方案,是下策,在$nextTick无法解决时才应使用。而且,如果delay时间太长,那效果就很奇怪了。
正束手无策时,把$nextTick换了种写法,居然就可以了!
watch: {
async neighNo(newVal) {
if (newVal) {
await this.$nextTick()
this.$router.replace(`/base/business/${newVal}`)
}
}
},
卧槽,这和上面的代码不是一个意思的吗?为什么这就可以?
翻看Vue官方文档,$nextTick用法:
将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
区别仅仅是this的绑定不一样。
watch到neighNo的变化后,本身当前页会由于菜单栏小区切换而刷新,那么此时当前的页面实例将要销毁,而this应该绑定在了这个要销毁的实例上。然后又切换了路由,重新创建了页面实例,this在这个过程中失去了正确的上下文,从而导致data失去了响应性。
而用await的写法,this会根据语法作用域来确定绑定的上下文,每次都会绑定在对应的页面实例上,从而工作正常。
await this.$nextTick()和this.$nextTick(callback)有什么区别?记一次bug调试的更多相关文章
- Vue.nextTick和Vue.$nextTick
`Vue.nextTick(callback)`,当数据发生变化,更新后执行回调. `Vue.$nextTick(callback)`,当dom发生变化,更新后执行的回调. 参考原文:http://w ...
- JdbcTemplate查询数据 三种callback之间的区别
JdbcTemplate针对数据查询提供了多个重载的模板方法,你可以根据需要选用不同的模板方法. 如果你的查询很简单,仅仅是传入相应SQL或者相关参数,然后取得一个单一的结果,那么你可以选择如下一组便 ...
- Vue nextTick 机制
背景 我们先来看一段Vue的执行代码: export default { data () { return { msg: 0 } }, mounted () { this.msg = 1 this.m ...
- vue 修改数据界面没有及时更新nextTick
使用场景:有些时候,我们使用vue修改了一些数据,但是页面上的DOM还没有更新,这个时候我们就需要使用到nextTick. vm.$nextTick( [callback] ) 说明: 将回调延迟到下 ...
- Vue源码解析之nextTick
Vue源码解析之nextTick 前言 nextTick是Vue的一个核心功能,在Vue内部实现中也经常用到nextTick.但是,很多新手不理解nextTick的原理,甚至不清楚nextTick的作 ...
- [NodeJs系列][译]理解NodeJs中的Event Loop、Timers以及process.nextTick()
译者注: 为什么要翻译?其实在翻译这篇文章前,笔者有Google了一下中文翻译,看的不是很明白,所以才有自己翻译的打算,当然能力有限,文中或有错漏,欢迎指正. 文末会有几个小问题,大家不妨一起思考一下 ...
- vue 之 nextTick 与$nextTick
VUE中Vue.nextTick()和this.$nextTick()怎么使用? 官方文档是这样解释的: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 D ...
- 五、vue nextTick
主线程的执行过程就是一个 tick,而所有的异步结果都是通过 "任务队列" 来调度被调度. 消息队列中存放的是一个个的任务(task). 规范中规定 task 分为两大类,分别是 ...
- The Node.js Event Loop, Timers, and process.nextTick() Node.js事件循环,定时器和process.nextTick()
个人翻译 原文:https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ The Node.js Event Loop, Ti ...
- Vue系列---理解Vue.nextTick使用及源码分析(五)
_ 阅读目录 一. 什么是Vue.nextTick()? 二. Vue.nextTick()方法的应用场景有哪些? 2.1 更改数据后,进行节点DOM操作. 2.2 在created生命周期中进行DO ...
随机推荐
- 《Go程序设计语言》学习笔记之数组
<Go程序设计语言>学习笔记之数组 一. 环境 Centos8.5, go1.17.5 linux/amd64 二. 概念 数组是具有固定长度且拥有零个或多个相同数据类型元素的序列. 三. ...
- 从静态到动态化,Python数据可视化中的Matplotlib和Seaborn
本文分享自华为云社区<Python数据可视化大揭秘:Matplotlib和Seaborn高效应用指南>,作者: 柠檬味拥抱. 安装Matplotlib和Seaborn 首先,确保你已经安装 ...
- Impala 高性能、低延迟的大数据查询引擎
Impala是什么? Impala提供对大数据更快速,交互式 SQL查询. Impala支持对存储在HDFS.HBase及S3等数据查询. Impala使用和Hive相同的元数据.SQL定义.ODBC ...
- #最大密度子图,0/1分数规划#UVA1389 Hard Life
题目 \(n\) 个点,\(m\) 条边的一个无向图,问导出子图的边数除以点数的最大值 分析 考虑二分这个答案,也就是0/1分数规划之后转换成 \(E-mid*V>0\) 这个问题虽然可以精确到 ...
- #01背包,容斥,排列组合#洛谷 5615 [MtOI2019]时间跳跃
题目 分析 不是凸多边形当且仅当边数小于2或者最长边大于等于其余边之和, 那么容斥一下,首先总权值为 \[\sum_{i=1}^nC(n,i)\times i=n\sum_{i=1}^nC(n-1,i ...
- #状压dp,背包,贪心#洛谷 5997 [PA2014]Pakowanie
题目 你有 \(n\) 个物品和 \(m\) 个包.物品有重量,且不可被分割: 包也有各自的容量.要把所有物品装入包中,至少需要几个包? 分析 考虑物品的数量很小,首先优先选容量大的背包, 设\(f[ ...
- 网上 server2008数据库恢复方法
从网下下载文件有两个:XX_DB_log.ldf 和XX_DB.mdf 首先:文件处理:右键--属性--安全---编辑--勾选"完全控制"--确定--即可.(两个文件都是相同操作) ...
- Windows 杀毒简单有效的方式
Windows 电脑杀毒通常会选择杀毒软件,这样太笨重,且容易占内存和存在流氓软件侵入. 推荐使用 Windows 自带的恶意软件删除工具 按住 Win + R 键,弹出运行窗口,输入 mrt. 系统 ...
- HMS Core打造影音娱乐行业解决方案,助推视听新浪潮
6月28日,HDD·HMS Core. Sparkle影音娱乐线上沙龙在各大直播平台与开发者们见面.本次线上沙龙围绕影音娱乐行业现状观察和趋势.用户数据洞察分析以及HMS Core影音娱乐行业解决方案 ...
- HMS Core机器学习服务实现同声传译,支持中英文互译和多种音色语音播报
当用户有跨语种交流或音频内容翻译的需求时,应用需要能自动检测语音内容再输出为用户需要的语言文字. HMS Core机器学习服务提供同声传译能力,同声传译实现将实时输入的长语音实时翻译为不同语种的文本以 ...