本文主要详细介绍vue的web在线聊天功能的实现。本文中的示例代码非常详细,具有一定的参考价值。感兴趣的朋友可以参考一下。
本文分享vue实现web在线聊天的具体代码,供大家参考。具体如下。
最终实现的效果
实现过程
无限卷轴形式的实现之前已经介绍过了,这里不再赘述。不清楚的可以通过文件前面的门户查看。
实时在线聊天主要功能点
滚动到两天表单的顶部,自动加载历史记录和更多信息。数据加载时,需要有加载动画;
发送信息是滚动条自动滑动到表单底部,自己发送的信息出现在聊天表单中;
在接收别人的信息时,需要判断滚动条在表单中的位置,当接收到距底部一定范围内的信息时,需要自动滑动到表单底部;
聊天状态下收发信息不能重复显示;
聊天表单中收发信息要逆序显示,即越靠近表单底部的信息就是最新消息;
最好通过WebSocket与后端建立长连接,后端主动推新消息到前端。这里主要介绍一下前端实现聊天表单的思路,但WebSocket部分就不展开了,简单用定时器轮询实现。
话不多说,直接去码。
后端返回数据格式
我觉得所有的设计和功能实现都是基于数据的,所以我们先来看看后端返回的数据格式:
{
' Code': 200,//响应代码
Msg': 'OK ',//响应消息
'总计':1,
SYSTIME':' 2020-12-16 15: 23: 27 ',//系统响应时间
数据':[{
头像': ',//用户的头像
内容':' { '类型':' txt ',' msg ':'你好!} ',//消息内容
' IsRead': 0,//是否已被读取?
' IsOneself': 0,//消息是您自己发送的吗?0否,1是
' MsgId': 10,//消息Id,用于重复数据删除
昵称':'蓝海燕鱼',//用户昵称
用户代码':' 202012162030202232 '//用户代码
}]
}
这里需要注意的是,内容字段返回的是json格式的字符串数据,内容内容格式如下:
//文本消息
{
键入':' txt ',
msg ':' Hello '//消息内容
}
//图片消息
{
类型':' img ',
Url ':'图片地址',
ext':'jpg ',
' Width':360,//宽
' Height':480,//高
'尺寸':388245
}
//视频消息
{
键入':'视频',
URL ':' http://nim test . nos . Netease . com/CBC 500 e 8-e19c-4b0f-834 b-c 32d 4d c 1075 e ',
ext':'mp4 ',
' Width':360,//宽
' Height':480,//高
'尺寸':388245
}
//地理位置消息
{
类型':'本地',
地址':'中国浙江杭州王上路599号',//地点
'经度':120,//经度
'纬度':30//纬度
}
HTML代码
模板
Modal title='在线交流' v-model='chatVisible '
可拖动的
页脚-隐藏
:width='580' @on-cancel='cancel '
div class='聊天'
div class=' chat-message-body ' id=' chat form ' @ scroll=' scroll '
自旋v-if='加载'
Icon type=' IOs-loading ' size=18 class=' spin-Icon-load '/Icon
/旋转
div dis-hover v-for='(item,index) in data '
:key='index' class='message-card '
div :class='item.isOneself==1?'“消息-行-右”:“消息-行-左”
img :src='item.avatar?' item . avatar:defaltavatar '
高度='35 '宽度='35 '
div class='消息内容'
div :style='item.isOneself==1?'文本对齐:右对齐;显示器:flex伸缩方向:行-反向':'''
{{item.nickName}}
span class='消息时间'
{{item.createTime}}/span
/div
div class='消息正文'
{{item.content.msg}}
/div
/div
/div
/div
/div
投入
v-model='form.msg '
type='textarea '
style=' margin:10px 0;'
占位符='主动一点,世界会更大!'
:rows='4 '
/
/div
div class='footer-btn '
button @ click=' cancel ' type=' text '取消/按钮
按钮类型='primary' @click='sendMsg '发送/按钮
/div
/Modal
/模板
注:自己发的信息和别人发的信息展示样式不一样,所以需要通过isOneself字段进行展示样式的区分。
Java脚本语言代码
脚本
从" @/api/index "导入{listMsg,send msg };
导出默认值{
姓名:"聊天",
道具:{
值:{
类型:布尔型,
默认值:错误
}
},
data() {
返回{
chatVisible:this.value,
加载:假,
defualtAvatar:要求('././资产/默认-头像。SVG '),//后端没有返回头像默认头像,注意:需要用需要请求方式才能动态访问本地文件
数据:[],
非重复数据:[],//消息去重数组
offsetMax:0,//最大偏移位,记录当前获取的最大id,往后的定时轮询数据时每次只获取比这个身份证明(识别)大的数据
offsetMin:0,//最小偏移位,记录当前获取的最小id,往上滑动时每次只获取比这小身份证明(识别)大的数据
搜索表单:{ //每次定时获取数据或首次加载数据提交的形式表单数据
页码:1,
页面大小:20
},
形式:{ //发送数据提交数据表单
内容:'',
邮件:""
},
定时器开关:0 //定时器开关,默认关闭
};
},
方法:{
init(){
},
loadMsg(){ //窗体打开默认加载一页数据,窗体什么周期中值运行一次
让那个=这个;
这个。搜索表单。最大偏移=这个。最大偏移量;
listMsg(this.searchForm).然后(res={
if (res.code==200) {
res.data.forEach(e={
//标记最大偏移位
if(that.offsetMax e.msgId){
那个。offset max=e . msgid
}
e。内容=JSON。解析(例如内容);
that.data.unshift(e)
那个。独特的数据。push(e . msgid);
//标记最大偏移位,后端返回数据是逆序,所以最后一条身份证明(识别)最新
那个。offset min=e . msgid
});
//数据加载完成,滚动条滚动到窗体底部
这个。scrolltobottom();
}
});
},
show(){ //打开窗体初始化数据
//初始化数据
这个。数据=[];
这个。非重复数据=[];
这个。偏移最大值=0;
这个。偏移最小值=0;
这个。搜索表单。页码=1;
这个。搜索表单。pagesize=20
this.form={
内容:'',
邮件:""
};
这个。loadmsg();
this.chatVisible=true
//开启定时器
这个。定时器开关=1;
这个。reload data();
},
sendMsg(){ //发送消息
如果(!this.form.msg){
这个Message.warning('不能发送空白信息');
返回;
}
let content={ //封装消息体
类型:' txt ',
msg:this.form.msg
};
这个。形式。内容=JSON。stringify(内容);
sendordemsg(这个。表单).然后(res={
if (res.code==200) {
研究数据。内容=JSON。解析(解析数据。内容);
这个. data.push(资源数据)
这个。形式。msg=
这个。distincdata。推送(参考数据。msgid);
这个。scrolltobottom();
//发送信息只返回当前一条,此时可能对方已经发送信息,所以不修改偏移量
}
});
},
scrollToBottom(){ //滚动到窗体底部
这个. nextTick(()={
让聊天表单=文档。getelementbyid('聊天表单');
聊天表单。顶部滚动=聊天表格。滚动高度;
});
},
//滚动到最上方,取历史数据,根据分页参数取。不用修改偏移标记位,但是需要判重
滚动(){
让聊天表单=文档。getelementbyid('聊天表单');
let scroll top=聊天表单。滚动顶部;
if(scrollTop==0){
this.loading=true
让那个=这个;
这个。搜索表单。偏移最小值=这一点。偏移最小值;
这个。搜索表单。偏移最大值=" ";
listMsgByOrder(this.searchForm).然后(res={
this.loading=false
if (res.code==200) {
res.data.forEach(e={
如果(那个。distincdata。索引(e . msgid)0){
e。内容=JSON。解析(例如内容);
那个。数据。un shift(e);
那个。独特的数据。push(e . msgid);
//修改最小偏移位
if(that.offsetMin e.msgId){
那个。offset min=e . msgid
}
}
});
}
});
}
},
reloadData(){
//判断定时器开关是否开启,如果开启,则执行定时器
if(this.timerSwitch){
setTimeout(()={
设params={ };
参数。页码=1;
params.pageSize=20
参数。最大偏移=这个。最大偏移量;
让那个=这个;
listMsgByOrder(params).然后(res={
if (res.code==200) {
res.data.forEach(e={
//修改最大偏移位,放到校验重复之前,防止当前发送信息已经放入消息列表,但是偏移值没该的情况
if(that.offsetMax e.msgId){
那个。offset max=e . msgid
}
如果(那个。distincdata。索引(e . msgid)0){
e。内容=JSON。解析(例如内容);
那个。数据。推送(五)
那个。独特的数据。push(e . msgid);
//收到新消息,判断高度,如果当前滚动条高度距底部小于100,则动滑到底部
让聊天表单=文档。getelementbyid('聊天表单');
让gap=聊天形式。滚动高度-聊天表单。滚动顶部;
如果(间隙0间隙400){
这个。scrolltobottom();
}
}
});
那个。reload data();
}
});
},1000*2);
}
},
cancel(){ //关闭窗体需要把提示任务开关一起关闭调
this.chatVisible=false
这个。定时器开关=0;
}
},
已安装(){
}
};
/脚本
半铸钢钢性铸铁(铸造半钢)代码
style lang='less '。消息{
高度:350像素
}。ivu-卡-主体{
填充:5px
}。ivu-模态-车身{
填充:0px 16px 16px 16px
}。聊天消息正文{
背景色:# F8F8F6
宽度:545像素
高度:350像素
溢出:自动;
}。留言卡{
保证金:5px
}。消息-行-左侧{
显示器:flex
弯曲方向:行;
}。消息-行-右侧{
显示器:flex
弹性-方向:行-反向;
}。消息内容{
边距:-5px 5px 5px 5px;
显示器:flex
伸缩方向:列;
}。消息正文{
边框:1px纯色# D9DAD9
填充:5px
边框半径:3px
背景色:# FFF;
}。消息时间{
保证金:0 5px
字体大小:5px
颜色:# D9DAD9
}。页脚-btn {
浮动:对;
边距-底部:5px
}。旋转图标加载{
动画:ani-自旋1s线性无限;
}
@关键帧自动旋转{
form { transform:rotate(0度);}
50% {变换:旋转(180度);}
要{转换:旋转(360度);}
}
/风格
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。