|
|
@ -1,13 +1,14 @@ |
|
|
|
最近在写基于 React 和 Antd 的后台管理系统,用作我的博客管理上,在参考其他开源项目的时候有一个功能我很感兴趣,就是在管理后台中加入一个像浏览器 Tabs 标签页的功能,让它实现切换标签页的功能,虽然现在的管理系统的页面总数不多其实没有什么快速切换的需求 = = |
|
|
|
最近在写基于 React 和 Antd 的后台管理系统,用在我的博客管理上,在参考其他开源项目的时候有一个功能我很感兴趣,就是在管理后台中加入一个像浏览器的 Tabs 功能,让它能实现标签页的快速切换,虽然现在的管理系统的页面总数不多其实没有什么快速切换的需求 = = |
|
|
|
|
|
|
|
|
|
|
|
刚看到这个问题的时候,我的第一反应是有没有一个 API 可以记录并获取路由栈中的所有路由,再将其给渲染出来,就解决了标签页的显示问题,但是我找了一下似乎并没有这样的 API,所以这篇文章会用 Context + useEffect 监听路由的方式来实现标签页的显示。 |
|
|
|
刚看到这个问题的时候,我的第一反应是有没有一个 API 可以记录并获取路由栈中的所有路由,再将其给渲染出来,就解决了标签页的显示问题,但是我找了一下似乎并没有这样的 API,所以这篇文章会用 Context + useEffect 监听路由的方式来实现标签页的显示。 |
|
|
|
|
|
|
|
|
|
|
|
## 大致的思路 |
|
|
|
## 大致的思路 |
|
|
|
外层用 Context 包裹,在 Context 内部用 useEffect 监听路由是否发生变化,也就是 pathname,如果发生了变化就记录路由的属性,因为要实现显示Tab名称、Tab 跳转和保存路由的查询参数,所以记录的时候这些信息要一起保存起来。 |
|
|
|
外层用 Context 包裹,在 Context 内部用 useEffect 监听路由是否发生变化,如果发生了变化就在 Tabs 列表中加入变化的路由属性,因为要实现显示Tab名称、Tab 跳转和保存路由的查询参数,所以记录的时候这些信息要一起保存起来。 |
|
|
|
其实这个功能是可以不用 Context 实现,在 Tabs 组件内部使用 useEffect 也能实现相同的功能,但是我考虑到后边管理后台中或许会有别的页面也会需要用到类似的功能,就把它抽离出来方便复用。 |
|
|
|
|
|
|
|
|
|
|
|
其实这个功能也可以不用 Context 实现,在 Tabs 组件内部只使用 useEffect 也能实现相同的功能,但是我考虑到将来管理后台中或许会有别的页面也会需要用到类似的功能,就把它抽离出来方便复用。 |
|
|
|
|
|
|
|
|
|
|
|
## Tabs 添加路由 |
|
|
|
## Tabs 添加路由 |
|
|
|
有思路之后实现起来就很容易了,首先要实现一个 Context ,这个很简单直接跳过,然后实现一个路由的监听记录函数,这里用 useEffect 来做,具体的逻辑可以看函数的注释 |
|
|
|
有思路之后实现起来就很容易了,首先要写一个 Context ,这个很简单在这里直接跳过,然后实现一个路由的监听记录函数,这里用 useEffect 来做,具体的代码逻辑可以看函数的注释 |
|
|
|
|
|
|
|
|
|
|
|
```javascript |
|
|
|
```javascript |
|
|
|
// react-router 的 useLocation Hook |
|
|
|
// react-router 的 useLocation Hook |
|
|
@ -47,10 +48,11 @@ const addTabItem = (path, search) => { |
|
|
|
}; |
|
|
|
}; |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
以上的逻辑就是最核心的部分,通过监听路由变化,我们得到了一个 Tabs 列表,后续只需要渲染出它显示的问题就解决了 |
|
|
|
以上的逻辑就是最核心的部分,通过监听路由变化,我们得到了一个 Tabs 列表,后续只需要渲染出它那么 Tabs 显示的问题就解决了 |
|
|
|
|
|
|
|
|
|
|
|
## Tabs 切换路由和关闭路由 |
|
|
|
## Tabs 切换路由和关闭路由 |
|
|
|
解决了 Tab 添加的问题,接下来要解决的就是 Tab 的切换和关闭,总不能只能开不能关吧,点击和切换的代码逻辑很简单,代码量也很少,没有什么难点 |
|
|
|
解决了 Tab 添加的问题,接下来要解决的就是 Tab 的切换和关闭,总不能只能开不能关吧,切换和关闭的代码逻辑很简单,代码量也很少,没有什么难点 |
|
|
|
|
|
|
|
|
|
|
|
对于 Tab 的切换,我们需要一个新的状态来保存当前被选中的 Tab,这里叫作 activeTab |
|
|
|
对于 Tab 的切换,我们需要一个新的状态来保存当前被选中的 Tab,这里叫作 activeTab |
|
|
|
|
|
|
|
|
|
|
|
```javascript |
|
|
|
```javascript |
|
|
@ -65,7 +67,7 @@ const switchTab = (path, search = "") => { |
|
|
|
}; |
|
|
|
}; |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
而对于 Tab 的关闭,就没什么好说的了,查找然后删除,这里有一个特殊的处理,就是判断关闭的 Tab 是不是当前选中的 Tab,对于关闭当前选中 Tab 的操作,这里会把当前选中的 Tab 移动,保证页面上不会出现关闭了 Tab 但是页面还没有被关闭 |
|
|
|
而对于 Tab 的关闭,就没什么好说的了,非常简单的查找然后删除,这里有一个特殊的处理,就是判断关闭的 Tab 是不是当前选中的 Tab,对于关闭当前选中 Tab 的操作,这里会把当前选中的 Tab 向前移动,保证页面上不会出现关闭了 Tab 但是页面还停留在原地的问题 |
|
|
|
|
|
|
|
|
|
|
|
```javascript |
|
|
|
```javascript |
|
|
|
const closeTab = (path) => { |
|
|
|
const closeTab = (path) => { |
|
|
@ -83,6 +85,4 @@ const closeTab = (path) => { |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
## End |
|
|
|
## End |
|
|
|
至此,整个 Tab 功能的基本逻辑就已经实现了,完整的代码可以看[这里](https://github.com/YuJian920/YuJian-Blog/blob/Remake/YuJianBlog-Admin/src/context/TabContext.tsx),其实完整的 Tab 功能还没有结束,例如还有 Tab 长度的限制,避免打开的 Tab 太多导致长度过长,还有完备的 Tab 应该有一个右键菜单,可以实现关闭其他、关闭所有之类的更多的功能,这里就不展开谈了,如果有时间的话后边会再写一篇文章补全上述提到的这些功能 |
|
|
|
至此,整个 Tabs 功能的基本逻辑就已经实现了,完整的代码可以看[这里](https://github.com/YuJian920/YuJian-Blog/blob/Remake/YuJianBlog-Admin/src/context/TabContext.tsx),其实完整的 Tabs 功能还没有结束,例如还有对 Tabs 长度的限制,避免打开的 Tab 太多导致长度过长,还有完备的 Tabs 应该有一个右键菜单,可以实现关闭其他、关闭所有之类更多的功能,这里就不展开谈了,如果有时间的话后边会再写一篇文章补全上述提到的这些功能 |
|
|
|
|
|
|
|
|
|
|
|
也可以去我的[博客](https://yujian.icu/Article/14)看看~ |
|
|
|
|