大数据毕业设计之前端09:导航栏tab的滑动块如何实现

10 篇文章 1 订阅
4 篇文章 0 订阅

前言

上一篇主要讲了如何动态添加导航栏的tab,那么本篇将会写如何关闭tab、实现滑动块已经一些细节上的操作。

这是实现新增、关闭等功能后的tabs.vue,里面绑定的方法逻辑都是我基于BuildAdmin重构实现的,后面在讲滑动块的时候,可以回来看看图中html的代码。

首个tab

在第一次访问BuildAdmin或者刷新页面时,导航栏只有一个tab,这里选择是将 控制台 设置成了第一个tab。

getFirstRoute

所以我在router.ts中,实现了getFirstRoute() 来获取第一个route。

export const getFirstRoute = (routes: RouteRecordRaw[]): null | RouteLocationNormalized => {
    let route: any = null
    routes.forEach((item) => {
        if (item.meta?.menu_type == 'tab') {
            route = item
        }t
    })
    return route
}

看过前面路由动态加载文章的知道,从后台获取的路由信息,处理后是放在了navTabs.state.tabsViewRoutes中,然后渲染menu。所以getFirst是对tabsViewRoutes进行遍历,来获取第一个route。

渲染首个tab

获取了第一个router怎么渲染到导航栏呢。看过上篇导航栏tabs的知道,最终是将navTabs.state.tabsView中的路由渲染成导航栏的tab,所以只要将firstRoute放到tabsView就可以了,那么什么时候放呢?

这里利用vue component的声明周期函数onMounted,这个函数之后再tabs.vue初始化完成之后执行,而且只会执行一次。然后将并将firstRoute渲染,并将activeRoute设置为firstRoute。

为了实现tab的关闭功能,tab右侧都会有一个叉号的icon。但是当只有一个tab的时候,是没有关闭按钮的,所以需要v-show来判断当前tabsView的长度是否大于1,如果是则显示。

<Icon v-show="navTabs.state.tabsView.length > 1" />

2. tab滑动块

我们点击菜单或者tab的时候,会发现有个滑动块会滑动到tab下面。

其实这个滑动块就是一个div,只不过它的宽度是和位置是动态可变的。滑动块的html在div.nav-tabs中是这么定义的:

<div :style="activeBoxStyle" class="nav-tabs-active-box"></div>

可以看到滑动块的style样式属性绑定了一个变量activeBoxStyle,接着来看看如何实现在js中,如何利用activeBoxStyle定义此div的位置和宽度。

定义activeBoxStyle

首先就是利用reactive来定义响应式的activeBoxStyle变量,定义两个属性,一个是width表示宽度,另一个trasnform是元素转换,滑动块实在水平轴上进行来回变换,所以就用translateX

const activeBoxStyle = reactive({
    width: '0',
    transform: 'translateX(0px)'
})

默认值都为0。

计算宽度和位置

思考一下,滑动块的宽度是不是选中tab(即activeRoute)的div的宽度,在水平轴的位置是不是tab的div的起始位置,这么一说,我们岂不是获取到选中的这个tab的div,然后通过一些属性取得width和startOffset不就行了?

css中,有一个clientWidth属性,表示的就是元素的宽度,offsetLeft是子元素(tab的div)左侧离父元素(navTab导航栏)的距离。

所以定义一个方法,来计算宽度和水平轴距离,赋值给activeBoxStyle。

 const selectNavTab = (dom: HTMLDivElement) => {
    activeBoxStyle.width = dom.clientWidth + 'px'
    activeBoxStyle.transform = `translateX(${dom.offsetLeft}px)`
}

形参dom代表的是tab的div元素。这样滑动块的宽度和在水平轴的位置就计算出来了。那么,什么时候要调用这个方法呢,或者换种说法,什么时候回触发滑动块的移动?

  1. 点击菜单,新增或跳转tab
  2. 关闭tab
  3. 刷新页面

因为我们只实现了新增和跳转tab,这里就先以此为例来讲滑动块的原理。

滑动块变化

还记得我们是如何实现tab的新增吗?

这里就是复习一下上一篇的addTabs() 实现新增tab的流程:当点击菜单路由时,在路由守卫中会调用setActiveRoute将即将跳转的路由,即to设置为activeRoute,并触发watch调用回调执行addTabs()。

然后判断tabsView中是否有这个路由,如果没有,则放入,并将activeIndex设置为activeRoute在tabsView中的下标。

那么我们也要在watch的回调函数中,实现滑动块的滑动,即调用selectNavTab方法。但是要新建/跳转的tab的div需要怎么获取。这时候就用到了 @vueuse/core 库中的useTemplateRefsList方法。

useTemplateRefsList的作用就是通过ref绑定在元素上,就能将元素的dom放到list中。

<div class="ba-nav-tab"
     v-for="(item, idx) in navTabs.state.tabsView"
     :ref="tabsRefs.set"
>
</div>

<script setup lang="ts">
  import {useTemplateRefsList} from '@vueuse/core'
  const tabsRefs = useTemplateRefsList<HTMLDivElement>()
</script>

ba-nav-tab就是一个个tab,使用ref将HTMLDivElement元素绑定在了useTemplateRefsList中。

那我们如何知道当前新建/跳转的tab是useTemplateRefsList中的哪个div。这时候,上一篇名不见经传的activeIndex就出来发挥作用了。

activeIndex是activeRoute在tabsView的位置,而tabsViews路由和RefsList中div元素是顺序对应的,所以通过activeIndex就能获取到目标div。

这样,就在动态新增/跳转tab时实现了滑动块。

结语

同样,在关闭tab时也会触发滑动块滑动,这个就放在下一篇tab的关闭中一起讲,期待下一次再见。

  • 24
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值