首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

利用 Vue 实现评论板块:发表情,@某人消息推送

简介

在接到这个需求的时候,我就纳闷,为啥要搞这么多花样,评论就评论吧,它还要你实现艾特某人的时候,还要调用后台的IM接口,给相关人员发送通知推送;说到这里,有点经验的JY应该就想到了,数据参数如何组装和传递这是个关键点,后面再细说。

评论区主要实现的功能点有:表情包选择,艾特符识别并弹出人员选择,还有就是图片选择(篇幅有限,这个放在第二篇文章述说),还有就是支持表情包,艾特人,文本组合显示的文本区域(这个是难点)

组合显示的文本区域,除了能正常显示三种元素节点,还需要将其关联的数据包裹起来,方便在点击发送的时候,将这些数据提取出来进行组装,然后发送给后台;

刚开始,毫无头绪,不知从何下手的时候,想到的就是去寻找一劳永逸的插件,然后发现,比较适合做这方面的插件,无非就是富文本编辑器吧,比如最常用的富文本编辑器Vue-Quill-Editor[1],但是研究了一番这开源插件的文档发现,开发的API并不能满足我实际的需求,比如艾特人的情况下数据存储,还有改写后光标的显示和跟踪问题,,‍唉,一番折腾之后又陷入了苦思当中;但问题总归是要解决的,于是我开始萌生了不再依赖插件的想法;经过我一番的努力思索,还真给我整出来了,废话不多说,先上图:

接下来我会从以下几个方面分享我的开发思路喝实现方案

原型描述

思路分析

表情模块实现

艾特符模块实现

数据交互模块实现

代码实现

原型需求

具体的需求是这样子的,请看下方描述:

A.鼠标点击输入框即可开始输入内容

B.当在输入的过程发送了@消息时,被@的人会通过IM收到被@的消息。

输入@后弹出人员选择框,这里的人员包括“所有人”、“创建人”、“负责人”、“子任务负责人”、“参与人”。排序顺序按照此顺序进行展示。

排列在第一个的为“所有人”这里的所有人不包括自己。

下面的其他人员中同样不会显示出自己。

勾选人后,被勾选的人会显示到输入框中。

注意:如果@了所有人,又@了单个人,此时发送出去的消息针对个人只会发送一次。

C.通过@发送出去的消息除了会在当前页面进行展示外,还会通过IM将消息发送给对方:

@了几个人就会把消息单独发给那几个人。如果有相同的需要去重,只会发送一次。

如果@了所有人,那么就会单独发送给所有人(不包含自己)。

被@的人会在IM中收到消息。这条消息来自发起人与被@的人之间的私聊。如果聊天的内容中包含了附件,则附件不会发送到IM,只会发送本文内容和表情。做出了的效果如图:

QQ20230216-175213-HD.gif

IM聊天那边就会收到相关任务的评论信息

image.png思路分析表情模块实现

选择表情包弹层有两种方案,一种是直接图片链接展示,图片命名用中文,另一种是提交给后台的时候是要转译成【微笑】的形式进行保存,而不是图片链接

这里涉及到表情选择后,回显到文本框中。我们所知道的textarea标签只能传进文本内容,所要将div改写成可编辑的文本框,增加contenteditable="true"属性,通过获取div的Dom,对其进行光标定位,让表情包进行插入,再操作光标移动;可能看到这里的JY有点懵,在代码实现那里会细说。

image.png

image.png艾特符模块实现

当监听到用户输入@的时候我们弹出人员选择器,这时候我们需要记住现在光标所在的位置,当用户选择人员完毕之后,我们创建一个Dom在插入到我们刚刚记录光标的位置,并且把我们输入的@删除,将光标放在这个节点的最后;似乎过程描述得还蛮简单的,但不过实现起来还是有点难度;

一、使用到的JavaScript对象:

1. Range对象表示的包含节点或者文本节点一段片段

2. Selection对象表示用户的光标开始位置到结束位置的选区

(以上是我的个人理解,具体的需要到MDN上查阅)

二、实现的原理

首先通过const selection = Window.getSelection(),

const range = selection.getrangeAt(0)获取光标的位置,我使用的是create-pos插件准确获取光标的位置

然后监听键盘事件,阻止输入@的默认行为,并且创建一个SPAN标签,内容为@,然后到光标处;

创建两个新的span标签,把@+选中的内容让放到其中一个新建的span标签中,另外一个span标签插入空格

创建一个fragment片段,把第四步中两个span标签一次插入fragment中

最后使用Range对象中的insertNode()方法插入富文本中

第6步完成之后,找到第4步创建并带有@的SPAN节点,然后移除

删除时,首先找到包含@+内容的节点,然后把整个节点一起删除

数据交互模块实现

比如我要评论这样一条信息

那么我们需要怎样存储后端接口需要到的参数格式呢,比如IM推送,需要知道你艾特的是谁,还有表情包,到底要的是链接,还是标识符,这些需要分析如何存储和传递的, 而我这个项目的接口需要的数据格式如下:

image.png

其中imText是用于在IM聊天窗口中,发送消息的数据格式,

text部分是直接用于评论任务记录的显示,

users是用于存储艾特相关人员的用户id存储

显而易见,我们需要做的就是将users—id存储到艾特符元素里面,imText需要我们从内容框中得到的html,再做个正则匹配将其内容转换和替换成我们需要的数据格式;至于如何实现,待会在代码实现栏上详说

代码实现

表情包评论代码解析

选中表情

将文本框的光标位置移动到添加表情后的位置

将表情包以加装后img标签的形式累加到文本显示

@艾特某人代码解析

一、选择@按钮事件

可以阅读源码中的方法,这里主要说下,保存@某人信息的问题

给每一个选择的人员,构造一个Dom,设置为a标签元素,然后将用户信息存放在dataset里面,并设置一个classs属性(用于提交的时候通过正则匹配出来提取用户信息), 如下:

这里要写个监听函数,当用户按  的时候会被检索到,然后执行获取光标事件,并同时更新人员弹层选择列表,

三、发布评论前的数据转换

刚才在前面两个模块做的数据组装就是为了最后一步,发表评论的数据提取和传递问题

首先提取用户信息,将其存放在一个数组中

其次,将带有img标签的html文本,通过正则表达式将其提取出图片名称,用于IM的消息推送格式

最后就是整理数据,将后端定义好的数据格式传递给他们

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230316A05KPP00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券