使用vue怎样写一个web在线聊天的功能?
Admin 2021-09-15 群英技术资讯 1313 次浏览
今天给大家分享的是使用vue写一个web在线聊天的功能,这一需求在做网站在线客服的时候常会遇到,而想要实现实时在线聊天,对于主要的功能点是需要了解清楚的,感兴趣的朋友接下来就跟随小编一起了解看看吧。

无限滚动窗体的实现之前已经介绍过,这里就不在赘述了,不清楚的可以通过文档前文的传送门进行查看。
话不多说,直接上代码
我觉得所有的设计和功能实现都是基于数据的基础上去实现的,所以咋们先来看一下后端返回的数据格式:
{
"code": 200, // 响应编码
"msg": "OK", // 响应消息
"total": 1,
"sysTime": "2020-12-16 15:23:27", // 系统响应时间
"data": [{
"avatar": "", // 用户头像
"content": "{\"type\":\"txt\",\"msg\":\"你好!\"}", // 消息内容
"isRead": 0, // 是否已读
"isOneself": 0, // 是否是自己发送的消息 0否,1是
"msgId": 10, // 消息ID,用来去重
"nickName": "碧海燕鱼", // 用户昵称
"userCode": "202012162030202232" // 用户编码
}]
}
这里需要说明的是,content字段返回的是一个json格式的字符串数据,content内容格式如下:
// 文本消息
{
"type": "txt",
"msg":"你好" //消息内容
}
// 图片消息
{
"type": "img",
"url": "图片地址",
"ext":"jpg",
"width":360, //宽
"height":480, //高
"size": 388245
}
// 视频消息
{
"type": 'video',
"url": "http://nimtest.nos.netease.com/cbc500e8-e19c-4b0f-834b-c32d4dc1075e",
"ext":"mp4",
"width":360, //宽
"height":480, //高
"size": 388245
}
// 地理位置消息
{
"type": "local",
"address":"中国 浙江省 杭州市 网商路 599号", //地理位置
"longitude":120.1908686708565, // 经度
"latitude":30.18704515647036 // 纬度
}
HTML代码
<template>
<Modal title="在线沟通" v-model="chatVisible"
draggable
footer-hide
:width="580" @on-cancel="cancel">
<div class="chat">
<div class="chat-message-body" id ="chatform" @scroll="scroll"
>
<Spin v-if="loading">
<Icon type="ios-loading" size=18 class="spin-icon-load"></Icon>
</Spin>
<div dis-hover v-for="(item,index) in data"
:key="index" class="message-card">
<div :class="item.isOneself == 1?'message-row-right': 'message-row-left'">
<img :src="item.avatar?item.avatar:defualtAvatar"
height="35" width="35" >
<div class="message-content">
<div :style="item.isOneself == 1?'text-align:right;display: flex;flex-direction:row-reverse':''">
{{item.nickName}}
<span class="message-time">
{{item.createTime}}</span>
</div>
<div class="message-body">
{{item.content.msg}}
</div>
</div>
</div>
</div>
</div>
<Input
v-model="form.msg"
type="textarea"
style="margin:10px 0;"
placeholder="主动一点,世界会更大!"
:rows="4"
/>
</div>
<div class="footer-btn">
<Button @click="cancel" type="text">取消</Button>
<Button type="primary" @click="sendMsg">发送</Button>
</div>
</Modal>
</template>
注:自己发的信息和别人发的信息展示样式不一样,所以需要通过isOneself字段进行展示样式的区分。
JavaScript代码
<script>
import {listMsg,sendMsg } from "@/api/index";
export default {
name: "chat",
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
chatVisible:this.value,
loading:false,
defualtAvatar:require('../../assets/defult-avatar.svg'), // 后端没有返回头像默认头像,注意:需要用require请求方式才能动态访问本地文件
data:[],
distincData:[], // 消息去重数组
offsetMax:0, // 最大偏移位,记录当前获取的最大id,往后的定时轮询数据时每次只获取比这个id大的数据
offsetMin:0, // 最小偏移位,记录当前获取的最小id,往上滑动时每次只获取比这小id大的数据
searchForm:{ // 每次定时获取数据或首次加载数据提交的form表单数据
pageNumber: 1,
pageSize: 20
},
form:{ // 发送数据提交数据表单
content:"",
msg:""
},
timerSwitch:0 // 定时器开关,默认关闭
};
},
methods: {
init(){
},
loadMsg(){ // 窗体打开默认加载一页数据,窗体什么周期中值运行一次
let that = this;
this.searchForm.offsetMax = this.offsetMax;
listMsg(this.searchForm).then(res=>{
if (res.code == 200) {
res.data.forEach(e => {
// 标记最大偏移位
if(that.offsetMax < e.msgId){
that.offsetMax = e.msgId;
}
e.content = JSON.parse(e.content);
that.data.unshift(e)
that.distincData.push(e.msgId);
// 标记最大偏移位,后端返回数据是逆序,所以最后一条id最新
that.offsetMin = e.msgId;
});
// 数据加载完成,滚动条滚动到窗体底部
this.scrollToBottom();
}
});
},
show(){ // 打开窗体初始化数据
// 初始化数据
this.data =[];
this.distincData =[];
this.offsetMax = 0;
this.offsetMin = 0;
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 20;
this.form ={
content:"",
msg:""
};
this.loadMsg();
this.chatVisible = true;
// 开启定时器
this.timerSwitch = 1;
this.reloadData();
},
sendMsg(){ // 发送消息
if(!this.form.msg){
this.$Message.warning("不能发送空白信息");
return;
}
let content = { // 封装消息体
type:"txt",
msg:this.form.msg
};
this.form.content = JSON.stringify(content);
sendOrderMsg(this.form).then(res=>{
if (res.code == 200) {
res.data.content = JSON.parse(res.data.content);
this.data.push(res.data)
this.form.msg="";
this.distincData.push(res.data.msgId);
this.scrollToBottom();
// 发送信息只返回当前一条,此时可能对方已经发送信息,所以不修改偏移量
}
});
},
scrollToBottom(){ // 滚动到窗体底部
this.$nextTick(()=>{
let chatform = document.getElementById("chatform");
chatform.scrollTop = chatform.scrollHeight;
});
},
// 滚动到最上方,取历史数据,根据分页参数取。不用修改偏移标记位,但是需要判重
scroll(){
let chatform = document.getElementById("chatform");
let scrollTop = chatform.scrollTop;
if(scrollTop == 0){
this.loading =true;
let that = this;
this.searchForm.offsetMin = this.offsetMin;
this.searchForm.offsetMax = "";
listMsgByOrder(this.searchForm).then(res=>{
this.loading =false;
if (res.code == 200) {
res.data.forEach(e => {
if(that.distincData.indexOf(e.msgId) <0){
e.content = JSON.parse(e.content);
that.data.unshift(e);
that.distincData.push(e.msgId);
// 修改最小偏移位
if(that.offsetMin > e.msgId){
that.offsetMin = e.msgId;
}
}
});
}
});
}
},
reloadData(){
// 判断定时器开关是否开启,如果开启,则执行定时器
if(this.timerSwitch){
setTimeout(() => {
let params = {};
params.pageNumber = 1;
params.pageSize = 20;
params.offsetMax = this.offsetMax;
let that = this;
listMsgByOrder(params).then(res=>{
if (res.code == 200) {
res.data.forEach(e => {
// 修改最大偏移位,放到校验重复之前,防止当前发送信息已经放入消息列表,但是偏移值没该的情况
if(that.offsetMax < e.msgId){
that.offsetMax = e.msgId;
}
if(that.distincData.indexOf(e.msgId) <0){
e.content = JSON.parse(e.content);
that.data.push(e)
that.distincData.push(e.msgId);
// 收到新消息,判断高度,如果当前滚动条高度距底部小于100,则动滑到底部
let chatform = document.getElementById("chatform");
let gap = chatform.scrollHeight -chatform.scrollTop;
if(gap >0 && gap < 400){
this.scrollToBottom();
}
}
});
that.reloadData();
}
});
},1000*2);
}
},
cancel(){ // 关闭窗体需要把提示任务开关一起关闭调
this.chatVisible = false;
this.timerSwitch = 0;
}
},
mounted() {
}
};
</script>
CSS代码
<style lang="less">
.message {
height: 350px;
}
.ivu-card-body {
padding:5px;
}
.ivu-modal-body{
padding: 0px 16px 16px 16px;
}
.chat-message-body {
background-color:#F8F8F6;
width:545px;
height: 350px;
overflow: auto;
}
.message-card {
margin:5px;
}
.message-row-left {
display: flex;
flex-direction:row;
}
.message-row-right {
display: flex;
flex-direction:row-reverse;
}
.message-content {
margin:-5px 5px 5px 5px;
display: flex;
flex-direction:column;
}
.message-body {
border:1px solid #D9DAD9;
padding:5px;
border-radius:3px;
background-color:#FFF;
}
.message-time {
margin:0 5px;
font-size:5px;
color:#D9DAD9;
}
.footer-btn {
float:right;
margin-bottom: 5px;
}
.spin-icon-load {
animation:ani-spin 1s linear infinite;
}
@keyframes ani-spin{
form{transform: rotate(0deg);}
50% {transform: rotate(180deg);}
to {transform: rotate(360deg);}
}
</style>
以上就是用vue实现web在线聊天功能的代码,有需要的朋友可以参考,希望对大家学习vue有帮助,想要了解更多实现web在线聊天功能效果的内容,请继续浏览其他相关的文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
Window对象可以用来打开浏览器,调整浏览器的位置、大小等等功能。Window对象可以处理框架和框架之间的关系,通过这种关系在一个框架中处理另一
这篇文章主要为大家详细介绍了JS实现移动端上下滑动一次一屏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
排序算法类型有哪些?排序算法类型有冒泡排序、选择排序、插入排序、希尔排序、堆排序、快速排序、归并排序这些,那么用JavaScript怎样实现这些排序算法呢?感兴趣的有接下来就跟随小编来学习一下吧。
jquery中slow的意思是“缓慢的”,slow属性值用于控制jquery动画效果的动画速度,当参数值设置了“slow”时,元素的动画过程中会缓慢的改变元素的属性,语法为“元素对象.元素动画方法("slow")”。
Javascript动态样式控制方法,有不少朋友对此感兴趣,下面小编给大家整理和分享了相关知识和资料,易于大家学习和理解,有需要的朋友可以借鉴参考,下面我们一起来了解一下吧。
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008