Loading...

做一个评论系统(2)

日常推荐2个月前更新 Jone
70 0 0

闲来无事,准备用vue3重构下博客,主要是感觉每次写东西的时候仪式感太重了,每次都需要好多步骤才可以把数据推上去。最主要是我现在用的腾讯cdn加速,每次提交文章后还得刷新下cdn缓存,不然最新的文章总是刷不出来。

综上,目前正在一步步重构,完全按照自己的想法做一个。只有周末有时间弄,估计要好长时间才能弄完,弄完准备开源╭(●`∀´●)╯,希望能有佬给点建议。

先记录下vue3+vite实现的评论系统吧

后端

后端发来的数据json格式如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
[
{
"id": "1633425053677555714",
"content": "测试1",
"userEmail": "1449584369@qq.com",
"userName": "lkk",
"createTime": null,
"isDelete": 0,
"blogId": "/essay/",
"parentId": "-1",
"child": [
{
"id": "1633426077008101377",
"content": "回复测试1",
"userEmail": "1449584369@qq.com",
"userName": "lkk",
"createTime": "2023-03-08 11:14:59",
"isDelete": 0,
"blogId": "/essay/",
"parentId": "1633425053677555714",
"child": [
{
"id": "1633426195211976705",
"content": "回复回复测试1",
"userEmail": "1449584369@qq.com",
"userName": "lkk",
"createTime": "2023-03-08 11:15:27",
"isDelete": 0,
"blogId": "/essay/",
"parentId": "1633426077008101377",
"child": null
}
]
},
{
"id": "1633450477343531009",
"content": "回复测试1,2号",
"userEmail": "1449584369@qq.com",
"userName": "lkk",
"createTime": "2023-03-08 12:51:56",
"isDelete": 0,
"blogId": "/essay/",
"parentId": "1633425053677555714",
"child": null
}
]
},
{
"id": "1633425852315041794",
"content": "测试2",
"userEmail": "1449584369@qq.com",
"userName": "lkk",
"createTime": "2023-03-08 11:14:05",
"isDelete": 0,
"blogId": "/essay/",
"parentId": "-1",
"child": [
{
"id": "1633426253470859265",
"content": "回复测试2",
"userEmail": "1449584369@qq.com",
"userName": "lkk",
"createTime": "2023-03-08 11:15:41",
"isDelete": 0,
"blogId": "/essay/",
"parentId": "1633425852315041794",
"child": null
}
]
},
{
"id": "1633425874129616897",
"content": "测试3",
"userEmail": "1449584369@qq.com",
"userName": "lkk",
"createTime": "2023-03-08 11:14:10",
"isDelete": 0,
"blogId": "/essay/",
"parentId": "-1",
"child": null
}
]

后端发来的数据已经很简单明了了一眼就可以看出谁回复谁的。前端只需要遍历下json就可以了,我是用的vue3的父子组件来实现的。

我觉得突然悟了,原本样式都是抄的别人的,这两天一直自己边查边写,感觉样式也挺好懂的(只不过设计的有点丑)。

前端

用vue开发还是简单啊,直接用现成的布局组件和一些按钮输入框啥的,也不用担心设备适配的问题,基本都处理好了。

和vue2不同的是,你需要引入element-plus

1
2
3
4
5
6
7
import { createApp } from 'vue'
import Element from 'element-plus'
import './style.css'
import App from './App.vue'
import 'element-plus/dist/index.css'

createApp(App).use(Element).mount('#app')

简单来说两个组件就可以搞定,一个父组件,一个子组件。

父组件遍历所有对当前页面的评论,在遍历的过程中再调用子组件表示对这个评论的回复。子组件调用它本身,表示对这个回复的回复。

不知道能不能理解,就是递归的思想

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<template>
<div v-for="comment in commentList">
<div class="border">
<el-container id="comment">
<el-aside width="60px">
<Avatar :mail=comment.userEmail></Avatar>
</el-aside>
<el-main>
<div class="row">
<div class="meta">
<strong class="nick">{{comment.userName}}</strong>
<small class="time">{{comment.createTime}}</small>
</div>
<el-icon id="replay-icon" @click="isReplay(comment)"><ChatDotRound /></el-icon>
</div>
<div class="content">
<p>{{comment.content}}</p>
</div>
<div class="replies replies-expand">
<child :childComment = comment.child :parentComment = comment v-if="comment.child!=null"></child>
<replay :parentComment = comment v-if="replayId===comment.id"></replay>
</div>
</el-main>
</el-container>
</div>
</div>
</template>

用了el-container、el-aside、el-main,用来每一条评论布局。

for循环遍历所有对页面的评论就不多说了,主要看一下子组件child使用,往子组件中传了两个参数——comment.childcomment

comment.child用来给子组件提供评论数据。

comment则为子组件提供父组件信息,用来显示到界面上,就比如这个评论是回复给谁的。

replay这个组件是点击向某个评论回复时弹出来,现在还有点bug还没解决完。。。

Avatar组件提供每个评论者的头像,借鉴的twikoo,输入邮箱就可以获得qq头像了,向外部暴露了一个邮箱参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script setup lang='ts'>
import {ref,computed} from 'vue'
import {getQQAvatar} from '../utils/avatar.ts'
const props = defineProps({
mail: String})
let avatar = computed(()=>{
return getQQAvatar(props.mail);
})
</script>

<template>
<div class="avatar">
<img class="avatar-img" :src="avatar" alt="">
</div>
</template>

<style scoped>
.avatar {
flex-shrink: 0;
height: 2.5rem;
width: 2.5rem;
overflow: hidden;
text-align: center;
border-radius: 5px;
margin-right: 1rem;
}
.avatar .avatar-img {
height: 2.5rem;
color: #c0c4cc;
}
</style>

现在就差不多了,已经可以实现了。

不过提交评论的时候可能会有跨域问题,可以配一下vue的本地代理。

vite.config.ts修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server: {
https: false, // 是否开启 https
open: false, // 是否自动在浏览器打开
cors: true, // 允许跨域 8月更新
port: 3000, // 端口号
host: "127.0.0.1",
proxy: {
"/api": {
target: "", // 后台接口
changeOrigin: true,
secure: false, // 如果是https接口,需要配置这个参数
// ws: true, //websocket支持
rewrite: (path) => path.replace(/^\/api/, ""),
},
}
}

界面

做一个评论系统(2)

有点丑,真的尽力了。

© 版权声明

相关文章