import { Link, useMatches } from '@remix-run/react'; interface BreadcrumbItem { title: string; to?: string; } interface BreadcrumbProps { items?: BreadcrumbItem[]; className?: string; } interface PreviousRouteData { title: string; to: string; } interface Handle { breadcrumb: string | ((data: unknown) => string); to?: string; // 自定义面包屑链接 previousRoute?: PreviousRouteData | ((data: unknown) => PreviousRouteData | undefined); breadcrumbClassName?: string; } interface Match { handle?: Handle; pathname: string; data: unknown; } export function Breadcrumb({ items = [], className = '' }: BreadcrumbProps) { const matches = useMatches() as Match[]; // 构建面包屑数据 const breadcrumbs = items.length > 0 ? items : matches .filter(match => match.handle?.breadcrumb) .map((match, index, array) => { // 当前路由的面包屑 const current = { title: typeof match.handle?.breadcrumb === 'function' ? match.handle.breadcrumb(match.data) : match.handle?.breadcrumb as string, to: match.handle?.to || match.pathname // 优先使用 handle.to,否则使用 pathname }; // 如果当前路由有previousRoute属性且该路由是数组中的最后一个 if (match.handle?.previousRoute && index === array.length - 1) { // 获取previousRoute数据,支持函数形式 const prevRouteData = typeof match.handle.previousRoute === 'function' ? match.handle.previousRoute(match.data) : match.handle.previousRoute; // 如果previousRoute存在,添加到面包屑中 if (prevRouteData) { return [ { title: prevRouteData.title, to: prevRouteData.to }, current ]; } } return [current]; }) .flat(); // 扁平化数组 // 获取自定义类名 const getCustomClassName = () => { const lastMatch = matches[matches.length - 1]; return lastMatch?.handle?.breadcrumbClassName || ''; }; if (breadcrumbs.length === 0) { return null; } // 应用自定义类名 const customClassName = getCustomClassName(); const finalClassName = `mb-4 ${className} ${customClassName}`.trim(); return ( ); }