Commit 5ce1af42 by lijiabin

【需求 20331】 perf: 优化组件

parent 6902c1be
...@@ -90,256 +90,265 @@ ...@@ -90,256 +90,265 @@
<!-- 分割线 --> <!-- 分割线 -->
<!-- 评论列表 --> <!-- 评论列表 -->
<div v-loading="loading" class="divide-y divide-gray-100" v-if="list.length"> <div v-loading="loading" class="divide-y divide-gray-100">
<div <div v-show="list.length">
v-for="(item, index) in list" <div
:key="item.id" v-for="(item, index) in list"
:ref="(el) => (commentItemRefList[index] = el as HTMLElement)" :key="item.id"
> :ref="(el) => (commentItemRefList[index] = el as HTMLElement)"
<div class="p-4 transition-colors"> >
<div class="flex gap-3"> <div class="p-4 transition-colors">
<img <div class="flex gap-3">
@click="jumpToUserHomePage({ userId: item.userId, type })" <img
:src="item.avatar" @click="jumpToUserHomePage({ userId: item.userId, type })"
alt="" :src="item.avatar"
class="w-10 h-10 rounded-full object-cover cursor-pointer" alt=""
/> class="w-10 h-10 rounded-full object-cover cursor-pointer"
<div class="flex-1"> />
<div class="flex items-center gap-2 mb-2"> <div class="flex-1">
<span class="font-semibold text-gray-800">{{ item.replyUser }}</span> <div class="flex items-center gap-2 mb-2">
<!-- <span <span class="font-semibold text-gray-800">{{ item.replyUser }}</span>
<!-- <span
class="px-2 py-0.5 text-xs bg-gradient-to-r from-purple-100 to-blue-100 text-purple-600 rounded-full" class="px-2 py-0.5 text-xs bg-gradient-to-r from-purple-100 to-blue-100 text-purple-600 rounded-full"
> >
技术专家 技术专家
</span> --> </span> -->
<!-- <span class="px-2 py-0.5 text-xs bg-red-100 text-red-600 rounded-full">置顶</span> --> <!-- <span class="px-2 py-0.5 text-xs bg-red-100 text-red-600 rounded-full">置顶</span> -->
</div>
<!-- 换行 -->
<p
class="text-gray-800 my-2 break-all whitespace-pre-wrap"
v-html="parseEmoji(item.content)"
></p>
<!-- 评论图片列表 -->
<div class="flex flex-wrap gap-2">
<div
v-for="(img, imgIndex) in item.imgUrl.split(',').filter(Boolean)"
:key="imgIndex"
class="w-20 h-20 rounded-lg overflow-hidden mb-2 cursor-pointer"
>
<el-image
:src="img"
:preview-teleported="true"
class="w-full h-full object-cover"
:preview-src-list="item.imgUrl.split(',').filter(Boolean)"
:initial-index="imgIndex"
fit="cover"
/>
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center gap-6 text-gray-500">
<span class="flex items-center gap-2 text-[14px]">
<span
>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span>·</span>
<span class="text-gray-500">{{ item.region }}</span>
</span>
<div class="flex gap-2 items-center hover:text-blue-500">
<div
class="flex items-center gap-1 cursor-pointer"
@click="handleLickComment(item)"
>
<el-icon :size="16">
<svg-icon :name="item.hasPraise ? 'praise_fill' : 'praise'"></svg-icon>
</el-icon>
<span>{{ item.postPriseCount }}</span>
</div>
</div>
<button
class="cursor-pointer hover:text-blue-500 transition-colors text-[14px]"
@click="handleReply(item, index)"
>
回复
</button>
</div> </div>
</div> <!-- 换行 -->
<!-- 回复列表 --> <p
<!-- 问吧 和 其他 做区分 --> class="text-gray-800 my-2 break-all whitespace-pre-wrap"
<template v-if="!isQuestion"> v-html="parseEmoji(item.content)"
<div v-if="item.children?.length" class="mt-3 ml-4 space-y-3"> ></p>
<!-- 回复评论的内容 里面可能是 展示全部的 也有可能是展示5条之内容 --> <!-- 评论图片列表 -->
<div class="flex flex-wrap gap-2">
<div <div
v-for="child in getCurrentChildrenList(item)" v-for="(img, imgIndex) in item.imgUrl.split(',').filter(Boolean)"
v-loading="item.loadingChildren" :key="imgIndex"
:key="child.id" class="w-20 h-20 rounded-lg overflow-hidden mb-2 cursor-pointer"
class="flex gap-2 p-3 rounded-lg"
> >
<img <el-image
@click="jumpToUserHomePage({ userId: child.userId, type })" :src="img"
:src="child.avatar" :preview-teleported="true"
alt="" class="w-full h-full object-cover"
class="w-8 h-8 rounded-full object-cover cursor-pointer" :preview-src-list="item.imgUrl.split(',').filter(Boolean)"
:initial-index="imgIndex"
fit="cover"
/> />
<div class="flex-1"> </div>
<div class="flex items-center gap-1"> </div>
<span class="font-semibold text-gray-600 text-base">{{ <div class="flex items-center justify-between">
child.replyUser <div class="flex items-center gap-6 text-gray-500">
}}</span> <span class="flex items-center gap-2 text-[14px]">
<!-- v-if="item.replyName && item.replyName !== parentComment?.replyUser" --> <span
<span class="text-gray-500 text-sm flex items-center gap-1"> >{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
<el-icon class="mx-1"><IEpCaretRight /></el-icon> </span>
{{ child.replyName }} <span>·</span>
</span> <span class="text-gray-500">{{ item.region }}</span>
</span>
<div class="flex gap-2 items-center hover:text-blue-500">
<div
class="flex items-center gap-1 cursor-pointer"
@click="handleLickComment(item)"
>
<el-icon :size="16">
<svg-icon :name="item.hasPraise ? 'praise_fill' : 'praise'"></svg-icon>
</el-icon>
<span>{{ item.postPriseCount }}</span>
</div> </div>
<p </div>
class="text-gray-800 my-2 break-all whitespace-pre-wrap text-[16px]" <button
v-html="parseEmoji(child.content)" class="cursor-pointer hover:text-blue-500 transition-colors text-[14px]"
></p> @click="handleReply(item, index)"
<!-- 评论图片列表 --> >
<div class="flex flex-wrap gap-2"> 回复
<div </button>
v-for="(img, imgIndex) in child.imgUrl.split(',').filter(Boolean)" </div>
:key="imgIndex" </div>
class="w-20 h-20 rounded-lg overflow-hidden mb-2" <!-- 回复列表 -->
> <!-- 问吧 和 其他 做区分 -->
<el-image <template v-if="!isQuestion">
:src="img" <div v-if="item.children?.length" class="mt-3 ml-4 space-y-3">
:preview-teleported="true" <!-- 回复评论的内容 里面可能是 展示全部的 也有可能是展示5条之内容 -->
class="w-full h-full object-cover" <div
:preview-src-list="child.imgUrl.split(',').filter(Boolean)" v-for="child in getCurrentChildrenList(item)"
:initial-index="imgIndex" v-loading="item.loadingChildren"
fit="cover" :key="child.id"
/> class="flex gap-2 p-3 rounded-lg"
>
<img
@click="jumpToUserHomePage({ userId: child.userId, type })"
:src="child.avatar"
alt=""
class="w-8 h-8 rounded-full object-cover cursor-pointer"
/>
<div class="flex-1">
<div class="flex items-center gap-1">
<span class="font-semibold text-gray-600 text-base">{{
child.replyUser
}}</span>
<!-- v-if="item.replyName && item.replyName !== parentComment?.replyUser" -->
<span class="text-gray-500 text-sm flex items-center gap-1">
<el-icon class="mx-1"><IEpCaretRight /></el-icon>
{{ child.replyName }}
</span>
</div> </div>
</div> <p
<div class="flex items-center justify-between"> class="text-gray-800 my-2 break-all whitespace-pre-wrap text-[16px]"
<div class="flex items-center gap-6 text-gray-500 text-[14px]"> v-html="parseEmoji(child.content)"
<span class="flex items-center gap-2"> ></p>
<span <!-- 评论图片列表 -->
>{{ dayjs(child.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }} <div class="flex flex-wrap gap-2">
<div
v-for="(img, imgIndex) in child.imgUrl.split(',').filter(Boolean)"
:key="imgIndex"
class="w-20 h-20 rounded-lg overflow-hidden mb-2"
>
<el-image
:src="img"
:preview-teleported="true"
class="w-full h-full object-cover"
:preview-src-list="child.imgUrl.split(',').filter(Boolean)"
:initial-index="imgIndex"
fit="cover"
/>
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center gap-6 text-gray-500 text-[14px]">
<span class="flex items-center gap-2">
<span
>{{
dayjs(child.createTime * 1000).format('YYYY-MM-DD HH:mm:ss')
}}
</span>
<span>·</span>
<span class="text-gray-500">{{ child.region }}</span>
</span> </span>
<span>·</span> <div class="flex gap-2 items-center hover:text-blue-500">
<span class="text-gray-500">{{ child.region }}</span> <div
</span> class="flex items-center gap-1 cursor-pointer"
<div class="flex gap-2 items-center hover:text-blue-500"> @click="handleLickComment(child)"
<div >
class="flex items-center gap-1 cursor-pointer" <el-icon :size="16">
@click="handleLickComment(child)" <svg-icon
> :name="child.hasPraise ? 'praise_fill' : 'praise'"
<el-icon :size="16"> ></svg-icon>
<svg-icon </el-icon>
:name="child.hasPraise ? 'praise_fill' : 'praise'" <span>{{ child.postPriseCount }}</span>
></svg-icon> </div>
</el-icon>
<span>{{ child.postPriseCount }}</span>
</div> </div>
<button
@click="handleReply(child, index)"
class="cursor-pointer hover:text-blue-500 transition-colors"
>
回复
</button>
</div> </div>
<button
@click="handleReply(child, index)"
class="cursor-pointer hover:text-blue-500 transition-colors"
>
回复
</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </template>
</template> <!-- 问吧 如果有 子评论 直接变成 查看更多 -->
<!-- 问吧 如果有 子评论 直接变成 查看更多 --> <template v-else>
<template v-else> <div v-if="item.childNum">
<div v-if="item.childNum"> <button
<button class="cursor-pointer text-sm text-gray-500 mt-2"
class="cursor-pointer text-sm text-gray-500 mt-2" @click="handleOpenCommentDialog(item)"
@click="handleOpenCommentDialog(item)" >
> 查看全部{{ item.childNum }} 条回复>
查看全部{{ item.childNum }} 条回复> </button>
</button> </div>
</div> </template>
</template> <!-- 只有大于5 才会显示这个 -->
<!-- 只有大于5 才会显示这个 --> <div class="ml-4" v-show="item.childrenNum > 5 && !isQuestion">
<div class="ml-4" v-show="item.childrenNum > 5 && !isQuestion"> <!-- 展示 展开回复 -->
<!-- 展示 展开回复 -->
<button
v-show="!item.showChildrenPage"
class="cursor-pointer text-sm text-gray-500"
@click="handleExpandReply(item)"
>
还有{{ item.childrenNum - 5 }}条回复,<span
class="hover:text-blue-500 transition-colors"
>点击查看</span
>
</button>
<!-- 展示 收起回复 以及分页 -->
<div class="flex items-center gap-2" v-show="item.showChildrenPage">
<span class="text-sm text-gray-500"
>共{{ Math.ceil(item.childrenNum / 10) }}页</span
>
<el-pagination
:pager-count="5"
layout="pager"
v-show="item.showChildrenPage"
:current-page="item.childrenPageCurrent"
:total="item.childrenNum"
@current-change="handleChildrenCurrentChange($event, item, index)"
/>
<button <button
class="cursor-pointer hover:text-blue-500 transition-colors text-sm text-gray-500" v-show="!item.showChildrenPage"
@click="handleCollapseReply(item, index)" class="cursor-pointer text-sm text-gray-500"
@click="handleExpandReply(item)"
> >
收起回复 还有{{ item.childrenNum - 5 }}条回复,<span
class="hover:text-blue-500 transition-colors"
>点击查看</span
>
</button> </button>
<!-- 展示 收起回复 以及分页 -->
<div class="flex items-center gap-2" v-show="item.showChildrenPage">
<span class="text-sm text-gray-500"
>共{{ Math.ceil(item.childrenNum / 10) }}页</span
>
<el-pagination
:pager-count="5"
layout="pager"
v-show="item.showChildrenPage"
:current-page="item.childrenPageCurrent"
:total="item.childrenNum"
@current-change="handleChildrenCurrentChange($event, item, index)"
/>
<button
class="cursor-pointer hover:text-blue-500 transition-colors text-sm text-gray-500"
@click="handleCollapseReply(item, index)"
>
收起回复
</button>
</div>
</div> </div>
<!-- 展示 回复评论的输入框 -->
<transition name="fadeToComment">
<div v-show="showCommentBox(item)" class="flex gap-3 mt-4">
<img
:src="userAvatar"
alt=""
class="w-10 h-10 rounded-full object-cover cursor-pointer"
@click="jumpToUserHomePage({ userId: userInfo.userId, type })"
/>
<CommentBox
v-model:inputText="commentToOther"
v-model:inputImg="commentToOtherImgStr"
class="flex-1"
:ref="(el) => (replyToOtherBoxRefList[index] = el as HTMLElement)"
>
<template #submit>
<button
class="cursor-pointer disabled:opacity-50 px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-500 text-white rounded-full text-sm hover:shadow-lg transition-all"
:disabled="!commentToOther.trim() || commentToOtherLoading"
@click="handleComment(index)"
>
发表
</button>
</template>
</CommentBox>
</div>
</transition>
</div> </div>
<!-- 展示 回复评论的输入框 -->
<transition name="fadeToComment">
<div v-show="showCommentBox(item)" class="flex gap-3 mt-4">
<img
:src="userAvatar"
alt=""
class="w-10 h-10 rounded-full object-cover cursor-pointer"
@click="jumpToUserHomePage({ userId: userInfo.userId, type })"
/>
<CommentBox
v-model:inputText="commentToOther"
v-model:inputImg="commentToOtherImgStr"
class="flex-1"
:ref="(el) => (replyToOtherBoxRefList[index] = el as HTMLElement)"
>
<template #submit>
<button
class="cursor-pointer disabled:opacity-50 px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-500 text-white rounded-full text-sm hover:shadow-lg transition-all"
:disabled="!commentToOther.trim() || commentToOtherLoading"
@click="handleComment(index)"
>
发表
</button>
</template>
</CommentBox>
</div>
</transition>
</div> </div>
</div> </div>
<div class="px-4">
<el-divider class="my-2!" />
</div>
</div> </div>
<div class="px-4"> <!-- 底部分页 -->
<el-divider class="my-2!" /> <!-- 靠右侧 -->
<div class="flex justify-end">
<div class="w-fit p-4">
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:total="firstComentTotal"
@current-change="handleCurrentChange"
@size-change="changePageSize"
layout="prev, pager, next, slot"
>
<div>共 {{ total }} 条</div>
</el-pagination>
</div>
</div> </div>
</div> </div>
<!-- 底部分页 --> <div v-show="!list.length">
<!-- 靠右侧 --> <div class="flex items-center justify-center">
<div class="flex justify-end"> <el-empty :image-size="100" description="暂无评论" />
<div class="w-fit p-4">
<el-pagination
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:total="firstComentTotal"
@current-change="handleCurrentChange"
@size-change="changePageSize"
layout="prev, pager, next, slot"
>
<div>共 {{ total }} 条</div>
</el-pagination>
</div> </div>
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment