From bdf6243bd9d09174f37b883e4094e8e7f97ada37 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Mon, 7 Apr 2025 19:17:10 +0800 Subject: [PATCH] bump --- package.json | 2 +- src/router/index.tsx | 107 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/router/index.tsx diff --git a/package.json b/package.json index 7f550bd..1b56e08 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "clsx": "^2.1.1", - "tailwind-merge": "^3.1.0" + "tailwind-merge": "^3.2.0" }, "publishConfig": { "access": "public" diff --git a/src/router/index.tsx b/src/router/index.tsx new file mode 100644 index 0000000..295b465 --- /dev/null +++ b/src/router/index.tsx @@ -0,0 +1,107 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; + +// 路由上下文 +type RouterContextType = { + pathname: string; + navigate: (to: string) => void; +}; + +export const RouterContext = createContext(null); + +// 使用路由上下文的Hook +export const useRouter = () => { + const context = useContext(RouterContext); + if (!context) { + throw new Error('useRouter必须在RouterProvider内部使用'); + } + return context; +}; + +// 路由项定义 +export type RouterItem = { + path: string; + element: React.ReactNode; +}; + +// Router组件 - 路由系统的根组件 +type RouterProps = { + routes?: RouterItem[]; + children?: React.ReactNode; +}; +export const Route = ({ path, element }: RouteProps) => { + return <>{element}; +}; +export const Router = ({ routes, children }: RouterProps) => { + const [pathname, setPathname] = useState(window.location.pathname); + + // 导航方法 + const navigate = (to: string) => { + window.history.pushState(null, '', to); + setPathname(to); + }; + + // 监听浏览器前进后退 + useEffect(() => { + const handlePopState = () => { + setPathname(window.location.pathname); + }; + + window.addEventListener('popstate', handlePopState); + return () => window.removeEventListener('popstate', handlePopState); + }, []); + + return ( + + + {routes?.map((route, index) => ( + + ))} + {children} + + + ); +}; + +// Route组件 - 定义单个路由 +type RouteProps = { + path: string; + element: React.ReactNode; +}; + +// Routes组件 - 渲染匹配的路由 +type RoutesProps = { + children: React.ReactNode | React.ReactNode[]; +}; + +export const Routes = ({ children }: RoutesProps) => { + const { pathname } = useRouter(); + + // 将children转换为数组处理 + const childrenArray = React.Children.toArray(children); + + // 查找匹配的路由 + const matchedRoute = childrenArray.find((child) => { + if (React.isValidElement(child) && typeof child.type === 'function') { + const routeProps = child.props as RouteProps; + + // 简单路径匹配,可以扩展为支持参数等更复杂功能 + if (routeProps.path === pathname || (routeProps.path === '/' && pathname === '')) { + return true; + } + + // 支持通配符路由 + if (routeProps.path.endsWith('*') && pathname.startsWith(routeProps.path.slice(0, -1))) { + return true; + } + } + return false; + }); + + // 返回匹配的路由元素或空 + if (matchedRoute && React.isValidElement(matchedRoute)) { + // @ts-ignore + return <>{matchedRoute.props?.element}; + } + + return null; +};