最近帮中台团队面试了很多前端,有些想法不吐不快:发现现在很多前端都喜欢去 ToC 的业务团队,认为 ToB 的业务不就是去 XX 组件库里复制粘贴代码,然后增删改查吗?

但我想说,你那样产出的内容是没有灵魂的!你要说复制粘贴组件库可以帮助你来快速开发我信,但要是指望这种来输出一个好用的管理端我是不信的。

不同的数据用什么组件来承载?不同的操作用什么交互来实现?为什么用的同一套组件库我做的东西就总感觉差点意思?当然了,有的人会说:反正都是给内部人用的东西,能用就得了呗。好吧,只能说人各有志,这种心态来做前端,我是劝不了你的!

然后从技术上说,既然增删改查的内核是重复的,简单的,那理论上是不是可以抽象出一些工具和轮子来?不过关于这部分内容我之前的文章里有讨论过,今天主要是想从产品和交互的角度再来思考一下造轮子的意义:

  • 我点击提交的这个按钮它一定会在数据提交的过程中变成 loading 状态
  • 数据提交完毕之后一定会有一个 tip 来给我反馈结果
  • 提交完毕后当前页面的数据一定会被更新,而且会有个动画提示我哪部分数据发生了变化
  • 我输入完了表单数据一定可以用回车来代替点击提交
  • 如果是一个创建操作,那创建完成后当前的表单一定会被重置
  • 如果是查询操作,我查询的参数一定会映射在 url 中,我即使刷新了页面也不会丢失它们
  • 如果我想获得帮助,那去这个页面的右下角一定能找到一个帮助图标
  • ……

以上这些如果不靠技术手段去抽象出一个个轮子和范式来约束,你是很难保证团队中的每个成员都能“记得住”的。所以造轮子本身除了可以少写代码,我觉得更是为了产出一份“稳定”、“统一”的产品。

统一的交互才能产出完整的产品,完整的产品的所有反馈都是符合用户直觉和预期的。这可以让他们用起来莫名的爽!学习起来莫名的快! ———— 前端怎么深入思考

然而,对于一个中台团队来说,一般是没有产品和设计的,你的直接用户就是身边的开发者们,他们给你提需求,你负责实现。在此情境下,懂点产品和交互设计就很重要了。

那我们一直说产品思维,产品思维,说的是什么呢?举个简单的例子:某开发跟你说,我想要在某页面显示一个警告信息,告诉用户这个页面的数据不要轻易修改。

记住,这种直接面向页面设计的要求一般都是有问题的,你要相信你作为前端工程师在交互和设计方面一定是比他们更专业的,你要问清楚他们背后的需求是什么?

比如这个事情你问了之后,可能真实需求是希望尽可能保障生产环境数据的安全,让用户不能随意操作。于是,你要做的正确的事情就成了:好好设计一下前端所有生产环境操作的权限控制,不能操作的人直接就不给操作入口;能操作的人在真正操作的步骤里再给个醒目的提示,或者来一个吓人的弹窗。

这样才算是从产品的角度来实现需求。

总结一下:不要面向接口编程,要面向需求。从需求出发,你甚至可以反过来去要求他们来修改接口。

————– 分割线 ————–

恰好这两天帮一朋友改造他们的管理端,有一些很典型的场景可以分享一下。改造的模块是下单部分,如下图:

刚拿到这个页面的我是一脸懵逼的,我完全不知道这个用来创建订单的页面要怎么去创建订单。因为首先从直觉上页面上的这些元素就不符合我对一个创建类的表单页面的预期,而反直觉的设计一定不是好的设计!(但有可能是好的艺术。。

然后经过了一番询问,我终于知道了下单的完整逻辑是什么了,那么来一点一点拆解,我们先来看这部分:

用到了两个 Tab 选项。Tab 组件一般用于承载一些“平级的”数据,这意味着 Tab 中的内容是不分主次的。而对于一个用来创建订单的页面,为什么要有一个跟创建行为平级的 Tab?而且是看起来并没有什么关联的 Tab。

询问之后我才知道,那个叫做快捷查询栏的 Tab,title 写错了,其实应该叫创建用户。那么问题又来了,为什么要在创建订单的页面去创建用户?

询问之后我又知道了,原来创建订单的时候需要先选择用户,如果没有自己想要的用户可以去创建。
ok,即便如此,创建用户在这里也不应该和创建订单来“平分秋色”,它应当只是作为订单中用户这个字段的辅助功能而已

所以,以上啰嗦内容的核心意思是页面要分主次。那这部分该如何改造呢?很简单,首先把 Tab 干掉,然后把创建用户的入口放在用户选择器的下方,即把功能的入口放在真正需要它且触手可及的地方。如下图:

————– 分割线 ————–

我们继续来看下一部分:

上图的电话号查询会把结果展示在那个叫查询结果的表格中,然后点击表格中的数据来实现选择用户。这部分的主要问题首先还是没有分清主次:用了一个输入框,一个按钮和一个表格。其中表格还占了页面很大的空间来展示对于这个页面来说不怎么重要的用户列表,而真实需求却是为了给这笔订单“输入用户”。

那这部分该如何改造我想大部分人都能想得到了。是的,一个支持搜索的选择器:

不过这里值得一提的是很多人会乱用 AutoComplete 组件和支持搜索的 Select 组件。二者的区别是前者只是提供输入建议,我可以不接受建议自己输入任意内容;而后者只允许选择给定的选项。所以显然这个场景下使用 Select 才合适。

————– 分割线 ————–

再继续看:

刚开始我了解到的上图中表格的功能是:在选择完用户之后,去加载该用户的默认地址和最近的 10 笔订单中的地址,然后点击地址可以自动填充到下面的地址输入框中去。

所以和上面那个需求类似,第一想法还是把这两个表格给干掉,然后地址输入框采用 AutoComplete 来提供地址输入建议来解决快捷引用相关的地址的这个需求,而不是本末倒置地去花大量的篇幅来展示地址。

然而,再沟通之后我才了解到,原来地址表格中不单单只有地址字段,还有充装站供应站,所以点击之后同样还要关联它们。如果是这样的话,显然不能够给所有要关联的字段都做成 AutoComplete,那样的话字段与字段之间会丢失相关关系。

所以最终列表还是要展示的,不过肯定不能在创建区域占用地方了,类似上文提到的创建用户改造,把它的入口也给挪到一个正确的地方:

————– 分割线 ————–

Go on:

它们是一个二级联动的下拉选择器。然后对于多级联动场景来说,如果多级联动的内容存在严格的父子关系, Cascader 绝对是更好的选择。因为级联选择器首先是省地方,然后可以让用户专注于当前的关联选项,整个操作过程是自然和连贯的,且选择完成之后在单行内容上就可以清楚的看到包含父子关系的选择结果。就像这样:

————– 分割线 ————–

Let’s continue:

这部分要吐槽的点就太多了!令人发指的设计!令人智息的交互!为什么要用单选项来控制折叠面板?折叠面板不会自己折叠吗?我打开了面板为什么单选项没有被选中?传说中的单向绑定吗?这么多的选项为什么还要用单选项?Select 了解一下?

然后再从交互心理学上(我发明的!)吐槽一下:这个需求是不同的下单类型对应不同的表单内容,如果你使用了折叠面板作为不同的表单内容的容器,这很容易让人误会成无论我选择的下单类型是啥,折叠面板里的内容都是可以填的,不同面板里的内容如果我填了最后都会被提交出去!因为折叠面板本身只是对内容的收纳设计,可以节约空间,还可以让使用者随意切换自己想要看的那一级的内容,但从来没有内容如果被收起就不存在(不提交)了的意思!

所以。。。请来看一下我的设计(正确的设计!):

PS:其实上面的设计也是偷懒的做法,更好一些的方式应该是在创建订单的入口处就先让选择订单类型,类似这种:

不过即使偷懒了,也应当把类型这个字段放在尽量靠前的位置,因为该字段在逻辑上本身就是需要靠前的。举一反四,各个字段的顺序该怎么排列就把自己带入到需求当中,想一下如果是自己真实地来使用,脑子里浮现的数据顺序是什么。

总结一下:坚决使用 Select 来选择超过 x 个的选项,坚决的使用 Option 来选择少于或等于 x 的选项(x 取决于页面空间和选项肉眼识别的复杂度,一般等于 3);如果是是否型的选项,那建议使用单个 CheckBoxSwitch。然后不需要填写的表单就不要显示出来!

————– 分割线 ————–

RangeWoMenJiXuBa:(已词穷

这里倒是不难看出来交互的逻辑是:输入完相关内容后点击增加,内容会被添加到表格中。

只是不知道原开发者为什么会在一个主交互是输入的页面里对表格这个偏展示的组件如此情有独钟,而且只管输入不管修改和删除,以至于如果你这一步增加错了东西得刷新整个页面重来。。。

然后结合上文的一些类似场景,不难发现类似的交互处理是有套路的:一个表单里面如果出现了需要额外输入的东西,比如上文的添加用户和这里的添加物品,那么就把他们挪到别处去吧!PC 端可以用弹窗,可以用侧滑抽屉;移动端则可以 Push 一个新页面。于是改造的结果如下:

再强行总结一波:让表单页面放眼望去都是表单元素(最好长得都是像输入框的元素),且每个表单元素上展示的都是确定要提交的表单数据。

————– 分割线 ————–

现在知道写一个管理端也有很多事情可以搞了吧?!是不是都迫不及待地想去重构管理端了?没有管理端可以重构的甚至都迫不及待地想转岗到中台部门了?那么。。。

好消息!好消息!知乎中台前端组急招前端!

感兴趣的快私我!

————– 分割线 ————–

又想到了一点补充下:交互也要讲究逻辑自洽:比如页面的菜单,在二级菜单被打开的情况下,点击了整个菜单的「收起」,那菜单在被展开后,之前被打开的二级菜单也应当重新被打开。或者换句话说交互的功能也要遵循单一职责。

再比如页面的某个地方的数据展示是来自另一个地方的数据添加,那这两者的数据理论上应当一一映射的。你不能说我添加的时候那个数据叫「hello world」,你展示的时候就变成了 「Hello World」了(对!字母的大小写都不能差


 评论