最近想做一个与AI对话的一个聊天界面,uni-app 参考页面如下:
<!-- 聊天主体 -->
<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>
<!-- 头像 -->
<image class="avatar" :src="item.image">
</image>
</view>
<!-- 机器人发的消息 -->
<view class="item Ai" v-if="item.botContent != ''">
<!-- 头像 -->
<image class="avatar" :src="item.image">
</image>
<!-- 文字内容 -->
<view class="content left">
{{item.botContent}}
</view>
</view>
</view>
</view>
这个也是参考别人的,作者我真的找不到了,有问题联系我!
然后聊天数据它是这么存的
msgList:[
{
botContent: "你好啊,很高兴你可以关注我,请问我有什么可以帮助你的吗?",
userContent: "",
image:"/static/avatar/robot.jpg"
},
{
botContent: "",
userContent: "你好呀,非常高兴认识你",
image:"/static/avatar/user.jpg"
},
]
- botContent:AI的信息
- userContent:用户的输入信息
- image:双方的头像
显示的判断条件就是判断不为空串则为己方信息,通过不断对msgList使用push方法来实现聊天信息显示与交互。
let msg = "这是机器人的回复内容";
let obs={
botContent: msg,
userContent: "",
image:"/static/avatar/robot.jpg"
}
this.msgList.push(obj);//此时的puth是我们封装的部分
要求——问题是AI回复的这段话不是逐字显示的,效果如下:
思路:
1.确定效果文字要更新的数组元素:取出消息队列元素长度(1开始),这是下一个要添加的对象索引。
2.插入一个空的消息对象到消息队列
3.索引消息队列的对这个空的消息对象,对它的botContent进行追加,思路是通过字符串的滑动窗口不断更新字符索引与消息队列中botContent进行字符拼接,实现文字逐一出现的效果,
此外,charAt()方法返回字符串给定索引位置的字符。
// 发送消息
handleSend() {
//如果消息不为空
if(!this.chatMsg || !/^\s+$/.test(this.chatMsg)){
// 用户的消息显示
let userMsgObj = {
botContent: "",
userContent: this.chatMsg,
image: "/static/avatar/user.jpg"
};
this.msgList.push(userMsgObj);
this.chatMsg = '';
this.scrollToBottom();
// 机器人的回复内容
let msg = "这是一段固定回复内容,为了检测是否可以实现机器人回复文字逐一出现";
let botMsgObj = {
botContent: "", // 初始为空
userContent: "",
image: "/static/avatar/robot.jpg"
};
// 1. 获取新消息应该插入的索引位置
let msgListIndex = this.msgList.length;
// 2.添加空botContent到消息列表
this.msgList.push(botMsgObj);
// 3. 使用setTimeout实现逐字效果
let currentIndex = 0; // 初始化当前字符索引
const typeInterval = setInterval(() => {
if (currentIndex < msg.length) {
// 逐字追加到botContent
this.msgList[msgListIndex].botContent += msg.charAt(currentIndex);
currentIndex++;
this.scrollToBottom(); // 滚动到底部
} else {
clearInterval(typeInterval); // 停止间隔
}
}, 100);
} else {
this.$modal.showToast('不能发送空白消息');
}
}