评论的组件封装

2024-09-06 05:52
文章标签 封装 组件 评论

本文主要是介绍评论的组件封装,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
在这里插入图片描述

主评论的人在数组第一层级,回复的评论都在children里面

【{
name:"张三"
idGenerator: 475403892531269
info_Conmment":"今天天气晴朗😀"
children:[
{
mainIdGenerator:475388950118469
name:"张三"
name1:"李四"
idGenerator:475403933356101
info_Conmment:"哈哈哈哈"
}
]
}】
<template><divstyle="margin: 20px; margin-top: 40px"v-if="route.query.isComment == 'true' || props.isComment"><p style="font-size: 18px; color: #1d2129"><el-dividerstyle="width: 3px; height: 18px; background: #2c68ff; margin-left: 0px"direction="vertical"/>{{$t('view.course.comment')}}:</p><el-form :model="commentForm"><!-- maxlength="1000"show-word-limit --><el-form-item><el-inputv-model="commentForm.commentText":rows="3"type="textarea"maxlength="150"@input="handleInput(commentForm.commentText)":placeholder="$t('view.course.add_comment')"></el-input><div class="commentOperate"><div class="numberLimit">还能输入<span class="remainingCount">{{ remainingCount }}</span>个字符</div><div class="comment-operate-item"><VueEmoji @chooseEmoji="chooseEmoji" /><el-button class="commentBtn" type="primary" @click="userCommont">评论</el-button></div></div></el-form-item></el-form><!-- 评论列表 --><div v-if="comments.length > 0"><divv-for="(comment, index) in comments":key="comment.idGenerator"style="margin-top: 12px;border-bottom: 1px #f4f3f3;display: flex;align-items: flex-start;"><el-avatar:size="40"style="margin-right: 12px; margin-left: 10px":src="comment.avatarUrl || profile"></el-avatar><div style="flex: 1"><span style="font-size: 16px">{{ comment.name }}</span><p>{{ comment.info_Conmment }}</p><p style="font-size: 12px; color: #86909c; margin-top: 5px">{{ comment.createdTime }}<el-buttonlinkstyle="font-size: 12px; color: #86909c"@click="toggleLikeComment(comment.idGenerator, comment.isThumbsUp)"><!-- <svg-icon:icon-class="getCommentIconClass(comment.idGenerator)":src="getCommentIconSrc(comment.idGenerator)"class="svg-icon"style="margin-left: 20px;margin-right: 3px;transform: translateY(-1px);":class="{ liked: isCommentLiked(comment.idGenerator) }"/> --><svg-icon:icon-class="getCommentzanIconClass(comment.isThumbsUp)":src="getCommentzanIconSrc(comment.isThumbsUp)"class="svg-icon"style="margin-left: 20px;margin-right: 3px;transform: translateY(-1px);"/><span v-if="comment.thumbsUpCount > 0">{{comment.thumbsUpCount}}</span>{{ $t('view.course.like') }}</el-button><el-buttonlinkstyle="font-size: 12px; color: #86909c"@click="toggleReply(comment.idGenerator)"><el-icon style="margin-right: 3px; font-size: 16px"><ChatLineSquare /></el-icon>{{ $t('view.course.reply') }}</el-button><el-dropdown trigger="click"><template #default><span><el-button link><el-iconstyle="margin-left: 12px;color: #4e5969;font-size: 12px;transform: translateY(4px);"><MoreFilled /></el-icon></el-button></span></template><template #dropdown><el-dropdown-menu><el-dropdown-item @click="deleteComment(comment.idGenerator)">删除评论</el-dropdown-item><el-dropdown-item><el-dropdown trigger="hover" placement="right-start"><span>禁言<el-iconstyle="transform: translateY(3px); margin-left: 20px"><ArrowRight /> </el-icon></span><template #dropdown><el-dropdown-menu><el-dropdown-item @click="banUserHour(comment.id)">一个小时</el-dropdown-item><el-dropdown-item @click="banUserDay(comment.id)">一天</el-dropdown-item><el-dropdown-item @click="banUserWeek(comment.id)">一周</el-dropdown-item><el-dropdown-item @click="banUserForever(comment.id)">永久</el-dropdown-item></el-dropdown-menu></template></el-dropdown></el-dropdown-item></el-dropdown-menu></template></el-dropdown></p><!-- <el-inputv-if="showReplyInput[comment.id]"v-model="replyTexts[comment.id]"type="textarea"placeholder="说点什么吧"rows="4"maxlength="150"show-word-limitstyle="margin-top: 10px"/> --><el-form v-if="showReplyInput[comment.idGenerator]"><el-form-item class="childrenForm"><el-inputv-model="replyTexts[comment.idGenerator]":rows="3"type="textarea"maxlength="150"@input="handleInput(replyTexts[comment.idGenerator],comment.idGenerator)":placeholder="$t('view.course.add_comment')"></el-input><div class="commentOperate"><div class="numberLimit">还能输入<span class="remainingCount">{{remainCount[comment.idGenerator]}}</span>个字符</div><div class="comment-operate-item"><VueEmoji@chooseEmoji="chooseEmoji":replyComment="replyTexts[comment.idGenerator]":keyId="comment.idGenerator"/><el-buttonclass="commentBtn"type="primary"@click="userChildrenCommont(comment)">评论</el-button></div></div></el-form-item></el-form><!-- 子评论列表 --><divv-for="(reply, replyIndex) in comment.children":key="reply.id"style="margin-top: 12px"><divstyle="margin-top: 12px;border-bottom: 1px #f4f3f3;display: flex;align-items: flex-start;"><el-avatar:size="30":src="reply.avatarUrl || profile"style="margin-right: 12px"></el-avatar><div style="flex: 1"><span>{{ reply.name || "0713" }}</span><span style="margin-left: 10px; color: #86909c">{{ $t('view.course.reply') }}</span><span style="margin-left: 10px; margin-right: 10px">{{ reply.name1 }}:{{ reply.info_Conmment }}</span><p style="font-size: 12px; color: #86909c; margin-top: 5px">{{ reply.createdTime }}<el-buttonlinkstyle="font-size: 12px; color: #86909c"@click="toggleLikeComment(reply.idGenerator, reply.isThumbsUp)"><!-- <svg-icon:icon-class="getReplyIconClass(comment.id, reply.id)":src="getReplyIconSrc(comment.id, reply.id)"class="svg-icon"style="margin-left: 20px;margin-right: 3px;transform: translateY(-1px);":class="{ liked: isReplyLiked(comment.id, reply.id) }"/> --><svg-icon:icon-class="getCommentzanIconClass(reply.isThumbsUp)":src="getCommentzanIconSrc(reply.isThumbsUp)"class="svg-icon"style="margin-left: 20px;margin-right: 3px;transform: translateY(-1px);"/><span v-if="reply.thumbsUpCount > 0">{{reply.thumbsUpCount}}</span>点赞                  </el-button><el-buttonlinkstyle="font-size: 12px; color: #86909c"@click="toggleReply(reply.idGenerator)"><el-icon style="margin-right: 3px; font-size: 16px"><ChatLineSquare /></el-icon>回复</el-button><el-dropdown trigger="click"><template #default><span><el-button link><el-iconstyle="margin-left: 12px;color: #4e5969;font-size: 12px;transform: translateY(4px);"><MoreFilled /></el-icon></el-button></span></template><template #dropdown><el-dropdown-menu><el-dropdown-item@click="deleteComment(reply.idGenerator)">删除评论</el-dropdown-item><el-dropdown-item><el-dropdown trigger="hover" placement="right-start"><span>禁言<el-iconstyle="transform: translateY(3px);margin-left: 20px;"><ArrowRight /> </el-icon></span><template #dropdown><el-dropdown-menu><el-dropdown-item@click="banUserHour(comment.id)">一个小时</el-dropdown-item><el-dropdown-item@click="banUserDay(comment.id)">一天</el-dropdown-item><el-dropdown-item@click="banUserWeek(comment.id)">一周</el-dropdown-item><el-dropdown-item@click="banUserForever(comment.id)">永久</el-dropdown-item></el-dropdown-menu></template></el-dropdown></el-dropdown-item></el-dropdown-menu></template></el-dropdown></p><!-- <el-inputv-if="showReplyInput[reply.id]"v-model="replyTexts[reply.id]"type="textarea":placeholder="$t('view.course.add_comment')"rows="3"maxlength="150"show-word-limitstyle="margin-top: 10px"/> --><el-form><el-form-itemclass="childrenForm"v-if="showReplyInput[reply.idGenerator]"><el-inputv-model="replyTexts[reply.idGenerator]":rows="3"type="textarea"maxlength="150"@input="handleInput(replyTexts[reply.idGenerator],reply.idGenerator)":placeholder="$t('view.course.add_comment')"></el-input><div class="commentOperate"><div class="numberLimit">还能输入<span class="remainingCount">{{remainCount[reply.idGenerator]}}</span>个字符</div><div class="comment-operate-item"><VueEmoji@chooseEmoji="chooseEmoji":replyComment="replyTexts[reply.idGenerator]":keyId="reply.idGenerator"/><el-buttonclass="commentBtn"type="primary"@click="userChildrenCommont(reply)">评论</el-button></div></div></el-form-item></el-form></div></div></div><el-dividerborder-style="double"style="height: 1px; border: 1px solid #f4f3f3"/></div></div></div></div>
</template>
<script setup>
import VueEmoji from "@/views/activity/activityDetail/VueEmoji.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {addComments,searchComments,commentThumbsUp,commentCancelThumbsUp,deleteCommentApi,
} from "@/api/common";
import {singleCourseCommentThumbsUp,singleCourseCommentCancelThumbsUp,
} from "@/api/course";
import { useRoute, useRouter } from "vue-router";
const likeIcon = new URL("@/assets/images/icons/svg/like.svg", import.meta.url).href;
const yellowLikeIcon = new URL("@/assets/images/icons/svg/yellowlike.svg",import.meta.url
).href;
import profile from "@/assets/images/profile.jpg";
import { onMounted } from "vue";
const route = useRoute();
const router = useRouter();
const isComment = ref(true);
const detailLoading = ref(false);
// 評論數據
const comments = ref([]);
//回覆評論
const replyTexts = ref({});
const showReplyInput = ref({});
const commentForm = reactive({commentText: "",
});
const props = defineProps({isComment: {type: Boolean,default: false,},
});onMounted(()=>{searchCommentsFn()
})const getCommentzanIconSrc = (isThumbsUp) => {return isThumbsUp ? yellowLikeIcon : likeIcon;
};const getCommentzanIconClass = (isThumbsUp) => {return isThumbsUp ? "yellowlike" : "like";
};
const toggleReply = (commentId) => {remainCount.value[commentId] = 150;if (!showReplyInput.value[commentId]) {showReplyInput.value[commentId] = false;}showReplyInput.value[commentId] = !showReplyInput.value[commentId];
};// 評論點讚狀態
const commentLikes = ref({});const toggleLikeComment = (commentId, isThumbsUp) => {// if (!commentLikes.value[commentId]) {//   commentLikes.value[commentId] = false;// }// commentLikes.value[commentId] = !commentLikes.value[commentId];// console.log(commentLikes.value[commentId], "commentLikes.value[commentId]");if (!isThumbsUp) {singleCourseCommentThumbsUp({mainId: route.query.id,commentId: commentId,}).then((res) => {if (res.code == 200) {ElMessage.success("点赞成功");searchCommentsFn();}});} else {singleCourseCommentCancelThumbsUp({mainId: route.query.id,commentId: commentId,}).then((res) => {if (res.code == 200) {ElMessage.success("取消点赞");searchCommentsFn();}});}
};
const searchCommentsFn = () => {comments.value = []detailLoading.value = true;let params = {mainId: route.query.id,funType: 1,pageNum: 1,pageSize: 10,};searchComments(params).then((res) => {if (res.code == 200) {comments.value = res.data.items;detailLoading.value = false;} else {ElMessage.error(res.message);detailLoading.value = false;}});
};
const remainingCount = ref(150);
const remainCount = ref({});
const handleInput = (value, id) => {if (id) {remainCount.value[id] = 150 - value.length;} else {remainingCount.value = 150 - value.length;}// if (remainingCount.value < 0) {//   this.message = this.message.slice(0, this.maxLength);//   event.target.scrollTop = event.target.scrollHeight;// }
};const chooseEmoji = (item, replyComment, keyId) => {if (keyId) {replyComment += item;replyTexts.value[keyId] = replyComment;remainCount.value[keyId]--;} else {commentForm.commentText += item;remainingCount.value--;}
};
const addCommont = (params) => {addComments(params).then((res) => {if (res.code == 200) {ElMessage.success("评论成功");showReplyInput.value[params.parentIdGenerator] = false;replyTexts.value[params.parentIdGenerator] = "";remainCount[params.parentIdGenerator] = 150;commentForm.commentText = "";remainingCount.value = 150;searchCommentsFn();detailLoading.value = false;} else {detailLoading.value = false;ElMessage.error(res.message);}});
};
const userChildrenCommont = (comment) => {detailLoading.value = true;let params = {info_Conmment: replyTexts.value[comment.idGenerator],mainIdGenerator: comment.mainIdGenerator,parentIdGenerator: comment.idGenerator,moduleTypeEnums: 1,};addCommont(params);
};
const userCommont = () => {detailLoading.value = true;let params = {info_Conmment: commentForm.commentText,mainIdGenerator: route.query.id,parentIdGenerator: 0,moduleTypeEnums: 1,};addCommont(params);
};
// 刪除評論(按鈕)
const deleteComment = (idValue) => {const data = {id: idValue,};ElMessageBox.confirm(`確定刪除评论?`, "提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",}).then(() => {deleteCommentApi(data).then((res) => {if (res.code == 200) {ElMessage({type: "success",message: "刪除评论成功",});searchCommentsFn();} else {ElMessage({type: "error",message: res.message,});}});}).catch(() => {info;ElMessage.info("评论成功");});
};
watch(() => route.query,(newValue, oldValue) => {if (route.query.typeFlag == "courseindexEnter") {commentForm.commentText = "";showReplyInput.value = {};replyTexts.value = {};remainCount.value = {};remainingCount.value = 150;}},{ immediate: true }
);
defineExpose({ searchCommentsFn });
</script>
<style scoped lang="scss">
:deep(.el-form-item__content) {position: relative;//   margin-left: 20px;margin-top: 10px;padding-bottom: 10px;border: 1px solid #e7e7e7;border-radius: 6px;.el-textarea.el-input--default {.el-textarea__inner {box-shadow: 0 0 0 1px transparent !important;padding: 5px 16px !important;}}.commentOperate {height: 20px;border: 1px solid transparent;.numberLimit {position: absolute;// bottom: 5px;left: 16px;color: #999aaa;.remainingCount {color: #1d2129;padding: 0 2px;}}.comment-operate-img {width: 20px;height: 20px;}.comment-operate-item {position: absolute;// bottom: 0px;right: 21px;display: flex;align-items: center;.comment-operate-img {width: 20px;height: 20px;margin-right: 16px;cursor: pointer;}.commentBtn {padding-right: 10px;border-radius: 16px;width: 60px;height: 24px;font-size: 14px;}}}
}
</style>

emoji.json

{"data": "😀,😁,😂,😃,😄,😅,😆,😉,😊,😋,😎,😍,😘,😗,😙,😚,😇,😐,😑,😶,😏,😣,😥,😮,😯,😪,😫,😴,😌,😛,😜,😝,😒,😓,😔,😕,😲,😷,😖,😞,😟,😤,😢,😭,😦,😧,😨,😬,😰,😱,😳,😵,😡,😠,💘,❤,💓,💔,💕,💖,💗,💙,💚,💛,💜,💝,💞,💟,❣,💪,👈,👉,☝,👆,👇,✌,✋,👌,👍,👎,✊,👊,👋,👏,👐,✍,🍇,🍈,🍉,🍊,🍋,🍌,🍍,🍎,🍏,🍐,🍑,🍒,🍓,🍅,🍆,🌽,🍄,🌰,🍞,🍖,🍗,🍔,🍟,🍕,🍳,🍲,🍱,🍘,🍙,🍚,🍛,🍜,🍝,🍠,🍢,🍣,🍤,🍥,🍡,🍦,🍧,🍨,🍩,🍪,🎂,🍰,🍫,🍬,🍭,🍮,🍯,🍼,☕,🍵,🍶,🍷,🍸,🍹,🍺,🍻,🍴,🌹,🍀,🍎,💰,📱,🌙,🍁,🍂,🍃,🌷,💎,🔪,🔫,🏀,⚽,⚡,👄,👍,🔥,🙈,🙉,🙊,🐵,🐒,🐶,🐕,🐩,🐺,🐱,😺,😸,😹,😻,😼,😽,🙀,😿,😾,🐈,🐯,🐅,🐆,🐴,🐎,🐮,🐂,🐃,🐄,🐷,🐖,🐗,🐽,🐏,🐑,🐐,🐪,🐫,🐘,🐭,🐁,🐀,🐹,🐰,🐇,🐻,🐨,🐼,🐾,🐔,🐓,🐣,🐤,🐥,🐦,🐧,🐸,🐊,🐢,🐍,🐲,🐉,🐳,🐋,🐬,🐟,🐠,🐡,🐙,🐚,🐌,🐛,🐜,🐝,🐞,🦋,😈,👿,👹,👺,💀,☠,👻,👽,👾,💣"
}

这篇关于评论的组件封装的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141182

相关文章

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

Vue ElementUI中Upload组件批量上传的实现代码

《VueElementUI中Upload组件批量上传的实现代码》ElementUI中Upload组件批量上传通过获取upload组件的DOM、文件、上传地址和数据,封装uploadFiles方法,使... ElementUI中Upload组件如何批量上传首先就是upload组件 <el-upl

Vue3中的动态组件详解

《Vue3中的动态组件详解》本文介绍了Vue3中的动态组件,通过`component:is=动态组件名或组件对象/component`来实现根据条件动态渲染不同的组件,此外,还提到了使用`markRa... 目录vue3动态组件动态组件的基本使用第一种写法第二种写法性能优化解决方法总结Vue3动态组件动态

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表