【uni-app】uni-app实现聊天页面功能(小程序)——布局篇
前言
在工作中使用uni-app参与开发一个小程序,其中要写一个简单的聊天页面,虽然功能不多(只有一个发送文字的功能),但是其中的细节比较多,也踩过很多坑,特此记录下来。要实现的页面如图所示,该篇主要讲讲如何布局(参考了很多文章之后根据页面需求进行一个整合)。
划分区域
先划分大区域,主要包含两个(顶部导航栏用的小程序自带的,所以就没有自己写,后续有需求可能会自定义导航栏)聊天内容区和底部发送框。
其中因为要实现发送内容页面会自动滚到最底部,所以聊天内容区在布局上是采用了scroll-view,必须要给它设置一个基础的高度(这里设置为屏幕的高度),而聊天消息列表的高度是根据内容来撑开。
注意!底部聊天框是采用固定定位固定在页面的底部,它不遵循标准流,当聊天内容充满整个屏幕时,最底部的消息会被聊天框遮挡,为了避免这种情况发生,需要在聊天框外再套一层有固定高度的view来占位。
问题
内容溢出
而实际测试时还发现了一个问题:连续的数字会溢出内容框!
因为连续的数字被浏览器误认为是英文单词,而英文单词在默认情况下是不会分开换行的,解决方案是在css内容框中加入如下代码(二选一即可):
//写法一
word-wrap: break-word;
//写法二
word-break: break-all;
这样就解决了!
关于调试聊天框
小程序模拟器和真机上在聊天框中会略微有点差别!!!
(我设置了padding,模拟器上文字是贴着,但真机上文字居中)
模拟器:
真机:
代码实现
下面是整个页面的完整代码(已更新):
<template>
<view class="chat">
<scroll-view :style="{height: `${windowHeight}rpx`}"
id="scrollview"
scroll-y="true"
:scroll-top="scrollTop"
:scroll-with-animation="true"
class="scroll-view"
>
<!-- 聊天主体 -->
<view id="msglistview" class="chat-body">
<!-- 聊天记录 -->
<view v-for="(item,index) in msgList" :key="index">
<!-- 自己发的消息 -->
<view class="item self" v-if="item.userContent != ''" >
<!-- 文字内容 -->
<view class="content right">
{{item.userContent}}
</view>
<!-- 头像 -->
<view class="avatar">
</view>
</view>
<!-- 机器人发的消息 -->
<view class="item Ai" v-if="item.botContent != ''">
<!-- 头像 -->
<view class="avatar">
</view>
<!-- 文字内容 -->
<view class="content left">
{{item.botContent}}
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 底部消息发送栏 -->
<!-- 用来占位,防止聊天消息被发送框遮挡 -->
<view class="chat-bottom">
<view class="send-msg">
<view class="uni-textarea">
<textarea v-model="chatMsg"
maxlength="300"
:show-confirm-bar="false"
auto-height></textarea>
</view>
<button @click="handleSend" class="send-btn">发送</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
//滚动距离
scrollTop: 0,
userId:'',
//发送的消息
chatMsg:"",
msgList:[
{
botContent: "hello,请问我有什么可以帮助你的吗?",
recordId: 0,
titleId: 0,
userContent: "",
userId: 0
},
{
botContent: "",
recordId: 0,
titleId: 0,
userContent: "你好呀我想问你一件事",
userId: 0
},
]
}
},
computed: {
windowHeight() {
return this.rpxTopx(uni.getSystemInfoSync().windowHeight)
}
},
methods: {
// px转换成rpx
rpxTopx(px){
let deviceWidth = wx.getSystemInfoSync().windowWidth
let rpx = ( 750 / deviceWidth ) * Number(px)
return Math.floor(rpx)
},
// 发送消息
handleSend() {
//如果消息不为空
if(!this.chatMsg||!/^s+$/.test(this.chatMsg)){
let obj = {
botContent: "",
recordId: 0,
titleId: 0,
userContent: this.chatMsg,
userId: 0
}
this.msgList.push(obj);
this.chatMsg = '';
}else {
this.$modal.showToast('不能发送空白消息')
}
},
}
}
</script>
<style lang="scss" scoped>
$chatContentbgc: #C2DCFF;
$sendBtnbgc: #4F7DF5;
view,button,text,input,textarea {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 聊天消息 */
.chat {
.scroll-view {
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
color: transparent;
}
// background-color: orange;
background-color: #F6F6F6;
.chat-body {
display: flex;
flex-direction: column;
padding-top: 23rpx;
// background-color:skyblue;
.self {
justify-content: flex-end;
}
.item {
display: flex;
padding: 23rpx 30rpx;
// background-color: greenyellow;
.right {
background-color: $chatContentbgc;
}
.left {
background-color: #FFFFFF;
}
// 聊天消息的三角形
.right::after {
position: absolute;
display: inline-block;
content: '';
width: 0;
height: 0;
left: 100%;
top: 10px;
border: 12rpx solid transparent;
border-left: 12rpx solid $chatContentbgc;
}
.left::after {
position: absolute;
display: inline-block;
content: '';
width: 0;
height: 0;
top: 10px;
right: 100%;
border: 12rpx solid transparent;
border-right: 12rpx solid #FFFFFF;
}
.content {
position: relative;
max-width: 486rpx;
border-radius: 8rpx;
word-wrap: break-word;
padding: 24rpx 24rpx;
margin: 0 24rpx;
border-radius: 5px;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
color: #333333;
line-height: 42rpx;
}
.avatar {
display: flex;
justify-content: center;
width: 78rpx;
height: 78rpx;
background: $sendBtnbgc;
border-radius: 8rpx;
overflow: hidden;
image {
align-self: center;
}
}
}
}
}
/* 底部聊天发送栏 */
.chat-bottom {
width: 100%;
height: 177rpx;
background: #F4F5F7;
.send-msg {
display: flex;
align-items: flex-end;
padding: 16rpx 30rpx;
width: 100%;
min-height: 177rpx;
position: fixed;
bottom: 0;
background: #EDEDED;
}
.uni-textarea {
padding-bottom: 70rpx;
textarea {
width: 537rpx;
min-height: 75rpx;
max-height: 500rpx;
background: #FFFFFF;
border-radius: 8rpx;
font-size: 32rpx;
font-family: PingFang SC;
color: #333333;
line-height: 43rpx;
padding: 5rpx 8rpx;
}
}
.send-btn {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 70rpx;
margin-left: 25rpx;
width: 128rpx;
height: 75rpx;
background: $sendBtnbgc;
border-radius: 8rpx;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #FFFFFF;
line-height: 28rpx;
}
}
}
</style>
具体功能实现将放在下篇(可能一篇讲不完),有任何问题可以评论留言~