typescript 导航高亮显示主页,当我在子路由上时,例如在next.js中的blog/post

k10s72fa  于 2023-03-31  发布在  TypeScript
关注(0)|答案(1)|浏览(94)

我在Next JS和framer-motion中创建了一个导航组件来突出显示当前页面。
问题是,当我在一个子路由上时,例如'localhost:3000/blog/post',home标签仍然会突出显示。
如何只显示当前突出显示的页面及其子路由,例如,如果您在:

  • 本地主机:3000/博客
  • localhost:3000/blog/post

只有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;
u4dcyp6a

u4dcyp6a1#

也许您可以通过将您的/blog/post路由添加到相同的名称下但使用不同的url来简化此过程:

const data = [
  {
    url: "/",
    name: 'Home',
  },
  {
    url: "/dashboard",
    name: 'Dashboard',
  },
  {
    url: "/cart",
    name: 'Cart',
  },
  {
    url: "/blog",
    name: 'Blog',
  },
  {
    url: "/blog/post",
    name: 'Blog',
  },
];

然后将isSelected逻辑更改为:

...
               {data.map((item, index) => {
                  const isSelected = pathname === item.url;
                  return (
...

相关问题