您现在的位置是:首页 >技术杂谈 >react关于手搓antd pro面包屑的经验(写的不好请见谅)网站首页技术杂谈

react关于手搓antd pro面包屑的经验(写的不好请见谅)

恰小面包 2025-02-19 00:01:03
简介react关于手搓antd pro面包屑的经验(写的不好请见谅)

我们先上代码,代码里面都有注释,我是单独写了一个组件,方便使用,在其他页面引入就行了

还使用了官方的Breadcrumb组件

import React, { useEffect, useState } from 'react';
import { Breadcrumb, Button } from 'antd';
import { useLocation, NavLink, useNavigate } from 'react-router-dom';

// 定义面包屑项的类型
interface LocaItem {
  path: string;
  title: string;
}

interface CustomBreadcrumbProps {
  title: string; // 当前页面的标题,动态传递
}

const CustomBreadcrumb: React.FC<CustomBreadcrumbProps> = ({ title }) => {
  const navigate = useNavigate();
  const location = useLocation();
  const [loca, setLoca] = useState<LocaItem[]>([]);

  useEffect(() => {
    // 获取存储的面包屑数据
    const storedLoca = JSON.parse(sessionStorage.getItem('loca') || '[]');

    // 创建新面包屑项
    const newObject: LocaItem = {
      path: location.pathname,
      title: title, // 使用传入的 title 作为当前页面的标题
    };

    // 判断 loca 中是否有相同的 title
    const isExist = storedLoca.some((item: LocaItem) => item.title === newObject.title);

    // 如果不存在相同的 title,就 push 新对象
    if (!isExist) {
      storedLoca.push(newObject);
      sessionStorage.setItem('loca', JSON.stringify(storedLoca)); // 存储新的面包屑数据
    }

    setLoca(storedLoca); // 更新组件状态
  }, [location.pathname, title]); // 每次路径或标题变化时,更新面包屑

  // 删除面包屑项
  const handleRemove = (path: string) => {
    console.log(location.pathname);
    console.log(path);
    // 检查路径是否相同
    if (location.pathname === path) {
      const pathlink = JSON.parse(sessionStorage.getItem('loca') || '[]');
      const pathlinkLength = pathlink.length - 1;

      if (path === pathlink[pathlinkLength].path) {
        const newPath = String(pathlink[pathlinkLength - 1]?.path);

        // 延迟跳转,确保状态更新后执行
        setTimeout(() => {
          navigate(newPath || '/'); // 如果路径为空,跳转到默认页面
        }, 0);
      } else {
        const newPath = String(pathlink[pathlinkLength - 2]?.path);

        // 延迟跳转,确保状态更新后执行
        setTimeout(() => {
          navigate(newPath || '/'); // 如果路径为空,跳转到默认页面
        }, 0);
      }
    }

    // 更新面包屑数据
    const updatedLoca = loca.filter((item) => item.path !== path);
    sessionStorage.setItem('loca', JSON.stringify(updatedLoca)); // 更新 sessionStorage
    setLoca(updatedLoca); // 更新状态
  };

  // 渲染面包屑项
  const breadcrumbItems = loca.map((item: LocaItem) => ({
    title: (
      <span style={
  
  { display: 'flex', alignItems: 'center', marginLeft: '10px' }}>
        <NavLink
          to={item.path}
          style={({ isActive }) => ({
            fontWeight: isActive ? 'bold' : 'normal', // 高亮显示
            color: isActive ? '#1890FF' : 'normal', // 当前项文字颜色
            backgroundColor: isActive ? '#e6f7ff' : 'normal', // 当前项背景颜色
            borderBottom: isActive ? '1px solid #1890FF' : 'normal',
            borderRadius: '0',
            height: '30px',
            lineHeight: '30px',
            padding: '0 10px 0 10px',
          })}
        >
          {item.title}
        </NavLink>
        {/* 关闭按钮 */}
        <Button
          onClick={() => handleRemove(item.path)} // 点击删除当前面包屑项
          disabled={item.title === "首页"} // 禁用“首页”按钮
          type="link"
          icon={<span style={
  
  { fontSize: '16px' }}>×</span>}
          style={
  
  {
            padding: 0,
            fontSize: '16px',
            display: item.title === "首页" ? 'none' : 'block',
            width: '20px',
            margin: item.title === "首页" ? '0 5px 0 0' : '0',
          }}
        />
      </span>
    ),
  }));

  return (
    <Breadcrumb
      style={
  
  {
        margin: '16px 0',
        height: '30px',
      }}
      items={breadcrumbItems} // 使用动态生成的面包屑项
      separator="" // 去掉默认的斜杠分隔符
      itemRender={(route) => {
        return (
          <span style={
  
  { marginRight: '10px',whiteSpace:'nowrap' }}>{route.title}</span> // 给每个面包屑项加间距
        );
      }}
    />
  );
};

export default CustomBreadcrumb;

然后在其他页面引入

import Breadcrumbs from '../../../src/components/Breadcrumb/Breadcrumb';

使用:

title是面包屑的名称,你也可以获取当前路由的title,写个动态的

<Breadcrumbs title="需求管理" />

效果:

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。