vue 踩不完的异步之坑及解决

 更新时间:2022年05月26日 08:57:25   作者:scut_少东  
这篇文章主要介绍了vue 踩不完的异步之坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Js 的异步确实完美地解决了单线程的问题,但是同时也会带来许多问题。而且随着用的框架越来越多,越来越复杂,定位问题的难度也随之上升。

不知为什么,总觉得Vue 的断点调试相比于不使用框架的情况下更难用,这可能也是花了一个小时才找到问题产生的根源的原因。废话少说,以下便是问题产生的全过程以及查找问题的流程与逻辑梳理。

1. 任务需求分析

1.1 两个页面,两个组件

任务需求涉及到两个页面和两个组件之间的恩怨纠纷,它们的关系如下:

1.2 需求描述

  • 用户管理和权限管理是两个并列的页面。
  • 点开用户管理,里是userTable 组件展示出的用户列表。
  • 点开权限管理页面,然后点击页面上的组成员按钮,弹出modalUserList 弹框组件,modalUserList 中是userTable 组件展示的用户列表。
  • 点开用户管理时展示的是所有的用户列表,点开权限管理再点击组成员时展示的是属于该组的成员列表。

2. 功能是如何实现的?

2.1 以前端思维消化需求

  • 两个页面用到了同一个组件userTable,但是需要有不同的表现。所以我们需要一个tabletype 字段来标识当前是哪个页面引用了userTable 组件。
  • 用户点击权限管理页面的时候,他的孙子元素userTable 需要根据用户点击的记录id 来获取该组的用户信息,中间涉及两层父子组件通信,不太方便,使用vuex 进行处理。

2.2 代码实现 (简化版)

  • 用户管理页面引用userTable 组件的代码
<userTable
  :tableType="1"
  :userList="userList"></userTable>
  • 权限管理页面引用modalUserList 组件的代码
<modalUserList
  @closeModal="CloseModal"
  :id="chosenGroupId"
  :show="showUserList"></modalUserList>
  • modalUserList 组件引用userTable 组件的代码
<userTable
  :tableType="2"
  :userList="userList"></userTable>
  • 权限管理页面点击组成员按钮时的代码
ShowGroupUserList (index, row) {
  this.showUserList = true
  // 通知孙子获取用户列表
  this.SetAuthGetUserListTrue() // 通知孙子组件发送ajax 请求获取数据
  this.SetAuthGroupId(row.id)   // 设置authGroupId
}
  • userTable 组件mounted 和watch 代码
mounted () {
  this.GetUserList()
  // 权限管理点击按钮时才获取用户列表
  // 是通过点击权限管理的组成员按钮进入的
  if (this.authGetUserList) {
    this.GetUserListByGroupId(this.authGroupId)
    // 重新将刷新设为false
    this.SetAuthGetUserListFalse()
  }
}
watch: {
  authGetUserList: function (newV, oldV) {
    // 检查是否需要根据选择的权限组获取用户列表
    if (newV) {
      console.log(this.tableType)
      if (this.tableType == 1) {
        this.GetUserList()
      } else {
        this.GetUserListByGroupId(this.authGroupId)
      }
      // 重新将刷新设为false
      this.SetAuthGetUserListFalse()
    }
  }
}

2.3 代码翻译 

虽然贴了这么多代码,但是比较碎片化,一时半会可能不太好理清楚其中的逻辑所以这里再稍加解释,以上代码翻译成中文后大意如下:

  • 使用tableType 来区分,如果是从用户管理页面进入的,那么userTable 组件直接使用GetUserList 方法获取所有用户列表并显示。
  • 如果是从权限管理页面进入的,那么在用户点击组成员按钮的瞬间,权限管理页面发送通知告诉userTable 组件使用用户选择的行id 获取属于该权限组的用户列表并显示 (2.2 中最后两段代码)。

3. 遇到了什么问题?

  • 先进用户管理页面,再进权限管理页面,点击组成员按钮有大概率会展示所有用户列表而不仅仅是该权限组用户列表
  • 直接在权限管理页面点击组成员按钮有小概率会展示所有用户列表

4. 问题是如何解决的?

4.1 问题分析

分析一下问题的表现形式,针对问题的产生大概有以下两种猜测:

  • 由于tableType 类型传值错误导致表格显示数据出错。
  • 由于异步数据加载较慢,本次数据还没获取到,弹框就已经显示,显示内容是上次残留的数据,本次的数据获取到后由于某种原因没有触发页面重绘。

4.2 开始解决

查了一下代码发现tableType 传值并没有出现错误,第一条猜测不成立,那么大概率就是由于数据的异步获取导致的问题了。(虽然想不明白为什么获取到数据后没有触发页面重绘)

可能解决异步问题的一个猜想:等到数据加载完成了再显示弹框,而不是用户点击按钮的瞬间就显示(代价是爷孙组件通信),于是尝试在孙子组件加载数据完成时才通知爷爷组件显示弹框(父亲组件)。尝试失败,因为如果不先显示弹框,孙子组件就没有挂载,那就不能跟爷爷组件进行通信。

下一步,先显示父亲组件,等孙子组件获取数据成功后再显示孙子组件。设想功能成功实现,但是依然没有解决权限管理页面会显示所有用户列表的bug!

4.3 断点调试显神威

这个时候才想起来还是可以用断点调试的(使用Vue 以来基本都是用vue-dev-tools 进行调试了,刚好今天vue-dev-tools 又崩了...)。打断点一步一步走,发现在权限管理点击了组成员按钮的时候依然会在最后调用GetUserList 方法而不是GetUserListByGroupId 方法。为啥嘞?

回去看代码,2.2 中最后两段代码,mouted 中的写法,原来真的是有!问题!的!mounted 中的写法看起来是限先执行GetUserList,然后根据情况执行GetUserListByGroupId。可是由于异步的问题GetUserListByGroupId 方法获得返回值的时间不一定在GetUserList 之后,这就导致了bug 的不稳定性,有时正常,有时出问题了!

修改后的mounted 代码如下:

mounted () {
  // 权限管理根据权限组id 获取用户列表
  if (this.authGetUserList) {
    this.GetUserListByGroupId(this.authGroupId)
    // 重新将刷新设为false
    this.SetAuthGetUserListFalse()
  } else {
    // 用户管理直接获取所有用户列表
    this.GetUserList()
  }
}

呵呵哒,异步的坑踩了一个又一个!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 一步步详细讲解vue3配置ESLint

    一步步详细讲解vue3配置ESLint

    ESLint主要用于代码规范、统一代码风格,下面这篇文章主要给大家介绍了关于vue3配置ESLint的相关资料,文中通过图文以及实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • Vue2.0+ElementUI实现查询条件展开和收起功能组件(代码示例)

    Vue2.0+ElementUI实现查询条件展开和收起功能组件(代码示例)

    文章介绍了如何将查询条件表单封装成一个通用组件,以提高开发效率,组件支持多条件的折叠和展开功能,并提供了使用示例,感兴趣的朋友一起看看吧
    2025-01-01
  • 详解探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用

    详解探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用

    本篇文章主要介绍了详解探索 vuex 2.0 以及使用 vuejs 2.0 + vuex 2.0 构建记事本应用 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • VUE组件中的 Drawer 抽屉实现代码

    VUE组件中的 Drawer 抽屉实现代码

    这篇文章主要介绍了VUE组件 之 Drawer 抽屉 ,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • 详解Vue3中侦听器watch的使用教程

    详解Vue3中侦听器watch的使用教程

    学过 vue2 的小伙伴们肯定学习过侦听器,主要是用来监听页面数据或者是路由的变化,来执行相应的操作,在 vue3里面呢,也有侦听器的用法,功能基本一样,本文就来为大家详细讲讲
    2022-07-07
  • 深入解析vue中的权限管理

    深入解析vue中的权限管理

    权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源,这篇文章主要介绍了vue的权限管理的相关知识,需要的朋友可以参考下
    2022-06-06
  • vue+iview实现手机号分段输入框

    vue+iview实现手机号分段输入框

    这篇文章主要为大家详细介绍了vue+iview实现手机号分段输入框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 解决ant Design中this.props.form.validateFields未执行的问题

    解决ant Design中this.props.form.validateFields未执行的问题

    这篇文章主要介绍了解决ant Design中this.props.form.validateFields未执行的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • vue如何引入sass全局变量

    vue如何引入sass全局变量

    sass或者less都提供变量设置,在需求切换主题的项目中使用less或者sass变量,这篇文章主要介绍了vue引入sass全局变量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • Vue的路由动态重定向和导航守卫实例

    Vue的路由动态重定向和导航守卫实例

    下面小编就为大家分享一篇Vue的路由动态重定向和导航守卫实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03

最新评论