道招

邮箱收件人组件(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)动物出版社的电子书

相关文章

vue-cli设置css不生效

我们有的项目使用的是老的vue-cli脚手架生成的,今天想写点东西,发现.vue文件里面 style 里面写的样式都不生效了,很自然就想到是不是loader的问题。 在这种项目的webpack.ba 阅读更多…

用在线IDE写vue代码

上周末无意中发现了一个新的在线IDE,网址glitch.com,个人感觉很不错,于是顺便关注了下其它的在线IDE,比如codesandbox.io也不错,没有细看,可能自己已经先入为主的喜欢上glit 阅读更多…

邮件搬家:转移旧邮箱邮件至新邮箱

以前觉得估计用不上这个,今天才发现自己果然就这种蛋疼的需求,更奇葩的是网上还真能找到这样的解决方法。 1.安装微软的outlook,使用imap方式(pop3方式未测试,读者可以试试)配置自己的新旧 阅读更多…

道招网官方通知邮箱、腾讯微博、新浪微博

今天道招网正式确定了官方通知邮箱,并且命名此系统为 道招提示 ,通知邮箱为 notice_daozhao_com@163.com 。另外腾讯微博地址为 http://t.qq.com/share_i 阅读更多…

支持取消单选组件vue版

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

element-ui表单源码解析之el-input

关于表单校验el-input做的主要工作就是跟el-form-item交互,把input的相关事件发送给el-form-item,上一篇已经讲到在el-form-item的mounted的生命周期里 阅读更多…

关注道招网公众帐号