前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我攻克的技术难题 - BuildAdmin15:一键关闭所有tab,vue是如何做到的

我攻克的技术难题 - BuildAdmin15:一键关闭所有tab,vue是如何做到的

原创
作者头像
叫我阿柒啊
修改2024-02-17 07:49:31
2640
修改2024-02-17 07:49:31
举报

前言

上一篇写了 关闭当前标签 的功能实现,其中涉及了很多之前写过的知识点。今天就来看看关闭其他标签,关闭全部标签两个标签功能的实现,是否和关闭当前标签有什么关联。

代码语言:typescript
复制
case 'closeOther':
    closeOtherTab(menu)
    break
case 'closeAll':
    closeAllTab(menu)
    break

关闭其他标签

BuildAdmin中定义了closeOtherTab,用来关闭其他标签。在之前tabs的实现中曾经讲到,讲过tabs的渲染是通过v-for遍历tabsViews实现的。

那么关闭其他标签的实现思路就是:遍历navTabs中的tabsViews,通过filter只留下选中tab对应的menu路由即可 。这里我们先看closeOtherTab是如何定义的。

代码语言:typescript
复制
const closeOtherTab = (menu: RouteLocationNormalized) => {
    navTabs.closeTabs(menu)
    if (navTabs.state.activeRoute?.path !== menu.path) {
        router.push(menu)
    }
    navTabs.setActiveRoute(menu)
}

closeTabs

首先调用了navTabs状态中closeTabs方法,我们去navTabs.ts去看看代码逻辑。

之前关闭按钮和弹出框关闭tab的两种方式,都是调用了closeTab,在实现关闭其他标签页时,重新定义了closeTabs方法。

代码语言:typescript
复制
const closeTabs = (retainMenu: RouteLocationNormalized | false = false) => {
    if (retainMenu) {
        state.tabsView = [retainMenu]
    } else {
        state.tabsView = []
    }
}

参数retainMenu是需要保留的标签或者false。当传入一个menu时,tabsView会被初始化为只包含此menu的list,即关闭了其他所有的标签。当传入的是false,tabsView被初始化为空list,即关闭了所有的标签。

所以,closeTabs方法同时实现了关闭其他、关闭所有标签的两个功能,接着回到closeOtherTab,看看后面的实现。

滑动块

在关闭其他tab有两种情况:

  1. 关闭的tab是当前激活的,即滑动块所在的,路由不变。
  1. 关闭的tab是非激活的。

第一种情况,我们只需要考虑滑动块的位置改变即可。第二种情况,除了考虑滑动块位置的改变,还要跳转到选中tab的那个页面,即路由跳转。那么,滑动块的位置是如何改变的?

在之前滑动块的滑动实现中,我们定义了selectNavTab方法,当activeRoute改变时,就会调用此方法.

所以我们只需要修改activeRoute即可。对于tab是否为激活的判断,只需要将activeRoute和menu对比即可。所以closeOtherTab最后几行代码就实现了上面的两个功能点.

代码语言:typescript
复制
if (navTabs.state.activeRoute?.path !== menu.path) {
    router.push(menu)
}
navTabs.setActiveRoute(menu)

这样,就实现了关闭其他标签

关闭所有标签

关闭所有标签的设计思路为:关闭tabs栏中所有的tab,然后打开应用的第一个tab(即firstRoute,控制台)。所以,这里也会出现两种情况:

  1. 在控制台的tab上,选择关闭所有标签。
  1. 在非控制台的tab上,选择选择关闭所有标签。

第一种情况,其实直接关闭除了控制台之外的其他标签就行了,没有必要关闭了所有tab之后再创建一个控制台的tab,所以这种情况下问题就转变成了在控制台tab上关闭其他标签

第二种情况,就是之前提及的设计思路。在BuildAdmin中,定义了closeAllTab方法来关闭所有标签。

代码语言:typescript
复制
const closeAllTab = (menu: RouteLocationNormalized) => {
    const firstRoute = getFirstRoute(navTabs.state.tabsViewRoutes)
    // 第一种情况
    if (firstRoute && firstRoute.path == menu.path) {
        return closeOtherTab(menu)
    }
    // 第二种情况
    navTabs.closeTabs(false)
    if (firstRoute) router.push(firstRoute.path)
}

首先获取firstRoute来判断当前激活的tab是不是控制台,如果是,直接调用closeOtherTab关闭除控制台之外的tab。如果不是,则调用navTabs.closeTabs并传入false。

在上面关闭其他标签中讲过,传入false,tabsView被初始化为空的list。意味着tabs栏中将没有tab,这时候路由再跳转到firstRoute,打开控制台的tab。这样就实现了关闭所有标签的功能。

优化

虽然实现了关闭其他标签、关闭所有标签的功能,但是在后面的使用中可以根据个人的需要进行优化。

关闭其他标签

如果我们在某些页面上做了一些修改,当使用关闭其他标签关闭了这些页面之后,再重新打开,你会发现这些修改了的数据还是存在的。

如图,新建的控制台页面count为0,我将count累加到6之后,通过关闭其他标签关闭了控制台,重新打开控制台的count还是7。关闭所有标签同样也面临这个问题。

关闭所有标签

BuildAdmin中,控制台是firstRoute。所以当我们关闭所有标签时,会在tabs栏自动创建渲染控制台的tab。

在关闭所有tab时,如果tabs中没有控制台,则会新建控制台tab;如果tabs中有控制台,看起来是关闭了所有之后再新建控制台,其实还是复用了之前的组件。

如图,新建的控制台页面count为0,我将count累加到7之后关闭所有标签,然后“新建”的控制台的count还是7。

方案

出现这种现象的原因,就是之前讲的keep-alive的缓存机制导致的,具体可以参考BuildAdmin13:重新加载和keep-alive缓存。虽然通过标签关闭了页面,但是keep-alive的keepAliveComponentNameList中的组件缓存还没有删除。

但是通过关闭按钮关闭的tab,再重打开之后缓存就没了。

是因为在closeTab中通过mitt时间总线库,定义onTabViewClose事件关闭了对应tab的缓存。

同样,通过弹出框的关闭页面标签也没有缓存。

是因为关闭页面标签直接复用了closeTab,所以关闭页面的同时也删除了缓存。

那么,对于关闭其他标签、关闭所有标签删除缓存,其实也很简单。分别定义一个mitt事件,关闭其他标签时,遍历keepAliveComponentNameList,根据tab的route(menu)只留下此tab对应的组件缓存。

关闭所有标签时更为简单,直接将keepAliveComponentNameList = [],然后对firstRoute新建,并将新建的组件放入缓存中。

可以参考BuildAdmin14:关闭tab的mitt实现 onTabViewClose事件的实现。这两个部分的具体实现我这里就不写了,因为BuildAdmin中也是默认不删除缓存。

勾选了选择框,通过关闭其他关闭之后再打开,复选框依旧被勾选。存在即合理,有些场景下还是需要这种缓存功能的。

结语

本篇文章实现了弹出框的关闭其他标签和关闭所有标签的功能,归根结底还是对之前各个模块功能实现的再次整合。所以,还是那句话,学习是一个层层递进的理解过程,学了后面的不要忘了前面的

至此,弹出框的五个标签已实现其四,下篇文章就写剩下的最后一个标签全屏,同时作为第五期训练营的第21篇文章,来做一个good ending。

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 关闭其他标签
    • closeTabs
      • 滑动块
      • 关闭所有标签
      • 优化
        • 关闭其他标签
          • 关闭所有标签
            • 方案
            • 结语
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档