mirror of
https://github.com/LiuYuYang01/ThriveX-Blog.git
synced 2026-07-01 07:14:21 +08:00
feat(header, sidebar):增强导航链接并添加页面类型支持
- 更新了 Header 和 SidebarNav 组件中的导航链接处理,以使用 href、target 和 rel 属性的实用函数。 - 在导航渲染中添加了对“页面”类型的支持,从而可以更好地组织和显示页面链接。 - 修改了 Cate 类型定义,将“页面”包含为有效类型。 - 从 cateNav 导出新的实用函数以改进链接管理。
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import Show from '@/components/Show';
|
||||
import { Cate } from '@/types/app/cate';
|
||||
import { getCateNavHref, getCateNavRel, getCateNavTarget } from '@/utils/cateNav';
|
||||
import Link from 'next/link';
|
||||
import { IoIosArrowDown } from 'react-icons/io';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
@@ -22,7 +23,7 @@ export default ({ list, open, onClose }: Props) => {
|
||||
<div key={one.id}>
|
||||
{one.type === 'cate' && (
|
||||
<li className="group/one relative hover:bg-[#e0e6ec] dark:hover:bg-[#495362] rounded-md ">
|
||||
<Link href={`/cate/${one.id}?name=${one.name}`} className={`flex justify-between items-center p-3 px-5 text-[15px] group-hover/one:!text-primary text-[#333] dark:text-white whitespace-nowrap`} onClick={onClose}>
|
||||
<Link href={getCateNavHref(one)} target={getCateNavTarget(one.type)} rel={getCateNavRel(one.type)} className={`flex justify-between items-center p-3 px-5 text-[15px] group-hover/one:!text-primary text-[#333] dark:text-white whitespace-nowrap`} onClick={onClose}>
|
||||
{one.icon} {one.name}
|
||||
<Show is={!!one.children.length}>
|
||||
<IoIosArrowDown className="ml-2" />
|
||||
@@ -33,7 +34,7 @@ export default ({ list, open, onClose }: Props) => {
|
||||
<ul className="overflow-hidden top-[50px] w-full rounded-md">
|
||||
{one.children?.map((two) => (
|
||||
<li key={two.id} className="group/two">
|
||||
<Link href={`/cate/${two.id}?name=${two.name}`} className="inline-block w-full p-2.5 pl-10 text-[15px] box-border text-[#666] dark:text-[#8c9ab1] hover:!text-primary" onClick={onClose}>
|
||||
<Link href={getCateNavHref(two)} target={getCateNavTarget(two.type)} rel={getCateNavRel(two.type)} className="inline-block w-full p-2.5 pl-10 text-[15px] box-border text-[#666] dark:text-[#8c9ab1] hover:!text-primary" onClick={onClose}>
|
||||
{two.name}
|
||||
</Link>
|
||||
</li>
|
||||
@@ -43,9 +44,32 @@ export default ({ list, open, onClose }: Props) => {
|
||||
</li>
|
||||
)}
|
||||
|
||||
{one.type === 'page' && (
|
||||
<li className="group/one relative hover:bg-[#e0e6ec] dark:hover:bg-[#495362] rounded-md ">
|
||||
<Link href={getCateNavHref(one)} target={getCateNavTarget(one.type)} rel={getCateNavRel(one.type)} className={`flex justify-between items-center p-3 px-5 text-[15px] group-hover/one:!text-primary text-[#333] dark:text-white whitespace-nowrap`} onClick={onClose}>
|
||||
{one.icon} {one.name}
|
||||
<Show is={!!one.children.length}>
|
||||
<IoIosArrowDown className="ml-2" />
|
||||
</Show>
|
||||
</Link>
|
||||
|
||||
<Show is={!!one.children.length}>
|
||||
<ul className="overflow-hidden top-[50px] w-full rounded-md">
|
||||
{one.children?.map((two) => (
|
||||
<li key={two.id} className="group/two">
|
||||
<Link href={getCateNavHref(two)} target={getCateNavTarget(two.type)} rel={getCateNavRel(two.type)} className="inline-block w-full p-2.5 pl-10 text-[15px] box-border text-[#666] dark:text-[#8c9ab1] hover:!text-primary" onClick={onClose}>
|
||||
{two.icon} {two.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Show>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{one.type === 'nav' && (
|
||||
<li className="group/one relative hover:bg-[#e0e6ec] dark:hover:bg-[#495362] rounded-md ">
|
||||
<Link href={one.url} target={`${one.url.startsWith('http') ? '_blank' : '_self'}`} className={`flex justify-between items-center p-3 px-5 text-[15px] group-hover/one:!text-primary text-[#333] dark:text-white whitespace-nowrap`} onClick={onClose}>
|
||||
<Link href={getCateNavHref(one)} target={getCateNavTarget(one.type)} rel={getCateNavRel(one.type)} className={`flex justify-between items-center p-3 px-5 text-[15px] group-hover/one:!text-primary text-[#333] dark:text-white whitespace-nowrap`} onClick={onClose}>
|
||||
{one.icon} {one.name}
|
||||
<Show is={!!one.children.length}>
|
||||
<IoIosArrowDown className="ml-2" />
|
||||
@@ -56,7 +80,7 @@ export default ({ list, open, onClose }: Props) => {
|
||||
<ul className="overflow-hidden top-[50px] w-full rounded-md">
|
||||
{one.children?.map((two) => (
|
||||
<li key={two.id} className="group/two">
|
||||
<Link href={two.url} target={`${two.url.startsWith('http') ? '_blank' : '_self'}`} className="inline-block w-full p-2.5 pl-10 text-[15px] box-border text-[#666] dark:text-[#8c9ab1] hover:!text-primary" onClick={onClose}>
|
||||
<Link href={getCateNavHref(two)} target={getCateNavTarget(two.type)} rel={getCateNavRel(two.type)} className="inline-block w-full p-2.5 pl-10 text-[15px] box-border text-[#666] dark:text-[#8c9ab1] hover:!text-primary" onClick={onClose}>
|
||||
{two.icon} {two.name}
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { BsFillMoonStarsFill, BsTextIndentLeft } from 'react-icons/bs';
|
||||
|
||||
import { Cate } from '@/types/app/cate';
|
||||
import { getCateListAPI } from '@/api/cate';
|
||||
import { getCateNavHref, getCateNavRel, getCateNavTarget } from '@/utils/cateNav';
|
||||
|
||||
import { useConfigStore } from '@/stores';
|
||||
|
||||
@@ -107,7 +108,7 @@ export default () => {
|
||||
{/* 渲染分类 */}
|
||||
{one.type === 'cate' && (
|
||||
<li className="group/one relative">
|
||||
<Link href={`/cate/${one.id}?name=${one.name}`} target={`${one.url.startsWith('http') ? '_blank' : '_self'}`} className={`flex items-center p-5 text-[15px] whitespace-nowrap group-hover/one:!text-primary ${isPathSty || isScrolled ? 'text-[#333] dark:text-white' : 'text-white'}`}>
|
||||
<Link href={getCateNavHref(one)} target={getCateNavTarget(one.type)} rel={getCateNavRel(one.type)} className={`flex items-center p-5 text-[15px] whitespace-nowrap group-hover/one:!text-primary ${isPathSty || isScrolled ? 'text-[#333] dark:text-white' : 'text-white'}`}>
|
||||
{one.icon} {one.name}
|
||||
<Show is={!!one.children.length}>
|
||||
<IoIosArrowDown className="ml-2" />
|
||||
@@ -122,7 +123,7 @@ export default () => {
|
||||
className="opacity-0 -translate-x-2 group-hover/one:opacity-100 group-hover/one:translate-x-0 transition-all duration-300 ease-out"
|
||||
style={{ transitionDelay: `${index * 45 + 60}ms` }}
|
||||
>
|
||||
<Link href={`/cate/${two.id}?name=${two.name}`} target={`${two.url.startsWith('http') ? '_blank' : '_self'}`} title={two.name} className={`${submenuItemClass} truncate`}>
|
||||
<Link href={getCateNavHref(two)} target={getCateNavTarget(two.type)} rel={getCateNavRel(two.type)} title={two.name} className={`${submenuItemClass} truncate`}>
|
||||
{two.name}
|
||||
</Link>
|
||||
</li>
|
||||
@@ -132,10 +133,39 @@ export default () => {
|
||||
</li>
|
||||
)}
|
||||
|
||||
{/* 渲染页面 */}
|
||||
{one.type === 'page' && (
|
||||
<li className="group/one relative">
|
||||
<Link href={getCateNavHref(one)} target={getCateNavTarget(one.type)} rel={getCateNavRel(one.type)} className={`flex items-center p-5 px-10 text-[15px] whitespace-nowrap group-hover/one:!text-primary ${isPathSty || isScrolled ? 'text-[#333] dark:text-white' : 'text-white'}`}>
|
||||
{one.icon} {one.name}
|
||||
<Show is={!!one.children?.length}>
|
||||
<IoIosArrowDown className="ml-2" />
|
||||
</Show>
|
||||
</Link>
|
||||
|
||||
<Show is={!!one.children?.length}>
|
||||
<ul className={`${submenuPanelClass} bg-[rgba(255,255,255,0.95)] dark:bg-[rgba(44,51,62,0.95)]`} style={{ boxShadow: '0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08)' }}>
|
||||
{one.children?.map((two, index) => (
|
||||
<li
|
||||
key={two.id}
|
||||
className="opacity-0 -translate-x-2 group-hover/one:opacity-100 group-hover/one:translate-x-0 transition-all duration-300 ease-out"
|
||||
style={{ transitionDelay: `${index * 45 + 60}ms` }}
|
||||
>
|
||||
<Link href={getCateNavHref(two)} target={getCateNavTarget(two.type)} rel={getCateNavRel(two.type)} title={two.name} className={`${submenuItemClass} gap-1.5`}>
|
||||
<span className="shrink-0 transition-transform duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] group-hover/item:scale-125 group-hover/item:-rotate-6">{two.icon}</span>
|
||||
<span className="truncate">{two.name}</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Show>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{/* 渲染导航 */}
|
||||
{one.type === 'nav' && (
|
||||
<li className="group/one relative">
|
||||
<Link href={one.url} className={`flex items-center p-5 px-10 text-[15px] whitespace-nowrap group-hover/one:!text-primary ${isPathSty || isScrolled ? 'text-[#333] dark:text-white' : 'text-white'}`}>
|
||||
<Link href={getCateNavHref(one)} target={getCateNavTarget(one.type)} rel={getCateNavRel(one.type)} className={`flex items-center p-5 px-10 text-[15px] whitespace-nowrap group-hover/one:!text-primary ${isPathSty || isScrolled ? 'text-[#333] dark:text-white' : 'text-white'}`}>
|
||||
{one.icon} {one.name}
|
||||
{/* 如果有子分类就显示下拉三角 */}
|
||||
<Show is={!!one.children?.length}>
|
||||
@@ -151,7 +181,7 @@ export default () => {
|
||||
className="opacity-0 -translate-x-2 group-hover/one:opacity-100 group-hover/one:translate-x-0 transition-all duration-300 ease-out"
|
||||
style={{ transitionDelay: `${index * 45 + 60}ms` }}
|
||||
>
|
||||
<Link href={two.url} title={two.name} className={`${submenuItemClass} gap-1.5`}>
|
||||
<Link href={getCateNavHref(two)} target={getCateNavTarget(two.type)} rel={getCateNavRel(two.type)} title={two.name} className={`${submenuItemClass} gap-1.5`}>
|
||||
<span className="shrink-0 transition-transform duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] group-hover/item:scale-125 group-hover/item:-rotate-6">{two.icon}</span>
|
||||
<span className="truncate">{two.name}</span>
|
||||
</Link>
|
||||
|
||||
2
src/types/app/cate.d.ts
vendored
2
src/types/app/cate.d.ts
vendored
@@ -5,7 +5,7 @@ export interface Cate {
|
||||
url: string,
|
||||
icon: string,
|
||||
level: number,
|
||||
type: 'cate' | 'nav',
|
||||
type: 'cate' | 'page' | 'nav',
|
||||
count: number,
|
||||
is_hide: boolean,
|
||||
order: number,
|
||||
|
||||
16
src/utils/cateNav.ts
Normal file
16
src/utils/cateNav.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Cate } from '@/types/app/cate';
|
||||
|
||||
export function getCateNavHref(item: Cate): string {
|
||||
if (item.type === 'cate') {
|
||||
return `/cate/${item.id}?name=${item.name}`;
|
||||
}
|
||||
return item.url || '/';
|
||||
}
|
||||
|
||||
export function getCateNavTarget(type: Cate['type']): '_self' | '_blank' {
|
||||
return type === 'nav' ? '_blank' : '_self';
|
||||
}
|
||||
|
||||
export function getCateNavRel(type: Cate['type']): 'noopener noreferrer' | undefined {
|
||||
return type === 'nav' ? 'noopener noreferrer' : undefined;
|
||||
}
|
||||
@@ -3,4 +3,5 @@ export * from './await-io';
|
||||
export * from './htmlParser';
|
||||
export * from './common';
|
||||
export * from './url';
|
||||
export * from './request';
|
||||
export * from './request';
|
||||
export * from './cateNav';
|
||||
Reference in New Issue
Block a user