相信大家都有做过这类的后台管理系统

我们团队也有类似于这样的后台管理系统平台,且当用户切换到某一个页面时,这个页面都得去请求最新的数据,呈现出来~

这就会造成一个问题:当用户频繁切换 Tab 切换的时候,就会不断地去发起请求,进行渲染呈现,但是其实正在有意义的只有用户最后一次切换到的页面,我服了,真有人会这么频繁切换吗?不会是用户自己切着玩吧?

那应该怎么去优化呢?很多人第一时间想到了防抖,但是我想说的是:一般的防抖还真防不住!

一般的防抖

如果是比较普通的场景还是可以用用一般防抖的,就比如某一个页面内的 Tab 切换,因为这一类的 Tab 切换说到底就是在同一个页面组件下去写代码逻辑,所以也比较好控制这些 Tab 切换后的防抖处理

我们用一个小案例来演练一下,我准备四个文件,Index.vue、Tab1.vue、Tab2.vue、Tab3.vue

Tab1.vue

Tab2.vue

Tab3.vue

Index.vue

我们只需要在 Index.vue 中监听 Tab 的切换,然后获取对应的组件实例,去执行它们的 init 方法,就可以做到每次切换 Tab 都能去请求获取最新的数据

有人会问为啥不能直接将每个组件中的 init 写在各自的 onMounted 中?我来回答一下吧,因为 Tab 默认会做页面缓存,也就是只有第一次切换过去才会执行 onMounted,往后都不会执行了,这样有助于提升性能,所以不能将 init 写在 onMounted 中~

现在我们切换 Tab,会发现每切换一次就去运行请求一次,这显然违背了我们的期望

所以我们可以直接给 onTabChange加上防抖,即可解决此问题

现在我同样是频繁切换,但是最终发起请求的只有一次,也就是用户最终跳转到的 Tab

进阶版防抖

上面所说的一般的防抖只能适用于代码逻辑相对于比较集中的场景

但是如果是那种代码逻辑比较分散的场景呢?比如后台管理系统中,通过切换不同的 Tab 去切换不同的 路由页面,且这些页面都是经过 keep-alive 处理过的,且每个页面的请求逻辑都放在 onMounted 中

这些页面都是一个个的文件夹管理的,代码逻辑相对比较分散

为了简化场景,降低大家的阅读成本,我还是用刚刚的代码来模拟,还是 Index.vue、Tab1.vue、Tab2.vue、Tab3.vue

Tab1.vue

Tab2.vue

Tab3.vue

Index.vue

我们切换 Tab 时,可以发现每个 Tab 的请求只会发起一次,因为 onMounted 只会执行一次

但是我们想要的是每次切换 Tab 之后,每个页面都要去重新发起请求,那应该怎么做呢?

其实很简单,我们只需要 “改造” 一下 onMounted 即可

我们新建一个useCustomMounted.ts ,使用 watch + nextTick 来取代 onMounted

接着在Tab1.vue、Tab2.vue、Tab3.vue 中去使用这个 onCustomMounted,这里我只贴出 Tab1.vue 的,其他两个 Tab 同理,我就不贴出来了

接着在 Index.vue 中需要去监听 Tab 变化,并触发 changeActiveKey

现在切换 Tab 时,每次都会触发请求的起了

接下来就要加上防抖了,只需要加在 changeActiveKey 上即可

现在我同样是频繁切换,但是最终发起请求的只有一次,也就是用户最终跳转到的 Tab