vue实现pc聊天页面(vue实现web在线聊天功能)
类别:编程学习 浏览量:1184
时间:2021-10-23 10:53:32 vue实现pc聊天页面
vue实现web在线聊天功能本文实例为大家分享了vue实现web在线聊天的具体代码,供大家参考,具体内容如下
最终实现的效果
实现过程
无限滚动窗体的实现之前已经介绍过,这里就不在赘述了,不清楚的可以通过文档前文的传送门进行查看。
实时在线聊天主要功能点
- 滚动到两天窗体顶部,自动加载历史跟多信息,数据加载的时候,需要有一个loading动画;
- 发送信息是滚动条自动滑动到窗体底部,并且自己发送的信息出现在聊天窗体中;
- 收到别人发送信息时,需要判断滚动条处于窗体中的位置,在距离底部一定范围内收到信息需要自动滑动到窗体底部;
- 收发的信息在聊天状态不能重复显示;
- 收发的信息在聊天窗体中需要以逆序的方式展示,即离窗体底部越近的信息为最新消息;
- 授信最好通过WebSocket与后端建立长连接,有新消息由后端主动向前端推送消息方式实现,这里主要介绍前端实现聊天窗体思路,WebSocket部分就不展开了,采用定时器轮询的方式简单实现。
话不多说,直接上代码
后端返回数据格式
我觉得所有的设计和功能实现都是基于数据的基础上去实现的,所以咋们先来看一下后端返回的数据格式:
{ "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" alt="vue实现pc聊天页面(vue实现web在线聊天功能)" border="0" />
// 视频消息 { "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"> <li class="chat"> <li class="chat-message-body" id ="chatform" @scroll="scroll" > <Spin v-if="loading"> <Icon type="ios-loading" size=18 class="spin-icon-load"></Icon> </Spin> <li dis-hover v-for="(item,index) in data" :key="index" class="message-card"> <li :class="item.isOneself == 1?'message-row-right': 'message-row-left'"> <img :src="item.avatar?item.avatar:defualtAvatar" height="35" width="35" > <li class="message-content"> <li :style="item.isOneself == 1?'text-align:right;display: flex;flex-direction:row-reverse':''"> {{item.nickName}} <span class="message-time"> {{item.createTime}}</span> </li> <li class="message-body"> {{item.content.msg}} </li> </li> </li> </li> </li> <Input v-model="form.msg" type="textarea" style="margin:10px 0;" placeholder="主动一点,世界会更大!" :rows="4" /> </li> <li class="footer-btn"> <Button @click="cancel" type="text">取消</Button> <Button type="primary" @click="sendMsg">发送</Button> </li> </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.stri.jpg" alt="vue实现pc聊天页面(vue实现web在线聊天功能)" border="0" />
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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。
您可能感兴趣
- springbootvue项目代码(Vue+SpringBoot实现支付宝沙箱支付的示例代码)
- vue虚拟滚动条(vue轻松实现虚拟滚动的示例代码)
- vue-cli请求数据的方式(vue-cli配置使用Vuex的全过程记录)
- vue用手动上传图片(vue上传图片文件的多种实现方法)
- vue实现一个tab栏(Vue实现tab导航栏并支持左右滑动功能)
- vue实现添加购物车小球(Vue实现简易购物车案例)
- vue和springboot实战项目(vue+spring boot实现校验码功能)
- vue父组件怎么用子组件的数据(Vue使用v-model封装el-pagination组件的全过程)
- vuephp后台开发框架(Vue+thinkphp5.1+axios实现文件上传)
- vue子视图里再加routerview(vue router-view的嵌套显示实现)
- vue滚动条滚动事件(vue实现一个滚动条样式)
- vue源码系列教程(vue使用引用库中的方法附源码)
- vuex中action的值怎么接(vuex中Getter的用法详解)
- vue使用echarts教程(Vue使用echarts可视化组件的方法)
- vue3.0 如何使用useroute(详解vue3中setUp和reactive函数的用法)
- vue前端搜索功能如何实现(使用Vue3+Vant组件实现App搜索历史记录功能示例代码)
- 《祝卿好》台词又土又甜,就喜欢这么直接的恋爱(祝卿好台词又土又甜)
- 大女主 汤唯垂青电视圈,搭档朱亚文出演《大明皇妃孙若微传》(汤唯垂青电视圈)
- 红色代表什么(红色代表什么情感和含义)
- 高中数学题(高中数学题型总结及解题方法)
- 冰岛旅游攻略(冰岛旅游攻略及花费)
- 为什么现在年轻人越来越喜欢买衣服(为什么现在年轻人越来越喜欢买衣服穿)
热门推荐
- mysql返回结果集函数(mysql 判断是否为子集的方法步骤)
- python处理所有异常(Python异常处理知识点总结)
- js如何操作json字符串
- mysql大表查询优化方案(mysql查询优化之100万条数据的一张表优化方案)
- thinkphp6.0安装(使用composer安装使用thinkphp6.0框架问题视频教程)
- mysql判断表中字段是否存在(mysql插入前判断数据是否存在的操作)
- for循环能有两个变量吗(关于var在for循环遇到的问题解决)
- 腾讯云轻量应用服务器与VPS服务器、虚拟主机有什么区别?(腾讯云轻量应用服务器与VPS服务器、虚拟主机有什么区别?)
- oracle恢复删除的表数据
- html5+css3动画效果图(纯DOM+CSS3实现简单的小风车动画)