仿抖音评论系统:GitHub_Trending/do/douyin嵌套评论实现
在当今社交媒体平台中,评论系统是用户互动的核心功能之一。特别是嵌套评论功能,能够让用户之间的对话更加连贯和有条理。本文将详细介绍如何在GitHub_Trending/do/douyin项目中实现仿抖音风格的嵌套评论系统,包括评论展示、回复展开/折叠、点赞等功能。
评论组件结构
该项目的评论系统核心组件是src/components/Comment.vue,它采用了Vue.js的单文件组件形式,包含模板、脚本和样式三部分。
模板结构
模板部分使用了<from-bottom-dialog>组件作为容器,实现从底部弹出的评论对话框效果。对话框头部显示评论数量,中间部分是评论列表,底部是评论输入框。
评论列表通过嵌套的v-for指令实现,外层循环遍历主评论,内层循环遍历子评论(回复)。这种结构天然适合实现嵌套评论功能。
<div class="items">
<div class="item" :key="i" v-for="(item, i) in comments">
<!-- 主评论内容 -->
<div class="main">
<!-- 主评论内容展示 -->
</div>
<!-- 回复列表 -->
<div class="replies" v-if="Number(item.sub_comment_count)">
<template v-if="item.showChildren">
<div class="reply" :key="i" v-for="(child, i) in item.children">
<!-- 子评论内容展示 -->
</div>
</template>
<!-- 展开/折叠回复按钮 -->
</div>
</div>
</div>
脚本逻辑
脚本部分主要包含数据定义、计算属性、生命周期钩子和方法。其中核心方法包括:
getData(): 从API获取评论数据handShowChildren(): 展开/折叠回复send(): 发送评论loved(): 点赞/取消点赞
嵌套评论实现
数据结构
评论数据采用了树形结构,每个评论对象包含以下关键字段:
{
comment_id: "评论ID",
content: "评论内容",
nickname: "用户昵称",
avatar: "用户头像",
digg_count: "点赞数",
user_digged: "是否已点赞",
sub_comment_count: "回复数量",
children: "回复列表",
showChildren: "是否显示回复"
}
这种结构允许无限层级的嵌套评论,但在实际应用中,为了性能考虑,通常会限制嵌套层级。
展开/折叠功能
回复的展开/折叠功能通过handShowChildren()方法实现:
async handShowChildren(item) {
this.loadChildrenItemCId = item.comment_id
this.loadChildren = true
await _sleep(500) // 模拟加载延迟
this.loadChildren = false
if (item.showChildren) {
item.children = item.children.concat(sampleSize(this.comments, 10)) // 加载更多回复
} else {
item.children = sampleSize(this.comments, 3) // 初始加载3条回复
item.showChildren = true
}
}
当用户点击"展开回复"按钮时,该方法会切换showChildren状态,并加载相应的回复数据。为了提升用户体验,这里使用了_sleep(500)模拟网络请求延迟,并显示加载动画。
样式设计
嵌套评论的视觉层次通过CSS的padding实现:
.replies {
padding-left: 55rem; /* 通过左内边距实现缩进效果 */
}
这种设计使得回复评论相对于主评论向右缩进,形成清晰的视觉层次,用户可以直观地区分评论的层级关系。
核心功能实现
评论发送
评论发送功能通过send()方法实现:
send() {
if (!this.comment.trim()) {
return // 如果评论内容为空,直接返回
}
// 构建评论数据
const commentData = {
ip_location: baseStore.userinfo.ip_location,
aweme_id: this.videoId,
content: this.comment,
create_time: Date.now(),
// 其他必要字段...
}
// 将新评论添加到评论列表的最前面
this.comments.unshift(commentData)
// 清空输入框
this.comment = ''
// 重置@好友状态
this.isCall = false
this.resetSelectStatus()
}
发送成功后,新评论会立即添加到评论列表的最前面,实现"发布即见"的效果,提升用户体验。
点赞功能
点赞功能通过loved()方法实现:
loved(row) {
if (row.isLoved) {
row.digg_count-- // 取消点赞,点赞数减1
} else {
row.digg_count++ // 点赞,点赞数加1
}
row.user_digged = !row.user_digged // 切换点赞状态
}
点赞状态的切换会立即更新UI,无需等待服务器响应,这种"乐观更新"策略可以提升用户体验。
@好友功能
评论系统还支持@好友功能,通过toggleCall()方法实现:
toggleCall(item) {
item.select = !item.select
let name = item.name
if (this.comment.includes('@' + name)) {
this.comment = this.comment.replace(`@${name} `, '') // 移除@好友
} else {
this.comment += `@${name} ` // 添加@好友
}
}
用户可以点击"@"按钮选择好友,被选中的好友昵称会自动添加到评论输入框中。
界面设计
整体布局
评论系统采用了底部弹出的对话框形式,占据屏幕70%的高度:
<from-bottom-dialog
:page-id="pageId"
:modelValue="modelValue"
@update:modelValue="(e) => $emit('update:modelValue', e)"
@cancel="cancel"
:show-heng-gang="false"
maskMode="light"
:height="height" // 高度设置为"calc(var(--vh, 1vh) * 70)"
tag="comment"
mode="white"
>
这种设计既保证了评论区域有足够的空间,又不会完全遮挡视频内容。
评论项设计
每个评论项包含用户头像、昵称、评论内容、时间、点赞按钮和回复按钮:
加载状态
为了提升用户体验,系统在加载回复时会显示加载动画:
<Loading
v-if="loadChildren && loadChildrenItemCId === item.comment_id"
:type="'small'"
:is-full-screen="false"
/>
总结与扩展
主要特点
- 树形数据结构:采用树形数据结构存储评论,支持无限层级嵌套
- 延迟加载:回复采用延迟加载策略,提升初始加载速度
- 乐观更新:点赞、评论等操作采用乐观更新,提升用户体验
- 视觉层次:通过缩进和样式设计,清晰展示评论层级关系
优化方向
- 性能优化:对于大量评论,可以实现虚拟滚动(Virtual Scrolling)
- 缓存策略:缓存已加载的评论数据,减少网络请求
- 动画效果:添加评论发布、删除的动画效果
- 富文本支持:支持表情、图片等富文本评论
相关文件
- 评论组件:src/components/Comment.vue
- API接口:src/api/videos.ts
- 工具函数:src/utils/index.tsx
通过本文的介绍,我们了解了GitHub_Trending/do/douyin项目中嵌套评论系统的实现方案。这种实现方式既满足了功能需求,又保证了良好的用户体验,值得在类似项目中借鉴。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




