From e6464740f896bca9e5a3b27f539ee7108db4b55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=87=E9=98=B3?= Date: Thu, 2 Jul 2026 14:14:32 +0800 Subject: [PATCH] =?UTF-8?q?refactor(ArticleLayout)=EF=BC=9A=E7=94=A8=20Art?= =?UTF-8?q?icleMeta=20=E7=BB=84=E4=BB=B6=E6=9B=BF=E6=8D=A2=E5=86=85?= =?UTF-8?q?=E8=81=94=E6=96=87=E7=AB=A0=E5=85=83=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新了 Card 和 Classics 组件,以利用新的 ArticleMeta 组件显示文章元数据,提高代码可读性和可维护性。 - 删除了冗余的内联元数据渲染逻辑,简化了组件结构。 --- src/components/ArticleLayout/Card/index.tsx | 29 +-------- .../ArticleLayout/Classics/index.tsx | 32 ++-------- .../components/ArticleMeta/index.tsx | 60 +++++++++++++++++++ src/components/Header/index.tsx | 38 ++++-------- 4 files changed, 80 insertions(+), 79 deletions(-) create mode 100644 src/components/ArticleLayout/components/ArticleMeta/index.tsx diff --git a/src/components/ArticleLayout/Card/index.tsx b/src/components/ArticleLayout/Card/index.tsx index 77b65a2..bc8983e 100755 --- a/src/components/ArticleLayout/Card/index.tsx +++ b/src/components/ArticleLayout/Card/index.tsx @@ -2,11 +2,7 @@ import Link from 'next/link'; import { getRandomImage } from '@/utils'; import { getThemeCovers } from '@/lib/theme'; import { Article } from '@/types/app/article'; -import dayjs from 'dayjs'; - -import { RiFireLine } from 'react-icons/ri'; -import { IoTimeOutline } from 'react-icons/io5'; -import { GoTag } from 'react-icons/go'; +import ArticleMeta from '@/components/ArticleLayout/components/ArticleMeta'; import Empty from '@/components/Empty'; import Show from '@/components/Show'; @@ -36,28 +32,7 @@ const Card = async ({ data }: CardProps) => {

{item.title}

{genArticleInfo(item)}

-
-
- - - - {dayjs(+item.createTime!).format('YYYY-MM-DD')} -
- -
- - - - {item.view} -
- -
- - - - {item.cateList[0]?.name} -
-
+ diff --git a/src/components/ArticleLayout/Classics/index.tsx b/src/components/ArticleLayout/Classics/index.tsx index b015781..9eada39 100755 --- a/src/components/ArticleLayout/Classics/index.tsx +++ b/src/components/ArticleLayout/Classics/index.tsx @@ -2,11 +2,7 @@ import Link from 'next/link'; import { getRandomImage } from '@/utils'; import { getThemeCovers } from '@/lib/theme'; import { Article } from '@/types/app/article'; -import dayjs from 'dayjs'; - -import { RiFireLine } from 'react-icons/ri'; -import { IoTimeOutline } from 'react-icons/io5'; -import { GoTag } from 'react-icons/go'; +import ArticleMeta from '@/components/ArticleLayout/components/ArticleMeta'; import Empty from '@/components/Empty'; import Show from '@/components/Show'; @@ -49,28 +45,10 @@ const Classics = async ({ data }: ClassicsProps) => {

{item.title}

{genArticleInfo(item)}

-
-
- - - - {dayjs(+item.createTime!).format('YYYY-MM-DD')} -
- -
- - - - {item.view} -
- -
- - - - {item.cateList[0]?.name} -
-
+ diff --git a/src/components/ArticleLayout/components/ArticleMeta/index.tsx b/src/components/ArticleLayout/components/ArticleMeta/index.tsx new file mode 100644 index 0000000..21a0913 --- /dev/null +++ b/src/components/ArticleLayout/components/ArticleMeta/index.tsx @@ -0,0 +1,60 @@ +import { Fragment } from 'react'; +import dayjs from 'dayjs'; +import { FiCalendar, FiEye } from 'react-icons/fi'; +import { IconType } from 'react-icons'; +import { Article } from '@/types/app/article'; +import { cn } from '@/lib/utils'; + +interface ArticleMetaProps { + article: Pick; + className?: string; +} + +interface MetaItem { + key: string; + icon?: IconType; + label: string; +} + +function buildMetaItems(article: ArticleMetaProps['article']): MetaItem[] { + const items: MetaItem[] = [ + { + key: 'date', + icon: FiCalendar, + label: dayjs(+article.createTime!).format('YYYY-MM-DD'), + }, + { + key: 'view', + icon: FiEye, + label: `${article.view} 阅读`, + }, + ]; + + const category = article.cateList[0]?.name; + if (category) { + items.push({ key: 'category', label: category }); + } + + return items; +} + +export default function ArticleMeta({ article, className }: ArticleMetaProps) { + const items = buildMetaItems(article); + + return ( +
+ {/*
*/} +
+ {items.map(({ key, icon: Icon, label }, index) => ( + + {index > 0 && } + + {Icon && } + {label} + + + ))} +
+
+ ); +} diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 4bb286c..fb22728 100755 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -19,10 +19,10 @@ import { getCateNavHref, getCateNavRel, getCateNavTarget } from '@/utils/cateNav import { useConfigStore } from '@/stores'; const submenuPanelClass = - 'invisible opacity-0 -translate-y-2 pointer-events-none group-hover/one:visible group-hover/one:opacity-100 group-hover/one:translate-y-0 group-hover/one:pointer-events-auto transition-all duration-300 ease-out absolute left-0 top-full z-10 pt-1 min-w-full w-max max-w-[220px] overflow-hidden rounded-md'; + 'invisible opacity-0 scale-[0.98] pointer-events-none group-hover/one:visible group-hover/one:opacity-100 group-hover/one:scale-100 group-hover/one:pointer-events-auto transition-[opacity,transform,visibility] duration-200 ease-out absolute left-0 top-full z-10 pt-2 min-w-full w-max max-w-[220px] overflow-hidden rounded-md before:absolute before:inset-x-0 before:-top-2 before:h-2 before:content-[""]'; const submenuItemClass = - 'group/item relative flex w-full items-center min-w-0 px-5 py-2.5 text-[15px] text-[#666] dark:text-white transition-all duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] hover:translate-x-1.5 hover:!text-primary hover:bg-[#f2f2f2] dark:hover:bg-[#323e50] before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:h-0 before:w-[3px] before:rounded-r-full before:bg-primary before:transition-all before:duration-300 hover:before:h-[50%]'; + 'group/item relative flex w-full items-center min-w-0 px-5 py-2.5 text-[15px] text-[#666] dark:text-white transition-colors duration-150 hover:!text-primary hover:bg-[#f2f2f2] dark:hover:bg-[#323e50] before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:h-0 before:w-[3px] before:rounded-r-full before:bg-primary before:transition-[height] before:duration-150 hover:before:h-[50%]'; export default () => { const patchName = usePathname(); @@ -111,18 +111,14 @@ export default () => { {one.icon} {one.name} - +
    - {one.children?.map((two, index) => ( -
  • + {one.children?.map((two) => ( +
  • {two.name} @@ -139,20 +135,16 @@ export default () => { {one.icon} {one.name} - +
      - {one.children?.map((two, index) => ( -
    • + {one.children?.map((two) => ( +
    • - {two.icon} + {two.icon} {two.name}
    • @@ -169,20 +161,16 @@ export default () => { {one.icon} {one.name} {/* 如果有子分类就显示下拉三角 */} - +
        - {one.children?.map((two, index) => ( -
      • + {one.children?.map((two) => ( +
      • - {two.icon} + {two.icon} {two.name}