项目中遇到的问题

Posted 赏花赏景赏时光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目中遇到的问题相关的知识,希望对你有一定的参考价值。

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来实现的

以上是关于项目中遇到的问题的主要内容,如果未能解决你的问题,请参考以下文章

C/C++中关于宏定义中使用 # 和 ## 的作用

是否可以在 Excel 中进行 Levenshtein 距离而不必求助于宏?

数据的深拷贝浅拷贝的使用时机和实际遇到的问题和延展运算符拷贝数据的错误使用

数据的深拷贝浅拷贝的使用时机和实际遇到的问题和延展运算符拷贝数据的错误使用

在 Postgresql 中打开和关闭连接的最佳时机是啥时候?

iOS 开发 把握AFNet网络请求完成的正确时机