完成目录级别样式

This commit is contained in:
宇阳
2024-08-25 21:41:00 +08:00
parent 586b811622
commit 8a8aa012d7
9 changed files with 131 additions and 73 deletions

View File

@@ -1,6 +1,17 @@
import Request from "@/utils/request";
import { Comment } from "@/types/app/comment";
// 新增评论
export const addCommentDataAPI = async (id: number, data: Comment) => {
return await Request<string>(`/comment/${id}`, {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
}
// 获取评论列表
export const getCommentListAPI = async () => {
return await Request<Paginate<Comment[]>>("/comment");

View File

@@ -31,7 +31,7 @@ export default async ({ params }: Props) => {
<Copyright />
<UpAndDown id={id} prev={{ id: 1, title: "大前端" }} next={{ id: 1, title: "大前端" }}/>
<Comment></Comment>
<Comment id={id}></Comment>
</div>
</div>
</div>

View File

@@ -1,11 +1,16 @@
"use client"
import React, { useState, useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
// import { addCommentDataAPI } from '@/api/Comment';
import { useForm } from 'react-hook-form';
import { Comment } from '@/types/app/comment'
import { addCommentDataAPI } from '@/api/comment';
import "./index.scss"
const CommentForm = () => {
interface Props {
id: number
}
const CommentForm = ({ id }: Props) => {
const [isEmote, setIsEmote] = useState(false);
const [placeholder, setPlaceholder] = useState("来发一针见血的评论吧~");
const [cid, setCid] = useState(0);
@@ -17,15 +22,10 @@ const CommentForm = () => {
name: "",
email: "",
url: "",
avatar: '',
rid: 0,
avatar: ''
}
});
useEffect(() => {
console.log(errors);
}, [errors])
useEffect(() => {
const info = JSON.parse(localStorage.getItem("data") || '{}');
setValue('name', info.name || '');
@@ -39,9 +39,13 @@ const CommentForm = () => {
// setPlaceholder(`回复评论给:${data.name}`);
// };
const onSubmit = async () => {
alert("🎉发布评论成功, 请等待审核!");
setPlaceholder("来发一针见血的评论吧~");
const onSubmit = async (data: Comment) => {
const { code, message } = await addCommentDataAPI(id, { ...data, createTime: Date.now() + "" })
console.log(code);
if (code !== 200) return alert("发布评论失败:" + message);
alert("🎉 发布评论成功, 请等待审核!");
// setPlaceholder("来发一针见血的评论吧~");
};
// const saveLocally = (formData) => {

View File

@@ -0,0 +1,75 @@
@import "@/styles/var.scss";
/* 添加平滑滚动效果 */
html {
scroll-behavior: smooth;
}
:target::before {
content: "";
display: block;
height: 80px;
/* 调整这个高度来设置偏移量 */
margin-top: -80px;
}
.ContentNavComponent {
.navs {
color: #4d4d4d;
font-size: 13px;
.nav_item {
padding-left: 10px;
margin-bottom: 5px;
transition: all 0.7s;
&::before {
content: "";
left: -10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 15px;
border-radius: 20px;
background-color: #539dfd;
transition: all 0.7s;
}
}
.active {
color: #539dfd;
padding-left: 30px;
border-radius: 10px;
background-color: #f7faff;
&::before {
left: 15px;
}
}
.h2 {
padding-left: 25px;
&.active {
padding-left: 35px;
&::before {
left: 20px;
}
}
}
.h3 {
padding-left: 45px;
&.active {
padding-left: 55px;
&::before {
left: 40px;
}
}
}
}
}

View File

@@ -6,6 +6,7 @@ interface NavItem {
href: string;
start: number;
end?: number;
className: string;
}
const OFFSET = 200; // 定义距离视口顶部多少像素时高亮导航项
@@ -16,25 +17,38 @@ const App: React.FC = () => {
useEffect(() => {
// 获取当前容器中所有的标题
// const list = document.querySelectorAll(".content h1, .content h2, .content h3");
const list = document.querySelectorAll(".content h2");
list.forEach((n) => n.setAttribute("id", n.textContent!));
const list = document.querySelectorAll(".content h1, .content h2, .content h3");
list.forEach((nav) => {
nav.setAttribute("id", nav.textContent!)
switch (nav.tagName) {
case "H1":
nav.setAttribute("class", "h1")
break;
case "H2":
nav.setAttribute("class", "h2")
break;
case "H3":
nav.setAttribute("class", "h3")
break;
}
});
// 给每个标题设置一个视口顶部的距离
const titles = Array.from(list).map(t => {
const top = t.getBoundingClientRect().top + window.scrollY;
return { href: t.textContent!, top };
return { href: t.textContent!, top, className: t.className };
});
// 设置起始距离和结束距离
const titlesList: NavItem[] = titles.map((title, index) => ({
href: title.href,
start: title.top,
end: index < titles.length - 1 ? titles[index + 1].top : Infinity
end: index < titles.length - 1 ? titles[index + 1].top : Infinity,
className: title.className
}));
console.log(titlesList);
setNavs(titlesList);
// 页面滚动到指定位置高亮导航项
@@ -56,12 +70,12 @@ const App: React.FC = () => {
<img src={directory.src} alt="" className="w-5 mr-2" />
</div>
<div className="w-full mt-4">
<div className="navs w-full mt-4">
{navs.map((item, index) => (
<a
key={index}
href={`#${item.href}`}
className={`nav_item overflow-hidden relative block p-3 hover:text-primary transition duration-700 ${active >= item.start && active < item.end! ? 'active' : ''}`}
className={`nav_item overflow-hidden relative block p-1 hover:text-primary transition duration-700 ${active >= item.start && active < item.end! ? 'active' : ''} ${item.className}`}
>
{item.href}
</a>

View File

@@ -11,10 +11,9 @@
.nav {
overflow: scroll;
width: 25%;
width: 20%;
max-height: 500px;
padding-left: 20px;
// margin-left: 5%;
padding-left: 10px;
border-left: 1px solid #eee;
position: sticky;
top: 90px;

View File

@@ -4,7 +4,7 @@ import React, { useEffect } from "react";
import ReactMarkdown from "react-markdown";
import "github-markdown-css"
import "./index.scss";
import ContentNav from "../ContentNav";
import ContentNav from "./component/ContentNav";
export default ({ data }: { data: string }) => {
useEffect(() => {

View File

@@ -1,45 +0,0 @@
@import "@/styles/var.scss";
/* 添加平滑滚动效果 */
html {
scroll-behavior: smooth;
}
:target::before {
content: "";
display: block;
height: 80px;
/* 调整这个高度来设置偏移量 */
margin-top: -80px;
}
.ContentNavComponent {
.nav_item {
padding-left: 10px;
transition: padding-left 0.7s;
&::before {
content: "";
left: -10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 20px;
border-radius: 20px;
background-color: #539dfd;
transition: all 0.7s;
}
}
.active {
color: #539dfd;
padding-left: 30px;
border-radius: 10px;
background-color: #f7faff;
&::before {
left: 15px;
}
}
}

View File

@@ -1,6 +1,6 @@
const url = "http://localhost:9999/api"
export default async <T>(api: string) => {
const res = await fetch(`${url}${api}`)
export default async <T>(api: string, data?: any) => {
const res = await fetch(`${url}${api}`, data)
return res.json() as Promise<Response<T>>;
}