ant design pro v5 - 07 多标签窗口 多窗口打开

2023-10-30

1 安装组件:

安装 yarn add umi-plugin-keep-alive

2 创建模板:/src/services/types/menu.ts

export interface menuTabProps {
    tab: string;
    pathname?: string;
    key: string;
    closable?: boolean;
  }
  
  export interface menuItemProps {
    name: string;
    path?: string;
    children?: menuItemProps[];
  }

3 创建模板:/src/utils/base.ts

import type { menuItemProps } from '@/services/types/menu';

/**
 * 处理菜单为一级数组
 * menus: 菜单数组
 */
export const handleMenusToFlat = (menus: menuItemProps) => {
  const flatMenus: any[] = [];
  const handle = (arr: any) => {
    arr.forEach((item: menuItemProps) => {
      if (item.routes && item.routes.length) {
        handle(item.routes);
      } else {
        flatMenus.push({
          pathname: item.path,
          name: item.name,
        });
      }
    });
  };
  handle(menus);
  return flatMenus;
};

4 创建模板:/src/models/exitMenus.ts

import type { menuTabProps } from '@/services/types/menu';
import { useState, useCallback } from 'react'

export default () => {
  const [exitMenus, setExitMenus] = useState<menuTabProps[]>([]);

  // 改变缓存菜单
  const updateMenus = useCallback((menus: menuTabProps[]) => {
    setExitMenus(menus);
  }, []);

  return {
    exitMenus,
    updateMenus,
  };
};

 5 文件位置:/src/global.less   插入样式

// 多标签窗口
.antLayoutAdminTabs {
  width: 100%;
  height: 40px;
  display: block;
  :global {
    .ant-tabs {
      top: 72px;
      position: fixed;
      padding: 0 16px;
      width: 100%;
      margin: -24px -24px 0;
      background: #fff;
      z-index: 18;
      overflow: hidden;
      height: 40px;
      box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
    }

    .ant-tabs-tab {
      background: #ffffff !important;
      border: 0 !important;
      font-size: 14px !important;
      border-bottom: 2px solid#ffffff !important;
      padding: 8px 18px !important;
    }

    .ant-tabs-tab-active {
      background: #e6f7ff !important;
      color: #1890ff !important;
      border-bottom: 2px solid#1890ff !important;
    }
  }
}

6 创建模板:/src/pages/layouts/commonLayout.tsx

import React, { useEffect, useState } from 'react';
import { Tabs } from 'antd';
import { history, useModel } from 'umi';
import { find } from 'lodash';
import { menuTabProps } from '@/services/types/menu';
import { handleMenusToFlat } from '@/utils/base';
import { KeepAlive, useAliveController } from 'react-activation';
import global from '@/global.less';

const CommonLayout = (props: any) => {

  const { location, route } = props;



  const { pathname } = location;
  const [activeKey, setActiveKey] = useState<string>('');
  const { dropScope } = useAliveController();
  const { exitMenus, updateMenus } = useModel('exitMenus', (model) => ({
    exitMenus: model.exitMenus,
    updateMenus: model.updateMenus,
  }));

  const flatMenus = handleMenusToFlat(route.routes);
  const noCachRoutes = ['/', '/user/login']; // 不需要缓存的路由

  // console.log("2222222222222222222222222222222222222", route);

  useEffect(() => {
    // console.log(333, location, flatMenus);
    if (noCachRoutes.includes(pathname)) return;
    const arr: menuTabProps[] = exitMenus.filter((item: menuTabProps) => item.key !== pathname);
    if (arr.length === exitMenus.length) {
      const activeTab = find(flatMenus, (item) => item.pathname === pathname) || {};
      const activeMenu: menuTabProps = {
        label: activeTab.name,
        key: pathname,
        closable: exitMenus.length > 0, // 新增时,第一个页面不能删除
      };
      arr.push(activeMenu);

      updateMenus(arr);
    } else if (exitMenus.length === 1) {
      // 删除时,只剩一个标签去掉删除图标
      const data = exitMenus;
      data[0].closable = false;
      updateMenus(data);
    }
    setActiveKey(pathname);
  }, [location]);

  const onTabChange = (key: string) => {
    history.push(key);
    setActiveKey(key);
    // console.log(key);
  };
  return (
    <>
      <div className={global.antLayoutAdminTabs}>
        <Tabs
          items={exitMenus}
          onChange={onTabChange}
          type='editable-card'
          hideAdd={true}
          activeKey={activeKey}
          onEdit={(path: string) => {
            // console.log(path, exitMenus, pathname);
            let activePath = pathname;
            const arr: menuTabProps[] = exitMenus.filter((item: menuTabProps, i: number) => {
              if (item.key === path) {
                // 获取前一个标签
                activePath = exitMenus[i - 1].key;
              }
              return item.key !== path;
            });
            // 如果关闭当前标签,展示前一个标签
            if (path === pathname) {
              history.push(activePath);
            }
            // 关闭页签去掉缓存
            dropScope(path);
            updateMenus(arr);
          }}
        />
      </div>
      <KeepAlive when={true} id={pathname} name={pathname} saveScrollPosition="screen" >
        {props.children}
      </KeepAlive>
    </>
  );
};

export default CommonLayout;

7 文件位置:/config/routes.ts   继承模板

{
    path: '/',
    component: './layouts/commonLayout',
    flatMenu: true,
    routes: [
      // {
      //   path: '/welcome',
      //   name: '工作台',
      //   component: '@/pages/modules/welcome',
      // }
    ]
  },

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ant design pro v5 - 07 多标签窗口 多窗口打开 的相关文章

随机推荐

  • 使用百度地图API出错

    在使用百度地图API做地理定位的时候 从拾取坐标系系统获取的坐标 其经纬度是反的 所以直接复制过去的时候 显示不出来地图的全景图 使用时记得交换位置
  • c#用Gnuplot画图源码

    直接调用这个类即可 需要下载个GnuPlot安装下 Author Leonardo Tazzini using System using System Diagnostics using System Drawing using Syste
  • Python爬虫学了几个月却不敢接单?过来人的经验总结收好!

    前几天有刷到一个提问 爬虫学了几个月了却还是不敢上手去接单 爬虫接单靠不靠谱 有些新手心里会犯嘀咕 怕不小心就踩了红线 作为过来人也接过不少单 来浅聊一下我的经验 这篇所说的经验总结可能更适合爬虫新手 爬虫大佬可以忽略 此篇小结 Pytho
  • MHA高可用配置和故障切换

    目录 引言 一 MySQL四种同步方式 1 1 异步复制 Async Replication 1 2 同步复制 Sync Replication 1 3 半同步复制 Semi Sync Replication 1 4 增强半同步复制 los
  • 锂电池保护板电路分析

    锂电池保护板基本模型如下 P 和P 接到负载以及充电电路 T接到充电电路的NTC R1 基准供电电阻 C1 起瞬间稳压和滤波作用 R2 过流 短路检测 R3 NTC电阻 1 当电路正常工作的的时候CO DO都是高电平 U2的两个NMOS导通
  • QT超市管理系统

    QT超市管理系统 前言 QT介绍 pro文件 主文件 main函数 窗口函数 mainwindow 用户登录 user login 超市系统数据库 maketsql 超市商品的增删改查 dlg addmak 收款码界面 picture 结语
  • SpringBoot中Server层以及Mapper层常用注解

    最近看了一下SpringBoot2的课程 发现好多的注解并不是很了解 只是简单的会用 但是真是发生的作用却不知道 最近花了一些时间把这些注解进行了一下整理 针对不同的层级进行了细致的划分 最近几天会依次给大家更新关于注解的内容 对大家有帮助
  • 大带宽、高速率接口对比---USB、PCIE、SATA、HDMI和以太网等接口

    一 PCIE接口 二 USB接口 三 SATA接口 SATA 编码方式 原始频宽 传输速率 有效速率 排线最长长度 SATA1 0 SATA2 0 8bit 10bit 3Gb s 300MB s 275MB s 1M SATA3 0 8b
  • VMware Workstation 15 语言修改

    VMware Workstation 15 语言修改 Win10系统之前因为2345 Flash的原因 把系统的地区改成了中国以外的地区 后来发现不仅Flash的问题没解决 VMware虚拟机的中文界面显示也变成了英文 之后在论坛里看到一个
  • win10如何把繁体字改成简体字

    win10如何把繁体字改成简体字 WBOY 发布 2023 07 09 13 17 05 转载 3431人浏览过 win10客户在开展文字输入的时候遇到了字体变为繁体字的状况 那么如何把繁体字改成简体字呢 是否有快捷键呢 win10繁体字改
  • Elasticsearch 相关度评分算法

    Elasticsearch 相关度评分算法 一 相关度评分算法的组成 1 1 boolean model 1 2 TF IDF 1 3 Vector space model 二 Lucene中的相关度分数算法 三 优化相关度分数计算的方式
  • QT设置控件颜色

    转自 http hi baidu com xiaofan812 item 9a039d62849fa22268105b11 一般的属于QWidget子类的一些控件 可以直接使用样式表 例如 label gt setStyleSheet co
  • 第二章 Vue 核心技术

    2 1 Vue 入门开发 2 1 1 创建工程 在本地创建文件夹D Project vue WebStudy 打开 VS Code 点击 File gt Open Folder 找到 D Project vue WebStudy 打开 单击
  • 使用Lattice包进行基础绘图 - R语言

    使用Lattice包进行基础绘图 R语言 Lattice包是R语言中一个强大且灵活的绘图工具 它可以用于创建各种类型的统计图形 在本文中 我们将介绍如何使用Lattice包进行基础绘图 并提供相应的源代码示例 首先 我们需要安装并加载Lat
  • javascript编写自己的模板解析器

    编写自己的模板解析器 因为最近在研究artTemplate ejs baaiduTemplate等模板 所以 一时兴起 自己也写了个简单的模板解析器 一个最基本的模板解析器 需要有什么功能呢 读取变量值 解析模板语句 按照这个思路 我们编写
  • 简单的感知器实现

    什么是感知器 神经网络的组成单元 神经元 神经元也叫感知器 感知器的组成 输入权值 激活函数 输出 感知器的输出公式 y f w x b 下面构建一个简单的感知器 from functools import reduce 1 functoo
  • leetcode—21.二叉树路径和相关题目leetcode总结

    文章目录 引言 112 路径总和 113 路径总和 II 129 求根节点到叶子节点数字之和 124 二叉树中的最大路径和 257 二叉树的所有路径 引言 树的求和属于树的题目中比较常见的 因为可以有几种变体 灵活度比较高 也可以考察到对于
  • C语言二级题库带答案+解析

    1 程序流程图中带有箭头的线段表示的是 A 图元关系 B 数据流 C 控制流 D 调用关系 参考答案 C 解析 在数据流图中 用标有名字的箭头表示数据流 在程序流程图中 用标有名字的箭头表示控制流 所以选择C 2 结构化程序设计的基本原则不
  • STM32单片机基础15——使用硬件I2C读取温湿度传感器数据(SHT30)

    本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设 读取SHT30温湿度传感器的数据并通过串口发送 1 准备工作 硬件准备 开发板 首先需要准备一个开发板 这里我准备的是STM32L4的开发板 Be
  • ant design pro v5 - 07 多标签窗口 多窗口打开

    1 安装组件 安装 yarn add umi plugin keep alive 2 创建模板 src services types menu ts export interface menuTabProps tab string path