【Vue3组件】分享一下自己写的简约风格评论区组件


代码比较简单,方便大家二次开发,旨在快速提供基础的样式模板,自行迭代定制


预览

在这里插入图片描述


简介

data = [
            {
            userImg:'',
            userName:"比克",
            time:'17小时前',
            content:"这生成的真不错呀!",
            ReplyData:[
                {
                    userImg1:'',
                    userName1:'比克大魔王',
                    userImg2:'',
                    userName2:'后方之水',
                    replytime:'6小时前',
                    replycontent:'哈哈哈,多谢夸奖!',
                    anthTags:1
                },
                {
                    userImg1:'',
                    userName1:'后方之水',
                    userImg2:'',
                    userName2:'比克大魔王',
                    replytime:'6小时前',
                    replycontent:'我也要生成同款',
                    anthTags:2
                },
            ]
        }
    ]
  • 使用提示

    • 确认传递给组件的数据严格遵循上述结构,以确保界面的正确显示。
    • 利用Vue 3的Composition API特性,可以进一步优化状态管理和逻辑处理。

代码

父组件

<template>
    <div class="firstglobals">
        <div class="avatar">
            <img :src="data.userImg" style="width: 56px; height: 56px; border-radius: 50%;" alt="" />
        </div>
        <div class="content">
            <div class="usertop">
                <div class="username">{{ data.userName }}</div>
                <div class="time">{{ data.time }}</div>
            </div>
            <div style="display: flex; flex-direction: column; margin-top: 1em;">
                <div class="text">{{ data.content }}</div>
                <div style="display: flex; align-self: flex-end;">
                    <img src="@/assets/globals/点赞默认.png" style="width: 20px;" alt="" />
                </div>
                <div class="but">回复</div>
            </div>
            <div>
                <div v-for="(item, index) in displayedReplies" :key="index">
                    <LuxCommentSectionItem :replyData="item" />
                </div>
                <div v-if="!showAllReplies && data.ReplyData.length > 2" class="load-more"
                    @click="showAllReplies = true">
                    加载更多回复 ...
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import LuxCommentSectionItem from '@/components/currency/LuxCommentSectionItem.vue';

interface ReplyData {
    userImg1:string,
    userName1:string,
    userImg2:string,
    userName2:string,
    replytime:string,
    replycontent:string,
    anthTags:number
}


interface CommentData {
    userImg: string;
    userName: string;
    time: string;
    content: string;
    ReplyData: ReplyData[];
}

const props = defineProps<{
    data: CommentData;
}>();

const showAllReplies = ref(false);

const displayedReplies = computed(() => {
    if (showAllReplies.value || props.data.ReplyData.length <= 2) {
        return props.data.ReplyData;
    } else {
        return props.data.ReplyData.slice(0, 2);
    }
});
</script>

<style scoped>
.but {
    width: 60px;
    padding: 5px 0px;
    background: #f1f1f1;
    border-radius: 4px;
    display: flex;
    justify-content: center;
    align-content: center;
    font-weight: 400;
    font-size: 14px;
    color: #0f1014;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

.but:hover {
    background: #ebe4e4;
}

.text {
    font-weight: 400;
    font-size: 18px;
    color: #000000;
    line-height: 21px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

.time {
    font-weight: 400;
    font-size: 12px;
    color: #666666;
    line-height: 14px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

.avatar {
    width: 56px;
    height: 56px;
    border-radius: 30px;
}

.usertop {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.username {
    font-weight: 700;
    font-size: 16px;
    color: #0f1014;
    line-height: 19px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

.content {
    display: flex;
    flex-direction: column;
    margin-left: 1em;
    margin-top: 10px;
    flex: 1;
}

.firstglobals {
    display: flex;
    justify-content: start;
    margin-top: 2em;
}

.load-more {
    margin-top: 30px;
    margin-left: 2em;
    color: #0066cc;
    cursor: pointer;
    font-size: 14px;
    font-size: 14px;
    cursor: pointer;
}


.load-more:hover {
    text-decoration: underline;

}
</style>

子组件

<template>
    <div class="reply-comments">
        <div class="top-user">
            <div style="display: flex;
            justify-content: center;align-content: center;gap: 8px;">
                <img :src="replyData.userImg1" style="width: 24px;height: 24px;border-radius: 50%;" alt="">
                <span class="username">{{ replyData.userName1 }}</span>
            </div>
            <div class="tags" v-if="replyData.anthTags === 1">
                作者
            </div>
            <div class="hf">
                回复
            </div>
            <div style="display: flex;
            justify-content: center;align-content: center;gap: 8px;">
                <img :src="replyData.userImg2" style="width: 24px;height: 24px;border-radius: 50%;" alt="">
                <span class="username">{{ replyData.userName2 }}</span>
            </div>
            <div class="tags" v-if="replyData.anthTags === 2">
                作者
            </div>
            <div class="time">
                {{ replyData.replytime }}
            </div>
        </div>
        <div class="content">
            {{ replyData.replycontent }}
        </div>
        <div style="display: flex;align-self: flex-end;">
            <img src="@/assets/globals/点赞默认.png" style="width: 20px;" alt="">
        </div>
        <div class="but">
            回复
        </div>
    </div>
</template>

<script setup lang="ts">

interface ReplyData {
    userImg1: string,
    userName1: string,
    userImg2: string,
    userName2: string,
    replytime: string,
    replycontent: string,
    anthTags: number
}

const props = defineProps<{
    replyData: ReplyData
}>();
</script>

<style scoped>
.but {
    width: 60px;
    /* height: 28px; */
    padding: 5px 0px;
    background: #F1F1F1;
    border-radius: 4px 4px 4px 4px;
    display: flex;
    justify-content: center;
    align-content: center;
    font-weight: 400;
    font-size: 14px;
    color: #0F1014;
    /* line-height: 16px; */
    text-align: left;
    font-style: normal;
    text-transform: none;
    margin-left: 32px;
}

.but:hover {
    background: #ebe4e4;
}

.content {
    font-weight: 400;
    font-size: 18px;
    color: #000000;
    line-height: 21px;
    text-align: left;
    font-style: normal;
    text-transform: none;
    margin-left: 32px;
    margin-top: 10px;
}

.time {
    font-weight: 400;
    font-size: 12px;
    color: #666666;
    line-height: 14px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

.hf {
    font-weight: 400;
    font-size: 14px;
    color: #B9B9B9;
    line-height: 16px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

.tags {
    width: 32px;
    height: 18px;
    background: #0F1014;
    border-radius: 4px 4px 4px 4px;
    color: #fff;
    font-weight: 400;
    font-size: 10px;
    color: #FFFFFF;
    line-height: 12px;
    text-align: center;
    font-style: normal;
    text-transform: none;
    flex-wrap: wrap;
    display: flex;
    justify-content: center;
    align-items: center;
}


.username {
    height: 24px;
    font-weight: 500;
    font-size: 13px;
    color: #0F1014;
    line-height: 15px;
    text-align: left;
    font-style: normal;
    text-transform: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
}

.top-user {
    display: flex;
    align-items: center;
    /* flex-wrap: wrap; */
    gap: 8px;
}

.reply-comments {
    display: flex;
    flex-direction: column;
    margin-top: 1em;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/735624.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Paimon Trino Presto的关系 分布式查询引擎

Paimon支持的引擎兼容性矩阵&#xff1a; Trino 是 Presto 同项目的不同版本&#xff0c;是原Faceboo Presto创始人团队核心开发和维护人员分离出来后开发和维护的分支&#xff0c;Trino基于Presto&#xff0c;目前 Trino 和 Presto 都仍在继续开发和维护。 Trino 生态系统-客…

虚拟机IP地址频繁变化的解决方法

勾八动态分配IP&#xff0c;让我在学习redis集群的时候&#xff0c;配置很多的IP地址&#xff0c;但是由于以下原因导致我IP频繁变动&#xff0c;报错让我烦恼&#xff01;&#xff01;&#xff01;&#xff01; 为什么虚拟机的IP地址会频繁变化&#xff1f; 虚拟机IP地址频繁…

webpack处理js资源10--webpack入门学习

处理 js 资源 有人可能会问&#xff0c;js 资源 Webpack 不能已经处理了吗&#xff0c;为什么我们还要处理呢&#xff1f; 原因是 Webpack 对 js 处理是有限的&#xff0c;只能编译 js 中 ES 模块化语法&#xff0c;不能编译其他语法&#xff0c;导致 js 不能在 IE 等浏览器运…

Zabbix+Garafana监控部署

ZabbixGarafana监控部署 一、IP规划 服务器IP备注zabbix-server192.168.100.128zabbix服务端zabbix-mysql192.168.100.130数据库zabbix-client192.168.100.132zabbix客户端garafana-server192.168.100.134Garafana 二、zabbix-server安装zabbix ​ 配置IP地址为&#xff1a…

俄语打招呼和问候的12种表达方式,柯桥俄语培训

- Как дела ? 近况如何&#xff1f; -Нормально, а ты как? 还行吧&#xff0c;你呢&#xff1f; Vol.2 -Как себя чувствуете? 你感觉如何&#xff1f; -Все замечательно! 一切都非常棒。 Vol.3 -Ка…

基于matlab的图像灰度化与图像反白

1原理 2.1 图像灰度化原理 图像灰度化是将彩色图像转换为灰度图像的过程&#xff0c;使得每个像素点仅包含一个灰度值&#xff0c;从而简化了图像的复杂度。灰度化原理主要可以分为以下几种方法&#xff1a; 亮度平均法 原理&#xff1a;将图像中每个像素的RGB值的平均值作为…

Vue40 修改默认配置

修改默认配置 在官网查看各个属性的作用 ### 在vue.config.js文件中&#xff0c;修改属性的值

计算机网络 静态路由及动态路由RIP

一、理论知识 1.静态路由 静态路由是由网络管理员手动配置在路由器上的固定路由路径。其优点是简单和对网络拓扑变化不敏感&#xff0c;缺点是维护复杂、易出错&#xff0c;且无法自动适应网络变化。 2.动态路由协议RIP RIP是一种基于距离向量的动态路由协议。它使用跳数作…

接口自动化拓展:Flask框架安装、介绍及工作中的应用!

Flask是一个轻量级的Python Web框架&#xff0c;用于构建Web应用程序和API。它简洁而灵活&#xff0c;容易上手&#xff0c;并且非常适合用于开发小型到中型规模的应用程序。在接口自动化测试中&#xff0c;Flask可以作为服务器框架&#xff0c;用于搭建测试接口。 本文将从零…

使用USI作为主SPI接口

代码; lcd_drive.c //***************************************************************************** // // File........: LCD_driver.c // // Author(s)...: ATMEL Norway // // Target(s)...: ATmega169 // // Compiler....: AVR-GCC 3.3.1; avr-libc 1.0 // // D…

UltraEditUEStudio软件安装包下载及安装教程

​根据软件大数据显示提供预定义的或使用者创建的编辑“环境”&#xff0c;能记住 UltraEdit 的所有可停靠窗口、工具栏等的状态。实际上我们可以这样讲HTML 工具栏&#xff0c;对常用的 HTML 功能作了预配置;文件加密/解密;多字节和集成的 IME。根据使用者情况表明Git Editor&…

day41--Redis(三)高级篇之最佳实践

Redis高级篇之最佳实践 今日内容 Redis键值设计批处理优化服务端优化集群最佳实践 1、Redis键值设计 1.1、优雅的key结构 Redis的Key虽然可以自定义&#xff0c;但最好遵循下面的几个最佳实践约定&#xff1a; 遵循基本格式&#xff1a;[业务名称]:[数据名]:[id]长度不超过…

【Linux系列】find命令使用与用法详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-26网络中的网络NiN

26网络中的网络NiN import torch from torch import nn import liliPytorch as lp import matplotlib.pyplot as plt# 定义一个NiN块 def nin_block(in_channels, out_channels, kernel_size, strides, padding):return nn.Sequential(# 传统的卷积层nn.Conv2d(in_channels, ou…

兰州理工大学24计算机考研情况,好多专业都接受调剂,只有计算机专硕不接收调剂,复试线为283分!

兰州理工大学&#xff08;Lanzhou University of Technology&#xff09;&#xff0c;位于甘肃省兰州市&#xff0c;是甘肃省人民政府、教育部、国家国防科技工业局共建高校&#xff0c;甘肃省高水平大学和“一流学科”建设高校&#xff1b;入选国家“中西部高校基础能力建设工…

年薪50w+的项目经理,手把手教你如何复盘

复盘是一种重要的学习和改进工具&#xff0c;对于项目经理来说&#xff0c;能帮助识别项目中的成功与失败&#xff0c;为未来的项目管理提供宝贵经验。 理论部分 定义目标。在开始复盘之前&#xff0c;明确复盘的目标是什么。是为了找出项目中的问题并提出解决方案&#xff0c…

Open MMLab 之 MMDetection3D框架

MMDetection框架入门教程&#xff08;完全版&#xff09;-CSDN博客 OpenMMLab MMDetection是商汤和港中文大学针对目标检测任务推出的一个开源项目&#xff0c;它基于Pytorch实现了大量的目标检测算法&#xff0c;把数据集构建、模型搭建、训练策略等过程都封装成了一个个模块…

Chromium 调试指南2024 Mac篇 - 准备工作 (一)

1.引言 Chromium是一个由Google主导开发的开源浏览器项目&#xff0c;它为Google Chrome浏览器提供了基础框架。Chromium不仅是研究和开发现代浏览器技术的重要平台&#xff0c;还为众多其他基于Chromium的浏览器&#xff08;如Microsoft Edge、Brave等&#xff09;提供了基础…

基于Openmv的色块识别代码及注意事项

在给出代码之前我先说注意事项以及需要用到的函数 1、白平衡和自动增益的关闭 打开白平衡和自动增益会影响颜色识别的效果&#xff0c;具体影响体现在可能使你颜色阈值发生改变 关闭代码如下 sensor.set_auto_gain(False) #关闭自动增益 sensor.set_whitebal(False) …

【笔记】HashMap的头插死循环问题

HashMap头插死循环是指在JDK1.7中&#xff0c;多线程环境下&#xff0c;HashMap进行扩容时由于多个线程一起执行扩容&#xff0c;可能会导致某一结点被错误插入头部并形成一个循环链表。 发生死循环的源码如下&#xff1a; // hashmap由数组链表构成 void transfer(Entry[] ne…