【uni-app】uni-app实现聊天页面功能——功能篇(下)

article/2025/9/22 7:01:56

目录

    • 前言
    • 一、聊天框随键盘抬起
      • 思路
      • 代码实现
    • 二、聊天消息列表随着聊天框的增高而滚动到最底部
      • 思路
    • 三、问题
    • 完整代码实现
    • 总结

前言

前面我有写关于如何进行聊天页面布局和实现聊天消息滚动到最底部的文章。

【uni-app】uni-app实现聊天页面功能——功能篇(上)

【uni-app】uni-app实现聊天页面功能(小程序)——布局篇

这篇文章是基于这两篇的基础上完善的。

主要还是实现以下两个功能:

  1. 点击聊天框的时候,聊天框随键盘抬起且聊天消息列表滚动到最底部,但整体页面不抬起

  2. 聊天框textarea根据内容自适应高度,且聊天消息列表随着聊天框的增高而滚动到最底部(说白了就是最底部的消息不会被增高的聊天框给挡住)

在这里插入图片描述

一、聊天框随键盘抬起

uni-app官方文档中其实有给出关于这个的解决方案,只用设置一个属性。

textarea | uni-app官网 (dcloud.net.cn)

textarea的属性:

adjust-position —— 键盘抬起时,是否自动上推页面(默认值为true)

cursor-spacing —— 指定光标与键盘的距离,单位px(就是设置键盘与输入框的距离,默认值为0)

<textarea cursor-spacing = "60"></textarea>

虽然这种方法简单,但是有一个不好的地方是:页面整体会上移

在这里插入图片描述

如果想让聊天框随键盘抬起的同时不想让页面上移,可以参考下面这个方法。

思路

首先我们需要在键盘抬起的时候获取到键盘的高度,然后给聊天框动态设置合适的bottom值(键盘的高度),最后给textarea的属性adjust-position设置为false。

至于在点击聊天框的时候聊天消息定位到最底部(不会被遮挡)我将放到第二个板块去讲!!!


获取键盘高度采用官方给出的api(最快且稳定的)实现:uni.hideKeyboard() | uni-app官网 (dcloud.net.cn)

我们在页面加载时设置uni.onKeyboardHeightChange监听事件去获取到键盘高度,在页面卸载时使用uni.offKeyboardHeightChange解除监听键盘高度事件。

代码实现

视图部分(简写):

<template><view class="chat"><scroll-view :style="{height: `${windowHeight-keyboardHeight}rpx`}"id="scrollview"scroll-y="true" :scroll-top="scrollTop":scroll-with-animation="true"class="scroll-view"><view id="msglistview" class="chat-body">...</view></scroll-view><!-- 底部消息发送栏 --><view class="chat-bottom"><view class="send-msg" :style="{bottom:`${keyboardHeight}rpx`}"><view class="uni-textarea"><textarea v-model="chatMsg"maxlength="300"confirm-type="send":adjust-position="false":show-confirm-bar="false"auto-height ></textarea></view><button @click="handleSend" class="send-btn">发送</button></view></view></view>
</template>

js部分:

data(){return{//键盘高度keyboardHeight:0,// 聊天框距离底部的高度bottomHeight: 0,}
},	
onLoad(){uni.onKeyboardHeightChange(res => {//这里正常来讲代码直接写//this.keyboardHeight=this.rpxTopx(res.height)就行了//但是之前界面ui设计聊天框的高度有点高,为了不让键盘和聊天输入框之间距离差太大所以我改动了一下。this.keyboardHeight = this.rpxTopx(res.height-60)if(this.keyboardHeight<0)this.keyboardHeight = 0;})
},
onUnload(){uni.offKeyboardHeightChange()//如果不传入监听的对象,则移除所有监听函数
}

二、聊天消息列表随着聊天框的增高而滚动到最底部

需求:

点击聊天框,聊天消息定位到最底部。聊天框textarea根据内容自适应高度(已实现),且聊天消息列表随着聊天框的增高而滚动到最底部(说白了就是最底部的消息不会被增高的聊天框给挡住)

思路

因为点击聊天框的时候,键盘抬起,所以此时的内容可视区高度应该是:屏幕高度-(聊天框高度+键盘高度),所以将这个高度赋值给聊天滚动区,同时页面更新时再调用聊天滚动到底部的函数就实现了

聊天框的高度我们可以用boundingClientRect获取到,然后在textarea的行数发生变化的时候(@linechange)调用获取聊天框高度的函数。

还有个小细节就是,套在聊天框最外层的view也要跟随着聊天框改高度,然后颜色也要设置成跟界面背景色一样,这样当聊天框弹起来的时候就不会闪出一个白板。

三、问题

设置scroll-view中的scroll-with-animation为true时,聊天发送消息会有一个过渡的动画效果。由于有动画时长,消息的发送会有一定的延时,这个动画的时长比我们设置的消息滚动到底部scrollToBottom函数的延时要长(也就是说,动画还未完成,就执行滚动到底部的函数,这只是我的个人猜想)。这样会导致发送的聊天消息比较长时(聊天消息只有一行的时候没影响),发送出去的消息会有一个回弹,页面不能滚到最底部(不能完整显示出聊天消息)。
在这里插入图片描述

解决方案
把动画效果删了,不加scroll-with-animation
(如果有更好的解决办法也可以告诉我!)

完整代码实现

整个页面完整代码:

<template><view class="chat"><scroll-view  :style="{height: `${windowHeight-inputHeight}rpx`}"id="scrollview"scroll-y="true" :scroll-top="scrollTop"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" :style="{height: `${inputHeight}rpx`}"><view class="send-msg" :style="{bottom:`${keyboardHeight}rpx`}"><view class="uni-textarea"><textarea v-model="chatMsg"maxlength="300"confirm-type="send"@confirm="handleSend":show-confirm-bar="false":adjust-position="false"@linechange="sendHeight"@focus="focus" @blur="blur"auto-height></textarea></view><button @click="handleSend" class="send-btn">发送</button></view></view></view>
</template>
<script>export default {data() {return {//键盘高度keyboardHeight:0,//底部消息发送高度bottomHeight: 0,//滚动距离scrollTop: 0,userId:'',//发送的消息chatMsg:"",msgList:[{botContent: "hello,请问我有什么可以帮助你的吗?",recordId: 0,titleId: 0,userContent: "",userId: 0},{botContent: "",recordId: 0,titleId: 0,userContent: "你好呀我想问你一件事",userId: 0},]	}},updated(){//页面更新时调用聊天消息定位到最底部this.scrollToBottom();},computed: {windowHeight() {return this.rpxTopx(uni.getSystemInfoSync().windowHeight)},// 键盘弹起来的高度+发送框高度inputHeight(){return this.bottomHeight+this.keyboardHeight}},onLoad(){uni.onKeyboardHeightChange(res => {//这里正常来讲代码直接写//this.keyboardHeight=this.rpxTopx(res.height)就行了//但是之前界面ui设计聊天框的高度有点高,为了不让键盘和聊天输入框之间距离差太大所以我改动了一下。this.keyboardHeight = this.rpxTopx(res.height-30)if(this.keyboardHeight<0)this.keyboardHeight = 0;})},onUnload(){uni.offKeyboardHeightChange()},methods: {focus(){this.scrollToBottom()},blur(){this.scrollToBottom()},// px转换成rpxrpxTopx(px){let deviceWidth = wx.getSystemInfoSync().windowWidthlet rpx = ( 750 / deviceWidth ) * Number(px)return Math.floor(rpx)},// 监视聊天发送栏高度sendHeight(){setTimeout(()=>{let query = uni.createSelectorQuery();query.select('.send-msg').boundingClientRect()query.exec(res =>{this.bottomHeight = this.rpxTopx(res[0].height)})},10)},// 滚动至聊天底部scrollToBottom(e){setTimeout(()=>{let query = uni.createSelectorQuery().in(this);query.select('#scrollview').boundingClientRect();query.select('#msglistview').boundingClientRect();query.exec((res) =>{if(res[1].height > res[0].height){this.scrollTop = this.rpxTopx(res[1].height - res[0].height)}})},15)},// 发送消息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 = '';this.scrollToBottom()}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;transition: all 0.1s ease;.send-msg {display: flex;align-items: flex-end;padding: 16rpx 30rpx;width: 100%;min-height: 177rpx;position: fixed;bottom: 0;background: #EDEDED;transition: all 0.1s ease;}.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>

总结

聊天界面差不多就这样完结了!很多功能都是边做边想到的,主要是实现更好的交互体验!有问题欢迎来评论区留言噢~


http://chatgpt.dhexx.cn/article/XTtAaNWN.shtml

相关文章

如何将 WhatsApp 聊天添加到您的网站

WhatsApp是全球最受欢迎的消息传递应用程序。平台上有超过 2 亿活跃用户与朋友、家人和企业进行交流。对于企业而言&#xff0c;WhatsApp 是与客户进行个人、可访问和非正式对话的理想渠道。 要将 WhatsApp 作为渠道引入您的客户旅程&#xff0c;第一步是将 WhatsApp 聊天按钮…

uni-app 即时聊天

项目介绍 前段时间在B站看到了有一个UP主在讲uni-app即时聊天的项目&#xff08;逸刻时光&#xff09;&#xff0c;在看了这个视频之后&#xff0c;感觉还是挺有兴趣的&#xff0c;所以在看他的讲解视频之后&#xff0c;就自己动手写了这个即时聊天项目&#xff0c;在样式方面…

uniapp+nvue实现仿微信App聊天应用 —— 成功实现好友聊天+语音视频通话功能

基于uniapp nvue实现的uniapp仿微信App聊天应用 txim 实例项目&#xff0c;实现了以下功能。 1: 聊天会话管理 2: 好友列表 3: 文字、语音、视频、表情、位置等聊天消息收发 4: 一对一语音视频在线通话 技术实现 开发环境&#xff1a;HbuilderX nodejs技术框架&#xff…

WhatsApp聊天记录迁移新手机,备份如何找回和删除?

当外贸人更换手机时&#xff0c;面临的第一大问题就是WhatsApp数据迁移的问题。 因为WhatsApp的聊天记录、联系人、图片、视频等&#xff0c;都是与客户息息相关的数据&#xff0c;对外贸人来讲都非常重要&#xff0c;所以一定要确保在换手机过程中不丢失WhatsApp的任何资料。…

[uni-app]聊天App实例

项目简介 基于uni-appvuevuexuniPopswiper等技术开发的仿微信聊天室uniapp-chatroom项目&#xff0c;类似vue及小程序api语法使开发更加方便&#xff0c;实现了发送图文消息、表情(gif动图)&#xff0c;图片预览、地图位置、红包、仿微信朋友圈等功能 效果图 在H5 / 小程序 …

开发社交聊天APP需要注意什么?如何快速开发聊天功能

随着互联网的发展&#xff0c;人们的沟通方式也在悄悄发生变化&#xff0c;由原来的面对面沟通&#xff0c;发展为网上沟通。让大家日常生活的通讯越来越方便了&#xff0c;各种APP层出不穷。那么&#xff0c;想开发一款社交聊天并进行运营&#xff0c;需要注意哪些方面&#x…

比较好用的聊天交友软件?最受年轻人欢迎的APP在这

现在都有哪些比较火,比较好用的聊天交友软件?移动社交是一件越来越普遍的事情&#xff0c;人们可以通过互联网&#xff0c;在社交软件上认识众多的一样的有趣人群&#xff0c;在国内都有哪些**的交友app哪个好??在中国在中国最受年轻人欢迎的APP又有哪些呢? 微信 微信可以…

程序员的时钟/原生抖音罗盘时钟代码分享/ 罗盘文字时钟软件非常火 /文字时钟

原生抖音罗盘时钟代码分享 罗盘文字时钟软件非常火 文字时钟 本站给大家分享这款就是通过原生j来s实现的文字时钟源码&#xff0c;有喜欢的朋友可以下载哦&#xff0c;无需安装&#xff0c;上传访问即可使用 简单实现&#xff1a;https://sucaiip.com/time-302.html

Android实现模拟时钟(简单+漂亮)--时针、分针、秒针

前言 前不久在网上看见Android实现的模拟时钟&#xff0c;感觉十分有意思&#xff0c;这里是地址&#xff1a; http://www.eoeandroid.com/forum.php?modviewthread&tid58324可惜的是这种方式没有 秒表。笔者突然对其有了兴趣&#xff0c;也想去实现以下自己的模拟时钟。折…

网页电子时钟

如图就是一个简易的网页电子时钟&#xff0c;利用Javascript和 html和 css就可以制作 <div class"wrapper"><div class"time-box"><div class"hour"></div><div class"sec"></div></div>&…

时钟啊时钟

效果图 JS /*** color --color 父级定义颜色 css直接使用变量*/ import { useState, useEffect } from react; import styles from ./style.less const index () > {const [time, setTime] useState({hours: 00,minutes: 00,seconds: 00})useEffect(() >{countDown() …

模拟钟表的手机软件_手机时钟软件推荐

下载 生活服务|47.3MB 更新时间&#xff1a;2019-04-04 12:04:18 评分&#xff1a;7 概要&#xff1a;抖音文字云时钟app是一款异常火爆的数字时钟软件&#xff0c;该软件在抖音上已经被众多小伙伴种草了&#xff0c;它拥有非常炫酷的背景&#xff0c;设置安装起来也非常简便&a…

抖音文字时钟壁纸html,抖音文字时钟

抖音文字时钟是一款为最近非常火的珍惜时间打造的钟表&#xff0c;有记录时间的功能也有很强大的警示作用&#xff0c;告诉我们时间的重要性&#xff0c;它有很多的模式可以调节使用&#xff0c;展现出自己喜欢的需要的时钟模式来&#xff0c;有需要的用户们就来这里下载吧。 温…

实现时钟特效

需求&#xff1a; 显示年、月、日、星期和二十四进制的时钟特效&#xff01; 代码&#xff1a; <!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title>时钟特效</title><style> body{backgrou…

超级实用的动态时钟。

绘制时钟 时钟动态效果的实现基于canvas画布的重绘&#xff0c;也就是说每秒都要在canvas画布上重新绘画一遍图形&#xff0c;在配合定时器即可实现动态效果。而实现此时钟主要有两个步骤&#xff0c;1是表盘的绘制&#xff0c;2是指针的绘制。 绘制时钟表盘 时钟表盘的刻度…

教你制作 简易罗盘动态时钟 网页文件

简易罗盘动态时钟&#xff08;含html文件和源码&#xff09; 快来获取 首先给大家展示成品截图 首选展示index.txt代码 <动态罗盘时钟> <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"v…

用前端代码编写一个动态的罗盘时钟

用前端代码编写一个动态的罗盘时钟 前言一、代码如下1.index2.js3.css 页面效果 前言 今天给大家分享一个罗盘时钟的前端代码&#xff0c;喜欢的小伙伴帮忙点赞一下噢&#xff01; 一、代码如下 1.index <!DOCTYPE html> <html lang"en"> <head>…

android时钟字体,文字时钟下载-文字时钟 安卓版v1.6.1-PC6安卓网

文字时钟屏保app是一款功能齐全又实用的时钟显示软件&#xff0c;文字时钟屏保app主界面是一个自带时间、日期、天气的LED数字时钟和模拟时钟&#xff0c;全屏显示翻页时钟&#xff0c;酷炫美观又实用。这款文字时钟屏保app可以一直保持显示状态。 软件介绍 文字时钟屏保app是一…

日历与时钟

目录 公历 黑色星期五 生物韵律 公历 在公历中&#xff0c;当年份为4的整数倍&#xff0c;但不是100的整数倍时&#xff0c;会出现闰年的现象。 y40 mod(y,4) 0 && mod(y,100)||mod(y,400)0 输出当时的年、月、日、时、分、秒 f%6d %6d %6d %6d %6d %9.3f\n cclock …

手机时钟软件推荐,创意时钟APP介绍

手机上有好用的时钟APP&#xff0c;时钟软件哪个好用? 每个人的手机屏幕都有着自己独特的设计&#xff0c;而时钟软件能够为用户的手机再增添一些风采和魅力&#xff0c;更有专为来年人设计的大字体桌面时钟&#xff0c;更加的清晰直观&#xff0c;各种特色的桌面时钟app中都有…