66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
|
import { useState, useEffect } from "react";
|
||
|
import Search20Regular from "@ricons/fluent/Search20Regular";
|
||
|
import { useLocation, useNavigate } from "react-router";
|
||
|
import { ICustomPage } from "../types";
|
||
|
interface IProps {
|
||
|
customPages: ICustomPage[];
|
||
|
}
|
||
|
|
||
|
interface INavItem extends ICustomPage {
|
||
|
active: boolean;
|
||
|
key: string;
|
||
|
}
|
||
|
|
||
|
export default function Nav(props: IProps) {
|
||
|
const navigate = useNavigate();
|
||
|
const location = useLocation();
|
||
|
const [navList, setNavList] = useState<INavItem[]>([]);
|
||
|
|
||
|
useEffect(() => {
|
||
|
const navList = props.customPages.map((i: ICustomPage) => ({
|
||
|
...i,
|
||
|
key: i.path,
|
||
|
active: false,
|
||
|
}));
|
||
|
setNavList(navList);
|
||
|
}, [props.customPages]);
|
||
|
|
||
|
/**
|
||
|
* 路由变化同步页面文字 active 状态
|
||
|
*/
|
||
|
useEffect(() => {
|
||
|
const path = location.pathname;
|
||
|
setNavList((p) => p.map((i) => ({ ...i, active: path === i.path })));
|
||
|
}, [location.pathname]);
|
||
|
|
||
|
/**
|
||
|
* 点击切换页面
|
||
|
*/
|
||
|
const onClickNavItem = (key: string) => {
|
||
|
const nav = navList.find((i: INavItem) => i.key === key);
|
||
|
setNavList((p: INavItem[]) =>
|
||
|
p.map((i: INavItem) => ({ ...i, active: key === i.key }))
|
||
|
);
|
||
|
navigate(nav!.path);
|
||
|
};
|
||
|
|
||
|
return (
|
||
|
<nav>
|
||
|
<div className="start"></div>
|
||
|
<div className="end">
|
||
|
<div className="search-container">
|
||
|
<Search20Regular />
|
||
|
<input type="text" placeholder="搜索 / 待开发" />
|
||
|
</div>
|
||
|
<ul>
|
||
|
{navList.map((item) => (
|
||
|
<li key={item.key} onClick={() => onClickNavItem(item.key)}>
|
||
|
<span className={item.active ? "active" : ""}>{item.title}</span>
|
||
|
</li>
|
||
|
))}
|
||
|
</ul>
|
||
|
</div>
|
||
|
</nav>
|
||
|
);
|
||
|
}
|