一、前述
最近接到一个在uniapp中nvue环境下实现评论区效果的需求,如图:
我们讨论的重点在于,图片中子评论区域的实现。
在vue类型的页面中<text>标签与<span>相似,均为行内元素,我们可以很轻松的实现图上的这一效果。但是在nvue环境下,元素仅支持flex布局,这就造成了我们无法使用行内元素的形式来实现这一效果。
先对按照UI做出基本代码:
<template>
<view>
<!--为方便阅读已去除其他代码,仅保留子评论相关代码-->
<view class="reply_sub_box">
<view class="reply_sub_item" v-for="subReply in replyData.sub_reply">
<!--昵称-->
<text class="reply_sub_item_nick">{{subReply.nick}}: </text>
<!--子评论内容-->
<text class="reply_sub_item_content">{{subReply.content}}</text>
</view>
</view>
</view>
</template>
<style>
.reply_sub_box{
padding: 11px;
border-radius: 5px;
background-color: #F3F6FD;
width: 545upx;
}
.reply_sub_item{
padding: 2px 0;
}
.reply_sub_item_nick,.reply_sub_item_content{
color: #333;
font-size: 13px;
line-height: 18px;
}
.reply_sub_item_nick{
font-weight:500;
color: #022454;
}
</style>
实现效果如图:
如图所示,两个text均被处理为块级元素,昵称独占一行。我们需要将昵称与内容处理为同一行,并且能够在样式上有所区分。
二、使用flex-direction处理排列方式(仅支持单行)
在nvue中,为方便元素布局,会默认flex的排列方向为纵向。通过设定flex-direction为row,可将子元素水平显示。
<template>
<view>
<!--为方便阅读已去除其他代码,仅保留子评论相关代码-->
<view class="reply_sub_box">
<view class="reply_sub_item" v-for="subReply in replyData.sub_reply">
<!--昵称-->
<text class="reply_sub_item_nick">{{subReply.nick}}: </text>
<!--子评论内容-->
<text class="reply_sub_item_content">{{subReply.content}}</text>
</view>
</view>
</view>
</template>
<style>
.reply_sub_box{
padding: 11px;
border-radius: 5px;
background-color: #F3F6FD;
width: 545upx;
}
.reply_sub_item{
flex-direction: row;/*在昵称与评论内容父元素增加此代码*/
padding: 2px 0;
}
.reply_sub_item_nick,.reply_sub_item_content{
color: #333;
font-size: 13px;
line-height: 18px;
}
.reply_sub_item_nick{
font-weight:500;
color: #022454;
}
</style>
实现效果如图:
至此,子评论的展示基本正常。但是,这个方法具有局限性。一旦评论的文本为多行,则会出现如下情况:
在评论长度超出之后,文本无法换行。
三、使用绝对定位叠加
这个是我目前使用的方式
提示:使用这个方法具有一定的限制:
1、差异字体与文本段落大小一致或接近
2、文字位置相对固定(例如本文中的昵称,相对位置固定于整个模块的左上)
当然了,他的优点是实现简单,相比下文的富文本,代码量较小
<template>
<view>
<!--为方便阅读已去除其他代码,仅保留子评论相关代码-->
<view class="reply_sub_box">
<view class="reply_sub_item" v-for="subReply in replyData.sub_reply">
<!--子评论内容,在评论内容之前加入昵称进行占位-->
<text class="reply_sub_item_content">{{subReply.nick}}:{{subReply.content}}</text>
<!--昵称,移到评论下方以确保层级在其之上可遮盖评论中的昵称部分-->
<text class="reply_sub_item_nick">{{subReply.nick}}:</text>
</view>
</view>
</view>
</template>
<style>
.reply_sub_box{
padding: 11px;
border-radius: 5px;
background-color: #F3F6FD;
width: 545upx;
}
.reply_sub_item{
padding: 2px 0;
}
.reply_sub_item_nick,.reply_sub_item_content{
color: #333;
font-size: 13px;
line-height: 18px;
}
.reply_sub_item_nick{
position: absolute;/*开启定位*/
background-color: #F3F6FD;/*设置背景色以完全遮盖底部文字*/
font-weight:500;
color: #022454;
}
</style>
实现效果如图:
至此,子评论的展示的效果已经正常
四、使用富文本
除了上述的两种方法外,我们还可以使用rich-text组件,通过富文本的方式来进行实现
在复杂元素节点的场景下,通过富文本来实现不同text效果行内展示是最优解,不仅支持丰富的组并且可指定标签进行点击拦截。但是在简单场景中使用富文本调试工作量较大,所以在本场景中我使用的是绝对定位叠加的方式实现
关于富文本的使用方式可参照文档说明进行开发,详情查看rich-text文档