我已经在Next JS和frame -motion中创建了一个导航组件来突出显示当前页面。
问题是,当我在子路由上时,例如'localhost:3000/blog/post', home选项卡仍然会突出显示。
如何只显示当前突出显示的页面及其子路由,例如,如果你在:
- localhost: 3000/博客
- localhost: 3000/博客/后
只有blog选项卡会被突出显示
import { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import LogoText from './Logo';
import routes from '../routes/config';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { useAuth } from './AuthContextProvider';
import Container from './Container';
const data = [
{
url: routes.home,
name: 'Home',
},
{
url: routes.dashboard,
name: 'Dashboard',
},
{
url: routes.cart,
name: 'Cart',
},
{
url: routes.blog,
name: 'Blog',
},
];
const Navbar = () => {
const [cartCount, setCartCount] = useState(0);
const router = useRouter();
const { pathname } = router;
const { logout, user } = useAuth();
useEffect(() => {
console.log(pathname, 'test path');
console.log(router, 'test router');
});
return (
<nav className="">
<div className="md:py-4">
<Container>
<div className="flex items-center justify-between py-4">
<div className="flex-shrink-0">
<Link href={routes.home}>
<a>
<LogoText />
</a>
</Link>
</div>
<div className="font-bold md:block overflow-x-scroll md:overflow-x-visible">
<div className="flex items-baseline space-x-4">
{data.map((item, index) => {
const isSelected = pathname.startsWith(item.url);
return (
<Link key={index} href={item.url}>
<a
className={`${
isSelected
? 'text-green-500'
: 'text-gray-300 hover:text-green-500'
} p-4 whitespace-nowrap relative`}
>
{isSelected && (
<motion.span
layoutId="underline"
className="absolute left-0 top-full block h-[3px] w-full bg-green-500"
/>
)}
<span className="ml-1">{item.name}</span>
</a>
</Link>
);
})}
{user?.uid && (
<button onClick={() => logout()}>Logout</button>
)}
</div>
</div>
</div>
</Container>
</div>
</nav>
);
};
export default Navbar;
更新1
我尝试了Robert的建议:
{data.map((item, index) => {
const isSelected = path === routes.home || (path !== routes.home && path.startsWith(item.url))
return (
<Link
key={index}
href={item.url}
className="text-gray-300 hover:text-green-500 p-4 whitespace-nowrap relative"
>
{isSelected && (<motion.span layoutId="underline" className='absolute left-0 top-full block h-[3px] w-full bg-green-500' />)}
<span className="ml-1">{item.name}</span>
</Link>
)
})}
作用于url '/blog',但不作用于'blog/subpost '。对于后一种类型的路由,home选项卡也会突出显示。
该函数从next.js useRouter钩子中确定路由的基路径
它根据url中存在的斜杠进行分割,并接受第一个条目,即基本路径。这假设你的导航栏有一个基本路径,而不是一个空的索引路径。
function getBaseRoute(route) {
const paths = route.split('/').filter(Boolean);
return `/${paths[0]}`;
}
然后我们使用函数并从路由器
传递pathname
来获得基本路由const baseRoute = getBaseRoute(router.pathname);
然后可以使用baseRoute
字符串将其与要突出显示的基本路径进行比较
<li className={baseRoute === '/home' ? 'active' : ''}>
当您查看/home
以及/home/update
的任何子页面时,这将起作用
这是一个非常重要的特性,上面的功能将解决您的navbar
组件中的问题。我不确定路由/
上索引页的行为