项目中遇到的问题
1、微信环境下、app环境下、谷歌浏览器下等内核实现原理不一致,引发vue中的钩子执行时序不一致,导致在vue中产生一些奇怪bug
1)在微信环境下,在beforeRouteEnter钩子中的next里面调用$nextTick钩子不执行
基本代码如下:
beforeRouteEnter(to, from, next) {
next(vm => {
// do something
// .....
console.log(1)
vm.$nextTick(() => {
console.log(2)
vm.getData()
})
})
}
使用nextTIck钩子原因:A、B页面是父子路由形式,A中调接口拿到的数据info会存在store里面,B页面会在调getData方法中的入参用到info信息,在不用nexTick直接调getData方法,有的场景从A进到B,info信息没更新,导致调接口拿到的数据不是最新的,所以用nextTick解决数据没更新问题
现象:在app内、谷歌浏览器下,会在控制台下先打印1,接着打印2;但是在微信环境下,打印1之后,永远不执行打印2的操作,即一直进不去nextTick钩子函数中的回调函数
解决方法:将nextTick改成timeout,在timeOut中调用getData,就解决数据没有更新的问题
beforeRouteEnter(to, from, next) {
next(vm => {
// do something
// .....
console.log(1)
let timer = setTimeout(() => {
clearTimeout(timer)
console.log(2)
vm.getData()
}, 0)
})
}
2)在微信环境下,在beforeRouteEnter钩子中的next里面,通过调getSuppliers()拿数据,更新字段supplierList,但是watch监听不到supplierList的变化
基本代码如下:
beforeRouteEnter(to, from, next) {
next(vm => {
// do something
// .....
vm.getSuppliers()
})
},
data() {
return {
supplierList: []
}
},
watch: {
supplierList(n, o) {
alert(n)
}
},
methods: {
getSuppliers() {
let data = {}
this.GET_SUPPLIER(data).then(res => {
this.supplierList = res
alert(JSON.stringify(this.supplierList))
}).catch(err => {
console.error('GET_SUPPLIER error: ', err)
})
}
}
现象:在app内,谷歌浏览器下,会先alert出接口里面的数据,接着会alert出watch中的数据,但是在微信环境下,会alert出接口里面的数据,watch里面的alert一直没有出现,即数据确实更新了,但是watch不到变量的更新
解决方法:在beforeRouteEnter中,getSuppliers放在setTimeout中调用
beforeRouteEnter(to, from, next) {
next(vm => {
// do something
// .....
let timer = setTimeout(() => {
clearTimeout(timer)
vm.getSuppliers()
}, 0)
})
}
总结:以上两个问题的原因都是一样的,即微信浏览器内核的实现原理和app、或谷歌浏览器的不太一样,导致vue中的钩子的执行时机不一样,导致了以上的bug。(仅个人看法)
tips:我们知道js的执行机制是单线程的,即同一时间只能做一件事情;而任务分为宏任务和微任务,微任务执的优先级高于宏任务。nextTick内部实现原理就是采用了任务降级处理的方式,即Promise => MutationObserver => setTimeout来实现的
上一篇: 项目中遇到的问题
下一篇: 项目中遇到的问题的总结