原型设计,要不要做这么复杂?我的答案是"需要做就做!" 入行以来,前前后后主导了几个项目的后台系统,由于每次都是从0到1开始设计,所以需要设计后台系统的菜单;而菜单的修改伴随着整个原型的迭代过程,经常为了维持页面的统一性或者模拟更真实的交互效果,需要花不短的时间修改。 在制作菜单的过程中,尝试过很多种方式,包括使用母版,动态面板,中继器等,慢慢的总结了一些经验,经历了几次的优化后,最终得到了一套合理的解决方案,而这个优化历史也可以分为几段: 无效率的菜单设计 使用母版增加你的工作效率 使用动态面板实现点击交互效果 使用中继器制作手风琴菜单 第一阶段:无效率的菜单设计 平面化的菜单设计,每个页面单独设计对应的菜单,即每个页面的菜单是分开的,不同菜单页面之间没有关联性,这种方法比较简单直接,但是每一个页面都需要重新画一次菜单,尤其是需要调整菜单内各个页面之间的排序或增加新页面的时候,为了一个页面的变动需要重新把所有的页面的菜单改过来,最终的导致花了很多不必要的时间在原型的修改上。 第二阶段:使用母版增加你的工作效率 认识到原来的工作方式十分低效之后(关键是影响工作完成的进度),我开始思考有什么方式可以优化这方面的工作效率,所以开始引入母版,将一个菜单放在母版的设计中,这样的话在设计不同的页面的时候直接将母版拖到对应的页面中,最后如果需要涉及菜单的修改的时候,就直接修改母版即可。 由于在不同的页面,菜单的展示样式是不一样的,需要高亮的菜单栏也是不一样的,如下图,当你打开京东"配送服务查询"页面的时候,高亮对应的二级菜单栏,且对应的一级菜单栏"配送方式"会展开,但是当你打开"订单查询"页面时,高亮订单查询页面并展开一级菜单栏"订单百事通";因此,我最开始使用母版的时候,只是单纯的利用母版来进行复制粘贴的效率,每次都是将母版拖到对应的页面,在脱离母版后对菜单进行修改,但是这个方式依旧是低效率的。 第三阶段:使用动态面板实现点击交互效果 经历了前面两次尝试之后,我发现除了需要使用母版来让菜单变得可以复用,还需要让菜单可以交互并应用于不同的页面,以达到真实的模仿页面点击效果的目的;所以开始使用动态面板来制作我的菜单,了解动态面板的都知道,动态面板的主要作用是通过不同的触发条件来切换不同的显示状态,所以只需要先布局好一级菜单栏,然后在一级菜单栏的基础上添加交互效果,控制动态面板显示不同的二级菜单栏。 具体做法如下: 1. 添加一个母版并进行命名,在母版中布局好一级菜单栏,和二级菜单栏,并给菜单栏命名:一级菜单栏分别命名为"yjcd1″,"yjcd2″,"yjcd2″…,添加一个动态面板,该动态面板命名为"erjicd",为该动态面板添加面板,将二级子菜单分别放入不同的面板,并给每个面板进行命名,如下图: 2. 设置交互效果,交互效果最终需要实现点击每个一级菜单栏,对应的动态面板分别显示对应的二级菜单栏,所以需要引入一个全局变量"ejcd",点击不同的一级菜单栏,会设置为不同的全局变量值,最终在页面加载的时候,先根据全局变量值判断动态面板需要怎么显示,如下图: 添加全局变量: 3. 设置点击一级菜单栏的交互效果: 交互效果1:设置值于ejcd=="1″目的是修改全局变量,使在点击二级子菜单的时候,跳转新页面,新页面加载的时候根据全局变量显示不同的二级菜单栏; 交互效果2:设置erjicd为商品的目的是修改当前页面的二级子菜单状态,使得点击不同的一级子菜单均可以在本页面切换查看不同的二级子菜单目录)。 4. 设置页面加载效果,每次跳转到新页面时,根据全局变量"ejcd"分别显示不同的二级子菜单目录: 5. 最后,为不同的二级子菜单添加跳转交互即可: 第四阶段:使用中继器制作手风琴菜单 1. 添加一级菜单栏 先整理菜单结构,添加多个矩形对应一级菜单栏;添加一个动态面板(命名为二级菜单),目的是点击一级菜单栏的时候,通过显示/隐藏该动态面板来控制是否展示二级菜单栏(具体怎么筛选二级菜单栏,下面再说) 2. 定义中继器元件中数据集(二级菜单栏) 在动态面板中添加一个中继器元件,用来显示二级菜单栏,中继器元件的主要作用就是通过修改/新增/删除中继器的参数可以达到修改/新增/删除二级子菜单的目的,同时点击一级菜单栏时保证可以以一定的逻辑展示对应的二级子菜单。 在中继器元件中添加列"name"作为二级菜单栏名称;添加列"sjid"将二级菜单和一级菜单栏联系在一起(用数据库的思维可以理解为对应一级菜单栏的外键);将一级菜单栏进行编号,如:商品管理对应1,销售管理对应2…;将二级菜单栏名称和一级菜单栏编号分别添加到中继器的数据集中,如下图所示: 3. 根据二级菜单栏名称跳转对应的页面 在点击二级菜单栏需要做的交互动作肯定是跳转到对应的页面,而中继器中只有一个矩形,所以需要根据某个条件进行判断点击这个矩形之后到底应该要跳转去哪里;另外在二级菜单中也需要显示对应的二级菜单栏名称。 为了实现显示二级菜单栏的名称,添加交互动作,即中继器每次加载时,需要设置矩形的文字为对应的二级菜单栏名字,这里可以使用函数[[item.name]];如下图: 为了实现点击二级菜单栏跳转对应的页面,可以设置点击的时候根据矩形内显示文字进行判断需要调转的页面; 另外,由于点击之后跳转到新的页面了,如果想让进入该页面的时候直接将对应的一级菜单栏下面的二级菜单栏全部展示出来,可以设置一个全局变量(如这里设置全局变量为"ejcdqjbl"),那么在加载新页面的时候就可以根据这个全局变量来控制二级菜单栏的展示;如下图所示: 4. 实现二级菜单列表展开收起的效果 为了实现点击一级菜单栏可以切换二级菜单列表的展开和收起的效果,可以给一级菜单栏添加交互效果。 需要实现该效果的逻辑为:点击一次菜单栏,如果对应的二级菜单列表已展开,那么就收起这个二级菜单列表;如果对应的二级菜单列表未展开,那么则先需要关闭其他的二级菜单列表,再展开对应的二级菜单列表。 # 判断当前的二级菜单是否展开:需判断动态面板的顶部是否和该一级菜单矩形有交集(用局部变量LVAR1来代替动态面板名称,方便函数的使用,[[LVAR1.top]]函数作用是定义原件顶部坐标;而[[This.bottom]]函数的作用是定义元件底部坐标);同时需要判断二级菜单对应的动态面板是否可见。 # 如果上一步判断为否的话,那么可以直接隐藏二级菜单对应的动态面板,并显示该一级菜单对应的二级菜单列表; 根据以上逻辑,那么如何控制打开的是该一级菜单对应的二级菜单列表,以及如何控制该二级菜单列表显示的位置就成为主要问题 所以先隐藏二级菜单动态面板: 再清除之前对中继器数据的筛选,再添加新的对中继器筛选的条件;同样也可以添加局部变量,将中继器元件定义为局部变量LVAR1,根据该二级菜单栏的name筛选对应sjid的中继器元件。 设置动态面板显示的尺寸:宽度可以设置一个固定的值,而高度的值则可以设置为需要显示的二级菜单栏数量*对应元件的高度 设置二级菜单动态面板的位置:移动动态面板至一级菜单栏的底部的位置[[LVAR1.left]],并和一级菜单栏的左边对齐[[LVAR1.bottom]];如下图所示 最后显示二级菜单动态面板,整体交互动作图下图所示: 5. 页面加载时能自动展开对应的二级菜单列表 之前设置二级菜单栏元件的交互动作的时候,也添加了一个全局变量,用于页面加载时二级菜单列表的展示; 这里的交互及引用的函数基本和上面的差不多,但是在添加对中继器中的二级菜单栏筛选的时候,需要将全部变量ejcdqjbl的值赋给局部变量LVAR1,这个时候函数[[TargetItem.fid==LVAR1]]就会根据局部变量LVAR1的值对中继器进行筛选。 小结 文中中继器的效果最终其实也可以用动态面板来组合实现,这个其实之前有尝试过,但是由于制作比较繁琐而且不容易维护,所以果断放弃了这种做法。 另外,在摸索如何设计菜单的过程中,也在一些社交群里面咨询同道,得到的统一的回复:"原型不重要,道理讲清楚就行…";个人觉得这些话还是被滥用了,一棍子打死了想去完善原型设计技巧的人而不看人家这样做的原因 至于我的原因比较简单: 给领导出一个能交互的原型,模拟真实的操作效果; 之前每次新做一个后台都需要重新画菜单,中间遇到要对菜单进行调整还需要花很多时间;最终这两个问题以一个较小的代价得以完美的解决。 总而言之,原型设计要不要做这么复杂,我的答案是"需要做就做!"