vue项目中created()被调用多次的踩坑实战

 更新时间:2023年03月29日 09:08:02   作者:追逐梦想永不停  
在vue项目中我在created中调用了两次get数据请求,所以下面这篇文章主要给大家介绍了关于vue项目中created()被调用多次的踩坑实战,需要的朋友可以参考下

一、问题描述

最近碰到一个奇怪的生产问题:

正常情况下、前端页面会请求一次后台、然后后台返回信息("处理成功"或"处理失败")、前端展示;
后台用aop+redis写了一个防止重复调用的方法,如果5s内同一个用户重复调用同一个接口,就返回"请勿重复调用",前端就会展示这个。

但是,某几个页面,前端总是会重复调用后端2次,导致用户只能看到"请勿重复调用",无法确认本次操作是成功还是失败,严重影响了用户的正常使用。(虽然是处理成功,但是显示不出来…)

一开始还怀疑是不是后端的问题,排查了半天,终于锁定了,是前端的问题,vue项目中的created()方法被调用了2次。

继续排查,发现从正常页面跳转到这个问题页面时,确实只跳转了1次,按理说created()方法应该也只触发1次的,但是就是不知道为什么触发了2次。

二、排查过程

1.从头开始排查前端项目,vue项目首先会加载main.js,发现这个文件里有:

import Vcon from './assets/js/vcon'

new Vcon({
  env: ENV
}, () => {
  new Vue({
    router,
    render: h => h(App)
  }).$mount('#app')
})

发现这个文件里,并不是普通的使用new Vue()创建的页面,而是外面有封装了一个new Vcon()方法,并传了2个参数,其中第一个参数是{ env: ENV },第二个参数是 () => { new Vue({ router, render: h => h(App) }).$mount('#app') }

2.继续,查看./assets/js/vcon.js文件,发现这个文件里有类似这样的:

class Vcon {
  constructor (opt, callBack) {
    this.env = opt.env || '' // 记录代码环境
    this.callBack = callBack // 记录回调函数
    // 如果是生产环境
    if (this.env !== 'test') {
      this.prodInit()
      typeof this.callBack === 'function' && this.callBack()
      return
    }

    // 如果是测试环境
    if (this.env === 'test') {
      this.testInit()
      return
    }
  }

  testInit () {
    import('vconsole').then(({ default: VConsole }) => {
      new VConsole()
      console.log('测试vconsole加载完成')
      typeof this.callBack === 'function' && this.callBack()
    })
  }
  
  prodInit () {
    let _that = this
    window.ISALES.callApp('getUserInfoByNative', {
      callback: function (userInfo) {
        if (userInfo.code === '0') {
          _that.betterStaffNUmber = userInfo.msg.staffNumber
          _that.betterHandler(userInfo)
          return
        }
        alert('获取sdk出错,请稍后再试')
      }
    })
  }
  
  betterHandler (userInfo) {
    if (userInfo.msg.userCode == 'admin') {
      import('vconsole').then(({ default: VConsole }) => {
        new VConsole()
        console.log(`admin的vconsole加载完成`)
        typeof this.callBack === 'function' && this.callBack()
      })
      return
    }else{
      this.callBack()
    }
  }
}

其中,当上一步执行new Vcon()时,实际执行的就是这里的constructor ()方法;

如果是测试环境,那就执行testInit ()方法,这个还是比较明显的,用来展示vconsole(测试环境一直正常,没有复测出来问题);
如果是生产环境,那就执行prodInit()方法,然后执行typeof this.callBack === 'function' && this.callBack()方法(这里感觉有些问题,先继续看);

prodInit()方法里,会执行window.ISALES.callApp方法,这个是个sdk方法(这个前端项目是vue项目,可以打包后把静态页面部署在服务器上;sdk方法是app和ios里的方法,前端只能这样才能调用到、待sdk方法处理完后会触发callback方法);

sdk方法中,会执行betterHandler()方法,意思是,如果当前app/ios的登录人是admin,那就显示vconsole,否则就不显示。

3.根据生产created()方法被调用2次、而测试正常的现象,排查到问题方法位置:

    // 如果是生产环境
    if (this.env !== 'test') {
      this.prodInit()
      typeof this.callBack === 'function' && this.callBack()
      return
    }

因为prodInit()方法的逻辑中,正常情况下,已经调用过一次typeof this.callBack === 'function' && this.callBack()了,然而执行完prodInit()方法后,又会调用一次typeof this.callBack === 'function' && this.callBack(),所以才导致created()方法被重复调用了2次。

4.正确代码如下:

    // 如果是生产环境
    if (this.env !== 'test') {
      this.prodInit()
      //这里导致了重复created()
      //typeof this.callBack === 'function' && this.callBack()
      return
    }

修改后,发布生产,终于恢复了正常。

三、备注

1.vue项目中,有时会自动优化代码格式,导致if后面没有大括号、只有1句,满足条件就执行、不满足就不执行,需要注意。

2.有时,if没有else,而是if中结尾有个return,此时也类似else,但是容易忽略,需要注意。(这个也是自动优化格式的?还是故意写的难懂了?)

3.typeof this.callBack === 'function' && this.callBack(),这个的意思是,如果this.callBackfunction类型的,那就会执行后面的this.callBack()方法,然后继续下一步;如果不是function类型的,那就不执行后面的方法,直接继续下一步。(又一个不好理解的高级写法,用if不好吗?)

4.正常情况下,vue页面的created()方法会在页面初始化的时候执行1次;但是如果代码有问题,就会导致created()方法会在页面初始化的时候执行2次或多次(如本文),这个坑需要注意。

总结

到此这篇关于vue项目中created()被调用多次的踩坑的文章就介绍到这了,更多相关vue created()被调用多次内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue+element多选级联选择器自定义props使用详解

    vue+element多选级联选择器自定义props使用详解

    这篇文章主要给大家介绍了关于vue+element多选级联选择器自定义props使用的相关资料,级联选择器展示的结果都是以数组的形式展示,也就是v-model绑定的结果,需要的朋友可以参考下
    2023-07-07
  • Vue-cli3中如何引入ECharts并实现自适应

    Vue-cli3中如何引入ECharts并实现自适应

    这篇文章主要介绍了Vue-cli3中如何引入ECharts并实现自适应,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Vue 项目中Echarts 5使用方法详解

    Vue 项目中Echarts 5使用方法详解

    这篇文章主要为大家介绍了Vue 项目中Echarts 5使用方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • vue实现两个区域滚动条同步滚动

    vue实现两个区域滚动条同步滚动

    这篇文章主要为大家详细介绍了vue实现两个区域滚动条同步滚动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • Vue组件解析之如何自定义弹窗组件ByDialog

    Vue组件解析之如何自定义弹窗组件ByDialog

    这篇文章主要介绍了Vue组件解析之如何自定义弹窗组件ByDialog问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Vue项目优化打包之前端必备加分项

    Vue项目优化打包之前端必备加分项

    相信现在很多人都是用Vue做过了各种项目,但是项目代码做完和上线并不代表这结束,还有上线以后的优化也是很重要的一点,这篇文章主要给大家介绍了关于Vue项目优化打包的相关资料,需要的朋友可以参考下
    2021-09-09
  • Vue实现回到顶部和底部动画效果

    Vue实现回到顶部和底部动画效果

    这篇文章主要为大家详细介绍了Vue实现回到顶部和底部动画效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • vue2和vue3的v-if与v-for优先级对比学习

    vue2和vue3的v-if与v-for优先级对比学习

    这篇文章主要介绍了vue2和vue3的v-if与v-for优先级对比学习,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • vue2源码解析之全局API实例详解

    vue2源码解析之全局API实例详解

    全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,下面这篇文章主要给大家介绍了关于vue2源码解析之全局API的相关资料,需要的朋友可以参考下
    2022-11-11
  • vue的for循环使用方法

    vue的for循环使用方法

    在本篇文章里小编给大家整理了关于vue的for循环使用方法和步骤,有需要的朋友们跟着学习下。
    2019-02-02

最新评论