欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

项目中遇到的问题

程序员文章站 2022-04-18 09:28:52
...

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

相关标签: vue 问题