Commits (2)
# React + TypeScript + Vite
# INTERN PROJECT FRONTEND
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
## 前端编辑方式
Currently, two official plugins are available:
### 修改方式
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 使用 npm run dev 即可实时跟随修改。
## Expanding the ESLint configuration 主要逻辑在 App.tsx 当中。
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: 如果需要修改逻辑,直接改正 App.tsx 的各个部分即可。
```js ### 打包方式
export default tseslint.config({
extends: [ 调用 npm run build 即可打包。
// Remove ...tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked, 打包后的文件在dist文件夹。
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked, 如果打包之后的html打开不显示,可以:
// Optionally, add this for stylistic rules - 把生成后的index.html打开
...tseslint.configs.stylisticTypeChecked, - 把js和css移至与html同目录下面
], - 把html当中引用js和css的路径修正
languageOptions: { - 去掉crossorigin字样
// other options... - 把script段从head移到body,并去掉type = "module"
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'], ## 后端对接
tsconfigRootDir: import.meta.dirname,
}, 在app.tsx当中硬编码了使用8080端口。可以在其中修改到实际使用的端口上面。
},
}) 后端对接部分与接口文档一致。具体内容如下:
设后端正确配置后,在8080端口上打开了后端服务(http://localhost:8080)。
### 获取评论:
URL:
- 部分获取: http://localhost:8080/comment/get?page={待请求的页码,从1开始计数}&size={每页大小}
- 获取全部: http://localhost:8080/comment/get?size=-1
方法:GET
header:无需
body: 无需
后端返回的response:
```json
{
"code": 0, // 0表示成功,其他表示失败
"msg": "success", // 返回信息
"data":
{
"total": int, //评论的总数,无论请求参数是什么
"comments":
[
{
"id": int, // 评论ID
"name": "string", // 评论者名字
"content": "string", // 评论内容
}
]
}
}
```
### 添加评论:
URL: http://localhost:8080/comment/add
方法:POST
header:
```json
{"Content-Type": "application/json"}
```
body:
```json
{
"name": "string", // 评论者名字
"content": "string" // 评论内容
}
``` ```
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: 后端返回的response:
```json
```js {
// eslint.config.js "code": 0, // 0表示成功,其他表示失败
import reactX from 'eslint-plugin-react-x' "msg": "success", // 返回信息
import reactDom from 'eslint-plugin-react-dom' "data":
{
export default tseslint.config({ "id": int, // 评论ID
plugins: { "name": "string", // 评论者名字
// Add the react-x and react-dom plugins "content": "string" // 评论内容
'react-x': reactX, }
'react-dom': reactDom, }
},
rules: {
// other rules...
// Enable its recommended typescript rules
...reactX.configs['recommended-typescript'].rules,
...reactDom.configs.recommended.rules,
},
})
``` ```
### 删除评论:
URL: http://localhost:8080/comment/delete?id={待删除的评论id}
方法:POST
header:无需
body: 无需
后端返回的response:
```json
{
"code": 0, // 0表示成功,其他表示失败
"msg": "success", // 返回信息
"data": null
}
```
...@@ -236,7 +236,7 @@ function App() { ...@@ -236,7 +236,7 @@ function App() {
<> <>
<div className="submit-container"> <div className="submit-container">
<form id="todoForm" onSubmit={handleSubmit}> <form id="todoForm" onSubmit={handleSubmit}>
<h3>用户名称</h3> <div className='form-text'><h3>用户名称</h3></div>
<input <input
type="text" type="text"
id="username" id="username"
...@@ -245,7 +245,7 @@ function App() { ...@@ -245,7 +245,7 @@ function App() {
onChange={(e) => setUsername(e.target.value)} onChange={(e) => setUsername(e.target.value)}
required required
></input> ></input>
<h3>评论内容</h3> <div className='form-text'><h3>评论内容</h3></div>
<input <input
type="text" type="text"
id="comment" id="comment"
...@@ -254,13 +254,12 @@ function App() { ...@@ -254,13 +254,12 @@ function App() {
onChange={(e) => setComment(e.target.value)} onChange={(e) => setComment(e.target.value)}
required required
></input> ></input>
<div> <div className="submit-button">
<button type="submit">提交</button> <button type="submit">提交</button>
</div> </div>
</form> </form>
</div> </div>
<h2>评论列表</h2> <div className="comment-topbar">
<div className="refresh-button">
{comments.length !== 0 && <p>{commentCount}条评论</p>} {comments.length !== 0 && <p>{commentCount}条评论</p>}
{comments.length === 0 && <p>暂无评论</p>} {comments.length === 0 && <p>暂无评论</p>}
<button type="button" onClick={fetchComments} disabled={loading}> <button type="button" onClick={fetchComments} disabled={loading}>
......
...@@ -23,7 +23,7 @@ a:hover { ...@@ -23,7 +23,7 @@ a:hover {
} }
body { body {
background-color: #f7f7f7; background-color: #f2f2f2;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
padding: 0; padding: 0;
margin: 0; margin: 0;
...@@ -63,28 +63,30 @@ body { ...@@ -63,28 +63,30 @@ body {
form { form {
justify-content: space-between; justify-content: space-between;
background-color: #eeeeee; background: linear-gradient(145deg, #f6ffff, #cfd6dc);
border: 1px solid #ccc; border: 1px solid #ccc;
margin-left: 1rem;
margin-right: 1rem;
margin-bottom: 1rem; margin-bottom: 1rem;
padding: 1rem 4rem; padding: 0.5rem 2rem;
box-shadow: 14px 14px 20px #dde4ea,
-14px -14px 20px #eff8fe;
} }
input[type="text"] { input[type="text"] {
flex: 1; flex: 1;
padding: 0.5rem; padding: 0.5rem 4rem;
font-size: 1rem; font-size: 1rem;
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 4px; border-radius: 4px;
background-color: #fff; background-color: #fff;
color: #111; color: #111;
margin-left: 1rem;
margin-right: 1rem;
} }
button { button {
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
margin-top: 0.5rem; margin-top: 0.5rem;
margin-bottom: 1rem; margin-bottom: 0.5rem;
border: none; border: none;
background-color: #10c266; background-color: #10c266;
color: #fff; color: #fff;
...@@ -102,11 +104,23 @@ button:focus-visible { ...@@ -102,11 +104,23 @@ button:focus-visible {
outline: 4px auto -webkit-focus-ring-color; outline: 4px auto -webkit-focus-ring-color;
} }
.refresh-button { .form-text{
display: flex;
justify-content: flex-start;
margin-left: 1rem;
}
.submit-button {
display: flex;
justify-content: flex-end;
margin-top : 0.5rem;
}
.comment-topbar {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0; padding: 0.5rem 2rem;
} }
...@@ -124,6 +138,13 @@ button:focus-visible { ...@@ -124,6 +138,13 @@ button:focus-visible {
margin-bottom: 2rem; margin-bottom: 2rem;
} }
.comments-container ul li:hover {
border-left: #E00000 5px solid;
background: linear-gradient(145deg, #f6ffff, #cfd6dc);
box-shadow: 31px 31px 62px #c4cacf,
-31px -31px 62px #ffffff;
}
.comments-container ul li .comment-name { .comments-container ul li .comment-name {
display: flex; display: flex;
align-items: left; align-items: left;
...@@ -132,6 +153,10 @@ button:focus-visible { ...@@ -132,6 +153,10 @@ button:focus-visible {
color: #666; color: #666;
} }
.comments-container ul li:hover .comment-name {
border-bottom: 1px solid #BBBBBB;
}
.comments-container ul li .comment-delete { .comments-container ul li .comment-delete {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
......