多标签页很多公司的后台管理系统都会有这个需求,之前用vue一般架子也是带的,现在公司用了antd pro ,看了下官方不支持,确实会影响性能,但是架不住需求。

补充: antdpro 已经内置了多页签,可以自己配置看看。这篇文章留着学习。

背景


先看下远古截图:

https://github.com/ant-design/ant-design-pro/issues/220

17年提出的需求现在还没有实现,看样官方也是铁了心了。在看看提供的其他解决方案:

  • https://github.com/LANIF-UI/dva-boot-admin
  • https://github.com/kuhami/react-ant
  • https://github.com/zkboys/react-admin
  • https://github.com/kuhami/react-ant-pro
  • https://github.com/MudOnTire/antd-pro-page-tabs
  • https://github.com/zpr1g/ant-design-pro-plus
  • https://github.com/lengjh/antd-design-pro-tabs
  • https://github.com/alitajs/alita/tree/master/packages/tabs-layout

另外我还找到了一个插件也可以实现:

https://github.com/fangzhengjin/umi-plugin-panel-tabs

这些不是因为这版本不对,就是细节不满意决定自己实现一个版本。

自己实现的好处:

  • UI自定义
  • 功能添加方便,知道核心原理,修改Bug也方便。

核心原理


先看最后实现的版本:

核心问题:

  1. 菜单标签路由地址联动
  2. 标签卡内容需要缓存,切换不丢失
  3. 后台返回路由也应该支持

功能实现


核心实现思路:

  1. 通过地址栏变化匹配路由变化标签栏
  2. 标签卡选用Tabs组件+ Route 标签加key缓存
  3. dva来实现数据管理,也可以选用别的,能全局操作即可。

具体逻辑就是,写一个TabsView 组件,在Layout chlidren的时候嵌套上Tabs 多页签卡这一层。

Layout 文件夹Index.ts 文件:

<TabsViewactiveKey={getActiveKey(props.tagsModel)}tags={props.tagsModel}route={props.route}dispatch={props.dispatch}/>

1、 数据实现组织

利用dva 来实现tags 数组的增删改查,具体代码如下:

/** @Author: ZY* @Date: 2021-10-25 13:42:43* @LastEditors: ZY* @LastEditTime: 2022-05-01 10:18:48* @Description: dva tags* tabs 整理设计思路:* 需求:两种逻辑,一种是菜单功能,功能、路由、tag是一对一的关系,另一种单据类可以开多个* 设计:* 利用tabs 进行页面布局,来实现缓存的目的。key是path和query的合集,这样能满足需求* 利用dva组织数据* 动态加载组件,组件利用key关联*/
import type { Reducer } from 'umi';
import _remove from 'lodash/remove';
import _cloneDeep from 'lodash/cloneDeep';
import _findIndex from 'lodash/findIndex';export interface Tag {key: string;title: string;path?: string;active: boolean;query?: any;
}export type TagsStateType = Tag[];export interface TagsModelType {namespace: 'tagsModel';state: TagsStateType;reducers: {addTag: Reducer<TagsStateType>;updateActive: Reducer<TagsStateType>;removeTag: Reducer<TagsStateType>;removeAllTags: Reducer<TagsStateType>;};
}/*** @description: 初始化tab* @param {*}* @return {*}*/
const homeTag: Tag = {key: `/dashboard`,title: '首页',active: true,path: '/dashboard',
};/*** @description:* @param {*}* @return {*}*/
const addNewTag = (tags: Tag[], newTag: Tag) => {if (_findIndex(tags, (t) => t.key === newTag.key) === -1) {// tags数组里面有没有新增的tagconst cTags = tags.map((t) => {const ct = _cloneDeep(t);ct.active = false;return ct;});return [...cTags, newTag];}// 新增tag 在数组中,选中即可。const cTags = tags.map((t) => {const ct = _cloneDeep(t);ct.active = ct.key === newTag.key;return ct;});return cTags;
};const TagsModel: TagsModelType = {namespace: 'tagsModel',state: [homeTag] as TagsStateType,reducers: {addTag: (state, action) => {if (state) {return addNewTag(state, action.payload);}return [];},updateActive: (state, action) => {if (!state) {return [];}const cTags = state.map((t) => {const ct = _cloneDeep(t);ct.active = ct.key === action.payload;return ct;});return [...cTags];},removeTag: (state, action) => {if (!state) {return [];}const ct = _cloneDeep(state);if (ct.filter((t) => t.active)[0].key === action.payload) {_remove(ct, (tag: Tag) => tag.key === action.payload);// 如果关闭的是当前选中的标签,默认选中最后一个的策略ct[ct.length - 1].active = true;} else {_remove(ct, (tag: Tag) => tag.key === action.payload);}return [...ct];},removeAllTags: () => {return [];},},
};export default TagsModel;

2、 tabsView 组件核心代码

这里会遍历tags 数组,然后创建tab, 每一个tab 都用Route 标签缓存,通过路径匹配的组件。

 <TabsactiveKey={activeKey}type="editable-card"hideAdd={true}onEdit={tabOnEdit}onChange={tabOnChange}onTabClick={onTabClick}>{tags.length &&tags.map((tag) => {return (<TabPane tab={tag.title} key={tag.key} closable={tag.key !== '/dashboard'}><Route key={tag.key} component={getPathComponent(tag.path!)} exact /></TabPane>);})}</Tabs>

通过路径找到组件

 const getPathComponent = (path: string) => {const r = route.routes?.filter((t) => {// 如果是动态路由,匹配非动态部分if (t.path?.includes(':')) {return path.includes(t.path.split(':')[0]);}return t.path === path;})[0];return (r as any).component;};

这样核心内容基本讲完,边缘代码就不多赘述了,代码再项目里还没来得及抽取,如有需要以后找时间发出。

应同学们要求匆忙抽取了这部分代码demo ,地址如下:

https://github.com/RainManGO/antd-pro-v5-tabs

antd pro v5 tab标签卡(多标签页)实现相关推荐

  1. Error: Module “xxx“ does not exist in container. / antd pro v5启用qiankun报错 / 同时使用mfsu和qiankun报错

    一.问题描述 我们用antd pro v5搭建前端项目,启用qiankun微前端模式,终端报错如下: Uncaught (in promise) Error: Module "xxx&quo ...

  2. antd pro v5

    antd pro v5 关于网络请求和路由设置相关 网络请求 antd在前段时间发布了v5版本,已经支持预览了,大家可以通过链接v5预览. 看完文档再对比v4,我个人感觉v5精简了不少,首先是弱化了d ...

  3. antd pro(V5) 实现多tab

    官方默认不支持多tab,所以需要自己去处理根据以往的经验这个不是很复杂. 主要的技术点如下: 1.样式(抄的vue-element-admin) 2.antd pro项目干预点app.tsx impo ...

  4. Bootstrap 导航元素( tab导航)标签页

    1.基本的导航元素:标签导航.基于ul.li而来,给ul添加 class="nav nav-tabs" 即可.选中的li添加 class="active"即可. ...

  5. java antd实现登录_Spring WebFlux + React搭建后台管理系统(3): antd pro v5实现登入登出...

    antdpro是蚂蚁金服开发的后台管理框架模板,继承了许多组建,可以满足快速开发,组建使用的antd,组建种类比较多,功能比较全,设计也挺好看的,但是封装程度有点高,用起来可能不是很灵活,一些功能需要 ...

  6. antd pro V5调整标题,菜单字体样式

    项目场景: 需要修改Antd Pro标题和菜单字体的大小和样式. 解决方案: Antd Pro原始默认字体是14px:通过控制台的小箭头,去查找菜单字体的className.在样式栏里面点击对应的cs ...

  7. antd pro v5修改title

    修改菜单上方(左侧) 的系统名称 在config/defaultSettings.ts中添加title:"新的系统名称"即可

  8. antd pro V5从服务端请求菜单

    要从服务端请求菜单可以在src下的app.tsx中修改运行时配置,menuDataRender或者menu, 在本人测试中如果使用menu项配置可以实现从服务端请求代码,不过locale:false无 ...

  9. Vant Tab标签页

    引入 import Vue from 'vue'; import { Tab, Tabs } from 'vant';Vue.use(Tab); Vue.use(Tabs); 代码演示 基础用法 通过 ...

最新文章

  1. 在Spring.Net中对于NHibernate.Caches.Prevalence的使用
  2. 《JavaScript 高级程序设计》学习总结五(3)
  3. asp net code
  4. 听说你想去大厂看学妹,带你看看网易互娱游戏测试面经
  5. matlab使用常犯的错误
  6. Mysql慢查询操作梳理
  7. 怎样查看JVM的默认收集器
  8. .net excel导入mysql_.NET Core使用NPOI将Excel中的数据批量导入到MySQL - 追逐时光者 - 博客园...
  9. 【最新教程】Pytorch还是Tensorflow超强两大框架实战
  10. 移动开发:怎么去掉点击时出现背景蓝色
  11. win7 由ie8升级ie11时安装不成功的一个原因
  12. 中国移动互联网半年大报告解析
  13. Android Studio中Cannot resolve symbol XXX的解决方法
  14. 用python爬取公众号推送图片并保存为PPT
  15. Element-UI组件之其他Others
  16. 校招潜规则,泄密太多我担心大厂HR封杀我
  17. MySQL经典四表查询(教师,学生,成绩,课程表)多表查询
  18. Expect 自动化控制和测试 Here Document 免交互 Linux- shell编程之免交互
  19. python调用大漠getcursorpos,GetCursorPos()函数
  20. r语言mysql包_R语言之RMySQL包

热门文章

  1. STM32_寄存器版本代码第一篇LED灯
  2. Allegro 批量采集( 采集 产品)、批量offer刊登( 刊登 产品)、铺货上架利器-ERP
  3. 鞍点(MOOC 翁凯 C语言源码)
  4. 如何批量隐藏Excel中手机号码四位数?
  5. Ckp的约会(xmu oj)贪心算法问题 by C++
  6. 博途PLC滤波指令 Filter_PT1、Filter_PT2、Filter_DT1详细使用说明(含Simulink+博途PLC仿真)
  7. 地理探测器的下载和使用
  8. Excel 函数大全之 INTERCEPT function 获取线性回归线的截距
  9. 栅格数据像元大小0.000几的处理方法或重采样失败显示像元过大或者过小
  10. docker-comose搭建openldap + svn + apache