前言

在上个月初,接到一个需求,要开发一个 聊天通讯 模块 并且 集成到 项目中的多个 入口,实现业务数据的记录追踪.

接到需求后,还挺开心,这是我第一次 搞 通讯 类的需求,之前一直是 B 端 的业务需求,不过现在也是在做这个方向,感觉 B  端 方向 挺有意思,管理着项目的整个项目上游和下游,然后服务于 内部人员 和 外部人员 使用,感觉挺自豪的。

下面就就跟着我来看看 如何 开发一个 聊天通讯 服务吧 !  (主要站在前端的角度来讲如何开发设计 )

技术栈

  • Vue 2.x

  • Websoket

  • Vuex

  • Element

  • vue-at

本项目是 以 Vue  技术栈生态开发的,其实不管用什么语言  , 思路是关键 ! 知道每一步需要干什么, 然后将每一步操作  整合起来 , 最终服务就跑起来了.

当中的每一步需要干什么  就是 编程 中的 function  功能,根据这个功能然后在细化分析需要有到哪些技术点  。在开发的过程中,你不可能对整个链路的所有技术点 熟悉,这就需要遇到啥困难,临时学习就可以了。

开始分析需求

首先,我们要等待 UI 设计师  的设计稿 画出来,  然后根据 UI 设计师的 设计稿分析整体 聊天通讯 的结构,从view  结构 来 划分 应该 大体 包括哪些 component  , 每个component  中 又包括哪些小的 component , 这样从 大 到 小  的方向将 设计稿  转化为 程序员视角的 component .

确立了有哪些component  ,  接下来 就是 确定 每个 小的 component 又有哪些 功能了。现在 UI 设计师们,一般画完界面后,会通过第三方软件 / 平台  来将效果图 转化成网页,并且可以通过 URL 可以直接访问,当光标放到页面中的某个元素时,可以获取到当前元素的 css style  , 不过,我建议不之 copy  ,有时和自己写的布局代码会冲突,按需copy .

效果图

真实效果图,我就在这里不放出来了,为了保密性,只把整体结构,列出来,然后带着大家分析结构和功能,如何进行编码设计和组件设计。

功能分析图

根据效果图,在进行组件划分时,我要记住这个原则:高内聚,低耦合  , 组件职责单一性

我们将组件划分为:

  • 联系人组件

  • 聊天组件 ---- 包括了 历史记录组件

功能根据 UI 设计师 提供的 URL 网页来看交互效果来定,并和组长 / 产品经理 交流需求,确定需求,以及砍掉不合理需求。

需求确定后,就是梳理组件部分的功能了。

组件构成

在分析组件之前,我们需要先了解一下Vue Component ,使用Vue 的 朋友应该很熟悉了,一个组件的构成由以下组成:

  1. data  组件内部状态

  2. computed  计算属性,监听data 变化来实现对应的业务逻辑需求

  3. watch  监听state 变化

  4. method  组将的功能编写区

  5. props  组件接受父组件 传递来的值,进行约束类型等

  6. lifecycle  组件的生命周期, 可以在组件创建到销毁的过程中执行对应的业务逻辑

联系人组件

这个组件主要是用来在聊天的时候,可以通过分组快速的找到某个人联系它,功能相对简单。

功能:

  1. 查找联系人

  2. 有通知某人操作

功能分析

「功能1: 查找联系人」

通过现有联系人json  数据来 查找输入的联系人进行匹配。(简单)

「功能2:通知某人」

当用户点击到某个联系人时,将点击的人 放到输入框里 显示 @xxx  [ 经过格式化处理 ] , 并将选中的联系人信息加入到发送消息的 json 对象中。

有多种实现方案,当用户点击了某联系人时,将触发事件,携带值传递给父组件[聊天组件的入口 index.vue ] 接收,然后将值传递给 聊天主体组件  ,通过 在 聊天主体组件 中 通过 $refs 进行传递值。

下面只提供示例代码

从联系人列表获取选中联系人

//联系人组件 concat.vuegetLogname(val){this.$emit('toParent',{tag:'add',logname:val})
},

「聊天框显示选中的联系人」

在聊天入口组件 接收 子向父 组件传递 选中联系人数据,然后给  聊天主体 组件绑定 ref , 通过refs  来将联系人数据传递到 聊天主体 组件显示。[这块 数据传递有多种方法,例如 Vuex]

//聊天组件入口 index.vue   它包括 联系人组件  聊天主体组件  历史记录组件//联系人组件
<Concat @toParent='innerHtmlToChat'/>//聊天主体组件
<ChatRoom @fullScreen="getFullStatus" @closeWindow="close" ref="chatRoom"/>// 接受innerHtmlToChat(data){this.$refs.chatRoom.$refs.inputConents.innerHTML+=`&nbsp;@&nbsp;${data.logname}`  //拼接到聊天输入框里
},

效果展示

从联系人列表选中人员,发送消息@人 接收到推送消息

聊天主体组件

这个组件就负责的功能就多了,这块我主要把关键的功能带大家来分析过一遍

关键功能;

  1. @ 好友功能,实现推送通知(在线通知 / 离线-上线通知)

  2. 聊天工具 [ 支持表情   支持大文件上传 ]

  3. 发送消息 [ ` 这块就可以跟业务挂钩了,发送信息时,并携带一些符合你项目需求的数据]

功能分析

「功能1 :@ 实现」

vue-at 文档  : https://github.com/von7750/vue-at

它的功能和 微信  和 QQ  **@ ** 功能一样,在聊天输入框里,当你 输入 @ 键时, 弹出好友列表,然后从中选择联系人进行聊天。

@  功能必须包括以下3个关键功能;

  • 可以弹出联系人列表

  • 可以监听输入字符内容进行过滤显示对应数据

  • 删除  @ 联系人

  • .......

一开始, 我是 自己造了个  @  功能 轮子 搞了搞,后来才发现市场上有相应的轮子,直接用第三方了,挺不错的 vue-at

下面来跟着我,来捋一下思路如何实现这个轮子,此处就不放实现代码了。

先来分析一波:

当在编辑区,输入 @ 时, 弹出框

  1. 我们可以在 mounted 生命周期中监听 按键 code  =  50  / 229 (中文/英文) 时,做出处理

  2. 由于我们这块采用的 div 可编辑属性 ,那么就获取到 可编辑属性的光标位置

  3. 然后通过光标位置 动态来改变 弹出框联系人列表的样式 top  left ,  实现跟着光标的 位置显示联系人列表。

  4. 然后 从列表中选择 联系人进行聊天,并将 联系人列表弹框 隐藏掉。

上面就实现了基本的  选中联系人功能

「删除选中的联系人」

由于这块是采用的可编辑属性, 我们可以获取选中的人,但「无法直接判断是删除的哪个人」,这时,只能通过判断 innerHTML 中是否包含某联系人,来进行删除已保存的联系人。

这时,已经基本满足了业务需求实现了。

第三方插件已经的够好了,我们就没必要再造轮子,浪费时间了, 但 实现思路 必须的懂。下面,我就来演示如何使用 第三方插件vue-at 实现 @ 功能

「1. 安装插件」

npm i vue-at@2.x

「2.组件 内部导入插件组件」

import At from "vue-at";

「3.注册插件组件」

components: {At},

「4. 页面中使用」

At 组件 必须包括 可编辑 输入内容区域, 这样,当输入 @ 时,会弹出联系人列表框。

  • members :   数据源

  • filter-match :  过滤数据

  • deleteMatch :  删除的联系人

  • insert  :  获取联系人

<At:members="filtercontactListContainer":filter-match="filterMatch":deleteMatch="deleteMatch"@insert="getValue"><template slot="item" slot-scope="s"><div v-text="s.item" style="width:100%"></div></template><divclass="inputContent"contenteditable="true"ref="inputConents"></div>
</At>
// 过滤联系人
filterMatch(name, chunk) {return name.toLowerCase().indexOf(chunk.toLowerCase()) === 0;
},
// 删除联系人
deleteMatch(name, chunk, suffix) {this.contactList = this.contactList.filter(item => item.logname != chunk.trim());return chunk === name + suffix;
},
// 获取联系人
getValue(val) {this.contactList.push({ logname: val });
},

「功能2:聊天工具箱」

聊天软件除了普通文字聊天,还有一些辅助服务来增加聊天的丰富性,例如: 表情 , 文件上传, 截图上传 .... 功能

我们先来看看 市场 热门聊天软件它们有哪些 聊天工具。

「微信聊天工具箱」

  • 表情

  • 文件上传

  • 截屏

  • 聊天记录

  • 视频聊天 / 语音聊天

微信聊天工具箱

QQ 聊天工具箱」

  • 表情

  • GIF 动图

  • 截屏

  • 文件上传

  • 腾讯文档

  • 图片发送

  • ..... 腾讯业务相关功能

QQ聊天工具箱

介绍了市场上热门聊天的工具箱有哪些工具,回归正题:我们的聊天工具箱  有哪些功能呢, 其实有哪些功能根据 业务来定,后期工具箱可以不断扩充。「我们的工具箱基本上满足日常聊天需求」

  • 表情

  • 文件上传  支持大文件 ( 几个G 都可以)

  • 截屏  Ctrl + Alt + A

  • 历史记录

下面我就来将比较几个重要的功能:文件上传  和 截屏 , 其它功能都很简单。

「文件上传」

上传组件我采用的是 Element el-upload 组件,由于我业务 要求上传文件支持大文件, 采用的 分片续传 方式来实现。

「分片续传思路」

  1. 我们上传也是采用的 websoket 上传,首次发送时,必须发送一些必要的文件基本信息

  • 文件名

  • 文件大小

  • 发送者

  • 一些跟业务相关的字段数据

  • 时间

  • 文件分片大小

  • 文件分片片数

  • 上传进度标识

首次发送完文件的基本信息后,开始发送分片文件信息,首先将文件分片后,然后依次读取片文件流,发送时携带文件流,等文件分片循环结束后,发送一个结束标识告诉后台发送完毕了 [这块你可以和后端商量设计数据格式]

「示例代码演示」

<el-uploadref="upload"class="upload-demo"drag:auto-upload="false":file-list="fileList":http-request="httpRequest"style="width:200px"><i class="el-icon-upload"></i><div class="el-upload__text" trigger><em> 将文件拖到此处然后点击上传文件</em></div>
</el-upload>

覆盖掉 Element 默认上传方式,改用自定义上传方式。

开始分片上传

// 上传文件httpRequest(options) {let that = this;//每个文件切片大小const bytesPerPiece = 1024 * 2048;// 文件必要的信息const { name, size } = options.file;// 文件分割片数const chunkCount = Math.ceil(size / bytesPerPiece);// 获取到文件后,发送文件的基本信息const fileBaseInfo = {fileName: name,fileSize: size,segments: "historymessage",loginName: localStorage.getItem("usrname"),time: new Date().toLocaleString(),chunkSize: bytesPerPiece,chunkCount: chunkCount,messagetype: "bufferfile",process: "begin",... 一些跟业务挂钩的 字段};that.$websoketGlobal.ws.send(JSON.stringify(fileBaseInfo));let start = 0;// 进行分片var blob = options.file.slice(start, start + bytesPerPiece);//创建`FileReader`var reader = new FileReader();//开始读取指定的 Blob中的内容, 一旦完成, result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.reader.readAsArrayBuffer(blob);//读取操作完成时自动触发。reader.onload = function(e) {// 发送文件流that.$websoketGlobal.ws.send(reader.result);start += bytesPerPiece;if (start < size) {var blob = options.file.slice(start, start + bytesPerPiece);reader.readAsArrayBuffer(blob);} else {fileBaseInfo.process = "end";// 发送上传文件结束 标识that.$websoketGlobal.ws.send(JSON.stringify(fileBaseInfo));}that.uploadStatus = false;that.fileList = [];};},

「效果演示」

功能3:截屏功能

PC  中,这是一个很重要的业务,通过这种技术可以从网上截取下自己感兴趣的文章图片供自己使用观看,可以帮助人们更好的去理解使用知识。

由于我们的输入内容区域采用的 可编辑 区域,此处可以插入任意内容,也可以使用外部 的截图功能,粘贴到输入框区域,这块就没必要的「造轮子了」

「1.  可编辑区域」

我们给 div  加上 该属性 contenteditable 就可以控制 div 中可输入哪些内容,外部复制过来内容也可以直接显示,还可以显示其带的css 效果。我们先来看看 contenteditable 有哪些属性吧 !

描述
inherit 默认值继承自父元素
true 或空字符串,表示元素是可编辑的;
false 表示元素不是可编辑的。
plaintext-only 纯文本
caret 符号
events

「注意」

不允许简写为 <label contenteditable>Example Label</label>

正确的用法是 <label contenteditable="true">Example Label</label>

「浏览器支持情况」

「使用」

<divclass="inputContent"contenteditable="true"ref="inputConents">
</div>

「效果展示」

「2. 截屏」

由于采用的是 可编辑 ,那么就可以随意从外部 copy , 哈哈,有意思的来了,支持 Windows 自带的截屏  + PC 第三方 截屏......

从 0 到 1 开发一个聊天通讯 服务 复盘总结相关推荐

  1. 勇敢跨越,从0到1开发一个属于自己的App

    1 前言 码字不易,且行且珍惜. 之前听一个老铁说,一个开发者的真正蜕变,要从真正做一个属于自己的App开始,你只有自己一个人摸索.研究,真正靠自己踏上这条路,才能尝尽这条路上的酸甜苦辣,才会成长!于 ...

  2. Android-IM从零开始开发一个即时通讯项目

    Android-IM从零开始开发一个即时通讯项目 https://www.jianshu.com/p/dca480006691 关于聊天室项目 聊天室项目,也被称为即时通讯(IM). 其原理是服务器是 ...

  3. 可视化入门:从 0 到 1 开发一个图表库

    作者介绍 万木:蚂蚁体验技术部前端工程师,AntV G2 栈的核心维护者,多次在 IEEE Vast Challenge,ChinaVis Challenge 等数据分析挑战赛中获得优异成绩.喜欢写代 ...

  4. 鸿蒙系统开发实战-开发一个聊天技巧软件堪称聊天神器

    鸿蒙开发实战-开发一个聊天助手APP 鸿蒙系统开发实战-开发一个聊天技巧软件堪称聊天神器.目前鸿蒙系统可真是过了一把自主研发的瘾,通过一个鸿蒙程序开发实战教程来演示如何开发一款聊天神器,视频教程放在了 ...

  5. Uni-app学习从0到1开发一个app——(3)简单小工程内容介绍

    文章目录 工程文件 看看一个标准的hello微信小程序工程文件的组成和作用. 工程文件 可以参考官方教程:传送门 之前的文章有详细的开发环境介绍,传送门Uni-app学习从0到1开发一个app--(2 ...

  6. python聊天室设计_如何使用 Python 开发一个聊天室?

    ​接下来我们就使用 Python 来操作 socket ,实现一个聊天室的一些主要功能.首先我们来回想下,一般的聊天室都是怎样的,有多个用户可以同时在线,他们可以实时获取到消息,实时发送消息. 服务端 ...

  7. GoEasy小程序即时通讯源码 v1.1.0基于GoEasy提供的websocket通讯服务

    介绍: GoEasy小程序即时通讯源码是一个基于GoEasy提供的websocket通讯服务,实现的小程序即时通讯,支持一对一单聊.群聊.会话列表.上下线提醒.历史消息.离线消息,支持发送图片.视频. ...

  8. 使用react+redux+react-redux+react-router+axios+scss技术栈从0到1开发一个applist应用

    先看效果图 github地址 github仓库 在线访问 初始化项目 #创建项目 create-react-app applist #如果没有安装create-react-app的话,先安装 npm ...

  9. 艾思软件教你, 自己动手,从0到1开发一个App

    本文假定读者是想通过自己的学习和努力,从0到1去制作自己的一款APP产品. 我将从独立开发者的角度,尽可能描述一条可行的路径. 第一步:制作产品原型 不懂开发的人可能觉得软件产品就只是程序员埋头吭哧吭 ...

最新文章

  1. mkl gt;=2018
  2. win7html文件,教你win7浏览器打不开本地html文件格式的解决方法
  3. 坐标上升算法(Coordinate Ascent)及C++编程实现
  4. Java获取当前运行的CPU是几核的
  5. C语言实现词典编排算法(附完整源码)
  6. 【若依(ruoyi)】解决同一Tomcat下两个/多个若依(ruoyi)项目部署报错
  7. mysql size_mysql fetch size 相关问题
  8. ATOM editor recommended by Sean
  9. 使用git命令提交代码到Github远程仓库的方法
  10. c语言用星号输出沙漏,《算法笔记》学习日记——3.3 图形输出
  11. 层次分析法详细讲解(小白必看电脑查看)
  12. 从NC程序中提取路径点的XYZ
  13. java 读文件内容_Java 如何读取txt文件的内容?
  14. docker进程管理(1号进程,僵尸进程详解)
  15. 哈夫曼码的编译码系统
  16. 2018年下半年网络工程师考试试题分析(4)
  17. hive 转拼音udf_Hive 自定义UDF函数
  18. 中国招聘网站调研报告
  19. 两张独立显卡连接两个显示器如何配置
  20. matlab_app实现一个简单的色彩分析可视化程序

热门文章

  1. 新方法破解Wi-Fi WPA2加密平均只需10分钟
  2. Linux下载蓝奏云文件,蓝奏云CMD控制台
  3. 浙江江西公费出国游黑幕调查
  4. 欧拉φ函数和欧拉降幂公式
  5. 基于微信理共享停车位预约小程序系统设计与实现 开题报告
  6. c语言五子棋毕业设计,基于c语言五子棋小游戏--本科生毕业设计.doc
  7. 基于GPS的公交车站点播报调试第四天
  8. 吉林大学 十佳歌手 计算机科学与工程学院,贾海洋 - 吉林大学 - 计算机科学与技术学院...
  9. ambari hdfs 启动报错_Ambari 1.6 自动安装hadoop 2.2.0 在Ambari启动namenode时报错
  10. Python 网络数据采集(三):采集整个网站