60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { useLocation, useNavigate } from "react-router";
|
|
import { IRoute } from "../types";
|
|
|
|
interface IProps {
|
|
menus: IRoute[];
|
|
subTitle: string;
|
|
version: string;
|
|
}
|
|
|
|
export default function Aside(props: IProps) {
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
const version = props.version;
|
|
const [menuList, setMenuList] = useState<IRoute[]>([]);
|
|
|
|
useEffect(() => {
|
|
if (props.menus?.length > 0) setMenuList(props.menus);
|
|
}, [props.menus]);
|
|
|
|
useEffect(() => {
|
|
const path = location.pathname.replace(/\//, "");
|
|
const isCompoPath = menuList.map((i) => i.path).includes(path);
|
|
if (!isCompoPath)
|
|
setMenuList((p) => p.map((i) => ({ ...i, active: false })));
|
|
}, [location.pathname]);
|
|
|
|
const toggle = (route: IRoute) => {
|
|
setMenuList((prev) => {
|
|
return prev.map((r: IRoute) => {
|
|
r.active = r.path === route.path;
|
|
return r;
|
|
});
|
|
});
|
|
navigate(route.path);
|
|
};
|
|
|
|
return (
|
|
<aside>
|
|
<div className="logo">
|
|
<img src="logo.png" />
|
|
<span data-version={version}>{props.subTitle}</span>
|
|
</div>
|
|
<h4>组件({menuList.length})</h4>
|
|
<ul className="nav-list">
|
|
{menuList.map((route: IRoute) => (
|
|
<li key={route.path}>
|
|
<a
|
|
className={route.active ? "active" : ""}
|
|
onClick={() => toggle(route)}
|
|
>
|
|
{route.name}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</aside>
|
|
);
|
|
}
|