From 5aae86e41fafc66a576fa8039b97f409e1ae5c90 Mon Sep 17 00:00:00 2001 From: cumt-robin <1148121254@qq.com> Date: Fri, 1 Nov 2024 19:37:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(tag):=20=E6=A0=87=E7=AD=BE=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E7=AB=A0=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #98 --- .changeset/dirty-bears-study.md | 5 ++ app/cra-react18/src/router/index.tsx | 4 + app/cra-react18/src/views/Tag/index.tsx | 114 ++++++++++++++++++++++++ package.json | 1 + 4 files changed, 124 insertions(+) create mode 100644 .changeset/dirty-bears-study.md create mode 100644 app/cra-react18/src/views/Tag/index.tsx diff --git a/.changeset/dirty-bears-study.md b/.changeset/dirty-bears-study.md new file mode 100644 index 0000000..5b2083b --- /dev/null +++ b/.changeset/dirty-bears-study.md @@ -0,0 +1,5 @@ +--- +"cra-react18": minor +--- + +feat: 标签列表及标签下文章等功能页面 diff --git a/app/cra-react18/src/router/index.tsx b/app/cra-react18/src/router/index.tsx index 5ee8820..f74eab0 100644 --- a/app/cra-react18/src/router/index.tsx +++ b/app/cra-react18/src/router/index.tsx @@ -21,6 +21,10 @@ const router = createBrowserRouter([ path: "/tags", lazy: () => import("../views/Tags"), }, + { + path: "/tag/:name", + lazy: () => import("../views/Tag"), + }, ]); export default router; diff --git a/app/cra-react18/src/views/Tag/index.tsx b/app/cra-react18/src/views/Tag/index.tsx new file mode 100644 index 0000000..b58dd58 --- /dev/null +++ b/app/cra-react18/src/views/Tag/index.tsx @@ -0,0 +1,114 @@ +import { useCallback, useEffect, useRef, useState } from "react"; +import { NavLink, useParams, useSearchParams } from "react-router-dom"; +import styled from "styled-components"; +import { Breadcrumb, Divider, Empty, Pagination, Skeleton } from "antd"; +import BaseLayout from "@/components/BaseLayout"; +import { ArticleDTO } from "@/bean/dto"; +import { articleService } from "@/services/article"; +import { setScrollTop } from "@/utils/dom"; +import { useAsyncLoading } from "@/hooks/async"; +import CardArticle from "@/components/CardArticle"; + +const ArticleList = styled.section``; + +export const Component: React.FC = () => { + const { name } = useParams(); + + const [articleList, setArticleList] = useState([]); + + const [total, setTotal] = useState(0); + + const [searchParams, setSearchParams] = useSearchParams(); + + const qsPageNo = searchParams.get("pageNo"); + const pageNo = qsPageNo ? Number(qsPageNo) : 1; + const [pageInfo, setPageInfo] = useState({ pageNo, pageSize: 6 }); + + const prevPageNo = useRef(pageInfo.pageNo); + + const handleGetArticleList = useCallback( + async (isChangePage: boolean) => { + const { data, total } = await articleService.pageByTag({ + ...pageInfo, + keyword: name as string, + }); + setArticleList(data); + setTotal(total); + if (isChangePage) { + setScrollTop({ + useAnimation: true, + duration: 0.3, + }); + } + }, + [pageInfo, name], + ); + + const { trigger: getPageList, loading } = useAsyncLoading(handleGetArticleList, [pageInfo, name]); + + useEffect(() => { + const qsPageNo = searchParams.get("pageNo"); + const pageNo = qsPageNo ? Number(qsPageNo) : 1; + if (pageNo && pageNo > 0 && pageNo !== prevPageNo.current) { + setPageInfo((prevPageInfo) => ({ + ...prevPageInfo, + pageNo, + })); + } + }, [searchParams]); + + useEffect(() => { + const isChangePage = pageInfo.pageNo !== prevPageNo.current; + getPageList(isChangePage); + }, [pageInfo, getPageList]); + + useEffect(() => { + prevPageNo.current = pageInfo.pageNo; + }, [pageInfo]); + + // 分页改变 + const onPageNoChange = (page: number) => { + setSearchParams({ pageNo: String(page) }); + }; + + return ( + + + {articleList.length > 0 ? ( + <> + + + 首页 + + + 所有标签 + + {name} + + + + + + {articleList.map((article) => ( + + ))} + + + + + ) : ( + + )} + + + ); +}; diff --git a/package.json b/package.json index 1170423..810294e 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ }, "homepage": "https://blog.wbjiang.cn/", "scripts": { + "changeset": "changeset", "webpack-vue3:dev": "pnpm --filter webpack-vue3 dev", "vite-vue3:dev": "pnpm --filter vite-vue3 dev", "cra-react18:dev": "pnpm --filter cra-react18 dev",