道招

邮箱收件人组件(vue版)成长历程(一)

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

邮箱收件人组件(vue版)成长历程(一)

前期项目中需要优化原始的收件人、抄送、密送部分,换成更加现代化的样式和用户,当时将这部分抽象成一个组件了,最近的需求是发件人也要使用该组件,鉴于发件人比收件人等需要校验的地方和交互习惯变动点较多,进行了重构,在此过程中发现自己当初思维还是比较局限,特发文记录下。

先看看发件人组件的样式吧 file

很显然,这里的收件人支持最少两种写法,一种是纯粹的只有收件地址,比如第一个test@qq.com,同时也支持第二种写法是带收件人和收件人地址另一个测试<anthortest @qq.com>,毕竟在可读性上第二个比第一个要好。 file

以下为了方便描述,我们把第二图中的第一个收件人状态称为预览态,第二个收件人状态称为编辑态

当时产品是参考网易邮箱大师(万恶之源)来实现功能的 总共需要支持以下功能

  1. test@qq.com另一个测试</anthortest><anthortest @qq.com>两种格式
  2. 在预览态校验邮箱合法性并进行对应的标识
  3. 预览态双击进入编辑态,失去焦点或者回车后回到预览态
  4. 支持搜索,搜索候选项能用键盘上下键实现选择,能够用回车上屏
  5. 预览态时支持鼠标单击后高亮,图一中第一个就是被点击选中的,颜色与第二个稍微有点不同,再删除键时删除,删除后光标在前一个内容后面,并且可以一直向左删除
  6. 点击两个收件人预览态(如果有的话)中间空白处插入新的,然后再按删除键可以一直向左删除
  7. 兼容Outlook、网易邮箱大师的收件人的复制、粘贴 当时主要参考网易邮箱大师客户端和gmail邮箱网页版

当然要看代码实现的话,只能看到gmail邮箱的,它的交互不太符合产品要求,但是那都是不是技术难点。 首先需要支持这些样式,原来的input是肯定不行了,那只能div了,怎么让它可编辑呢?我发现gmail在输入还是用的input,预览态时是用的div实现,当时出于挑战自己和青铜的倔强,想试着换个方案,完全使用可编辑div来实现。。。这个小小的倔强为后续很多功能瓶颈埋下了隐患。。。

整体逻辑

我们知道这个组件里面的内容其实是一个数组,数组个每个元素都是一个收件人对象。比如:

{
    label: '另一个测试',
    value: 'anthortest@qq.com',
    editable: true,
}

我们可以用一个属性editable,来控制当时是否是编辑态还是预览态,数组里面最多只会有一个是编辑态,让里面任何一个收件人失去焦点后或者被外部赋值后进行校验并更新预览态。在整个组件空白区域内点击时就网数组里面的合适位置插入一个收件人对象,并将其editable属性置为true,然后显示对应的光标。 我们可以把整个组件分成三个部分,一个是主组件main,一个是显示/输入组件inputItem,一个是候选词列表组件candidateBox

控制鼠标光标

这个应该是最先要考虑的问题,在contenteditable的div里面是点击到哪哪里就有光标,比如在预览态双击进入编辑态后,如果含有收件人信息的化,编辑态的需要展示的内容明显要比预览多的,这时怎么控制好光标到最后面呢? 此时光标默认在它的最后面,其中光标的实现可以用Range实现

const blank = document.createTextNode('');
const range = document.createRange();
range.selectNodeContents(blank); // 让光标聚焦在最后面
getSelection().removeAllRanges();
getSelection().addRange(range);
校验

在任何一个收件人信息输入失去焦点的校验,并更新预览态

响应点击

这个需要布局配合 file

  1. 在整个组件内但是非已存在收件人信息以外的区域(上图中的蓝框区域)点击时,认为是在最后面添加新的收件人,直接在数组最后push一个新的收件人对象
  2. 点击到某个收件人预览态(图中的绿框)时将其高亮,如果是双击的化则将其置为编辑态,如果是单击它前面(第一个小箭头所指区域),则是在它前面再增加一个收件人。这些都可以通过当前的index来实现。
删除

整个div内容通过tabindex实现删除

搜索

这个就比较简单了

搜索候选词

整个组件内最多只会有一个候选词选择框,它必定伴随关联着某个收件人对象

file

简单分析后我们会发现复杂的逻辑再inputItem里面,它要是能够切换预览态和编辑态,能控制光标,响应单击、双击。其实我们对候选词的上下键及回车上屏的响应也可以放到它上面,我们只用把这几个键盘事件来间接控制候选框的“焦点”,其实哪有什么焦点,只要让对应的颜色根据鼠标按键变化就行了,在用户感知时就感觉在移动焦点,这个我们可以让inputItem通知main,main再让candidateBox进行响应的颜色变化。inputItem作为主要的用户交互对象,将用户的鼠标和键盘行为通过事件告知main,main作为大脑据此让inputItem和candidateBox做出对应的响应。

这里需要注意的是在整体失去焦点后需要对数据做一个清空操作,因为我们这里鼠标点击后那个光标处实际上也是整个数组里面的一个inputItem,只是它是{ label: '', value: '', editable: true}而已。

这大概就是当时做的收件人组件的主要内容了,因为是公司项目,没法展示代码,欢迎和大家进行技术交流。

写不动了,关于在这个收件人组件的弊端和为何不满足简单扩展成发件人来使用,发件人和收件人需求点有何不同?这个部分内容下次再写。

更新时间:
上一篇:加个分享印象笔记收藏内容的功能?下一篇:怎么便宜价格付费看O’Reilly(原safaribooksonline)动物出版社的电子书

相关文章

2021年的一点工作总结(一)迁移React技术栈

2021年全年的工作总结起来很简单,算是做苦力的一年吧。。。 2021年春节后就开始邮件项目从Vue迁移到React的工作以及富文本编辑器由wangEditor替换成CKEditor。 其实自己 阅读更多…

支持取消单选组件vue版

原生的单选就是 &lt;input type=&quot;radio&quot;/&gt; ,正常情况在 name 相同的单选之间只能选一个,如果只有一个单选框的情况下,一经选中是无法自己取消的,和 阅读更多…

vue内置组件keep-alive源码解析

很简单,我们直接看vue的源码即可。 keep-alive 组件支持三个属性。 props: { include: patternTypes, exclude: patter 阅读更多…

从vuecli3学习webpack记录(零)整体流程

今天看了下自己之前写的从vuecli3学习webpack记录系列,感觉自己居然没有在一开始的时候把vuecli的 npm run serve 的整体流程在一篇文章里面完整的讲完,可能是因为打字打的手 阅读更多…

项目Vue转成React hooks可能存在的问题--急需类似setState回调

假设在Vue中有如下三个方法,并且初始时 this.a = ‘a’; this.b = ‘b’; funA() { this.a = &#039;1221&#03 阅读更多…

Vue和React hooks实现Select批量选择、选中条数、全选、反选实现对比

批量选择、全选、反选这些功能使用频率还是很高的,下面直接看看Vue和React分别怎么实现吧。 Vue 在使用Vue的时候是很容易实现的,我们以下列数据格式为例: const data 阅读更多…

关注道招网公众帐号
友情链接
消息推送
道招网关注互联网,分享IT资讯,前沿科技、编程技术,是否允许文章更新后推送通知消息。
允许
不用了