前言
之前的两篇文章,一篇实现了tab页的新增,一个讲了如何实现滑动块,本篇就来讲一下如何实现tab的关闭,以及tab关闭时滑动块的变换情况。
关闭tab
关闭tab主要从两个方面实现:
- 定义关闭tab方法
- 触发滑动块位置的修改
绑定点击事件
tab主要分为两个部分,左边的名称和右边的关闭按钮,我们这里给关闭按钮绑定一个点击事件。
<Icon v-show="navTabs.state.tabsView.length > 1" class="close-icon"
@click.stop="closeTab(item)" />
@就是v-on的缩写,click绑定了关闭函数closeTab,但是后面的 .stop是什么呢?
stop的作用是阻止事件冒泡,当我们在父元素中添加了一个click事件A,并且在其下的子元素中也添加了一个click事件B。这时我想点击子元素触发子元素的点击事件,但实际上会先触发子组件的A事件,然后触发父组件的B事件。
在这里B事件代表的就是:点击tab跳转页面事件。
从上图可以看到tab定义了一个@click事件,绑定了onTab。在之前只讲了tab的新增,没有讲tab跳转,就是留在这里讲。onTab其实就一行代码,调用router.push完成路由的跳转。
const onTab = (menu: RouteLocationNormalized) => {
router.push(menu)
}
而关闭按钮作为tab的子组件,定义了点击事件A,如果不使用.stop,那么当我关闭当前tab,还会触发当前tab对应的路由跳转,这样就乱套了。
除了stop,prevent也是后面会用到一个功能,prevent的作用是阻止触发dom的原始事件,而只执行我们自定义的事件,这里在后面用到会讲。
接下来就如看看如何定义点击事件closeTab() 。
定义点击事件
关闭tab又分为两种情况:
- 关闭的是滑动块所在的tab,即被激活的tab
- 关闭的是非滑动块所在的tab
如何区分是不是滑动块所在的tab呢,用关闭tab的route.path与activeRoute.path一比较就可以了。代码看下图:
首先直接调用状态变量navTabs的closeTab,看看closeTab是如何定义的.
function closeTab(route: RouteLocationNormalized) {
state.tabsView.map((item, index) => {
if (item.path === route.path) {
state.tabsView.splice(index, 1)
}
})
}
tabsView存放的就是所有的tab,遍历tabsView,与将要关闭tab的route比较,找到其在tabsView中的下标,即index,使用splice将其删除。splice一共两个参数,第一个是要删除的位置,第二个是删除的元素个数。
移动滑动块
最后就是考虑如何移动滑动块了。上面列举了关闭tab的两种情况,那么滑动块的移动也得针对于以上两种情况进行分别实现。
1. 关闭激活tab
如果关闭的是激活的tab,在BuildAdmin中就让滑动块跳到最后一个(如果你想跳到相邻的tab,也可以实现)。在上面的代码中可以看出来这种情况调用了toLastTab方法。
看看toLastTab是如何实现的。
const toLastTab = () => {
const lastTab = navTabs.state.tabsView.slice(-1)[0]
if (lastTab) {
router.push(lastTab.path)
} else {
router.push('/admin')
}
}
toLastTab的实现比较简单粗暴,就是利用slice取出tabsViews最后一个元素,直接使用router.push进行跳转。
2, 关闭非激活tab
当关闭非激活的tab时,滑动块位置会发生变化,但还是修饰之前的activeRoute。
这个在closeTab中是如何实现的呢?
nextTick(() => {
if (navTabs.state.activeRoute != null) {
navTabs.setActiveRoute(navTabs.state.activeRoute)
}
const div = tabsRefs.value[navTabs.state.activeIndex]
selectNavTab(div)
})
在上一篇滑动块写到,是将tab的div元素引用放到了一个list中,然后通过activeIndex获取对应tab的div,然后通过div的offsetLeft属性来获取滑动块在水平轴上的起始位置。所以关键点就是获取activeIndex。
那为什么调用setActiveRoute?因为每次调用setActiveRoute都会对activeIndex重新赋值。
所以这里就获取到了activeRoute在删除一个tab之后的tabsView中的位置,即activeIndex。然后通过activeIndex获取在引用list(tabsRefs)的div引用,调用selectNavTab来计算offset和width,然后赋值给activeBoxStyle,从而触发滑动块移动。
至于为什么要在nextTick中实现滑动块逻辑,因为nextTick是页面加载完成之后的一个回调,如果页面加载位完成,tab所在的div可能就没有初始化完成,就会报空指针异常。
结语
这就是我整理的关于tab关闭的一个思路,关键是捋清tab关闭时的两种情况,这样实现起来就比较容易,同时在功能开发的过程中,遇到了不少新的问题,同样也学到了新的知识。
标签:10,tab,事件,关闭,tabsView,毕业设计,滑动,div From: https://blog.csdn.net/CatchLight/article/details/135877716