设计师自主设计的一款菜单
时间:2023-07-24 20:27:01 | 来源:网站运营
时间:2023-07-24 20:27:01 来源:网站运营
设计师自主设计的一款菜单:
背景:ant design的菜单很好用,我们有优秀的设计师,给出了如下图的菜单交互
曲溜拐弯的菜单https://www.zhihu.com/video/1569800953997488129Update at 2023.02.16
竟然这么快这款菜单就被迭代掉了,在使用的过程中这款菜单有两个硬伤。
- 原文中也有提到hover展开二级菜单时会抖动,菜单原来越多,问题也没放大最终导致无法接受。改成了二级菜单从右侧划出,从交互上避免了抖动。
- 为了修改1的问题,把hover改成了click交互,又发现菜单选中和hover无法做到很好的区分,只好打开菜单即展示内凹进去的造型,会出现同时多个菜单被打开,样式很难看。
新的菜单同时解决了上边两个问题。如下图
注意点1:两个圆弧,一边向外凹,一边向里凸。
本来打算从antd的菜单做些CSS覆盖展示出来如效果图的样子,因为之前的调整都是这样干的,但是这次向里凹的造型没有办法通过border-radius来画出来。
注意点2: active和selected两种状态的记录
注意点3: full slim hide 三种状态的切换
注意点4: 二级菜单如何打开,点击 or hover
注意点5: 页面初始化时默认高亮对应菜单
最终,还是重新写一款全新的菜单组件吧,从交互和展示上已经跟antd差异太大,而且CSS因为缺少相应的dom也无法作出弧形的效果。刚开始不用想太复杂,菜单不就是一个for循环展示item就可以了么。然后有了二级菜单,只需要碰到subMenu的时候再加一层循环就行。分析到这,顺路说一下,TS还是香啊。提前把类型定义好,定义类型的过程其实也是梳理展示和依赖项的过程。
// https://github.com/n9e/fe-v5/blob/master/src/components/fc-menu/types.tsexport interface MenuItemProps { key: string; label: string; icon?: React.ReactNode;}export interface SubMenuProps extends MenuItemProps { children: MenuItemProps[];}export type IMenuProps = MenuItemProps | SubMenuProps | undefined;
两层循环后,基本就能呈现所有的菜单项了,两个圆弧都加上对应位置的dom然后通过border-radius绘制圆弧,并不复杂,不再赘述。
antd的Menu组件是通过useContent来在不同组件中传递状态,习惯了createglobalstate的写法,所以我是用了他来记录active和selected状态,并在full slim hide三个组件中共享状态。最后一点,也就是通过click事件来打开二级菜单还是hover打开二级菜单。其实大多是点击,但是设计师觉得hover打开,菜单有种手风琴交互的感觉,比较丝滑。但是菜单长短不一,加入hover一个有很多子菜单的一级菜单时,滑入下一个很少子菜单时会选不中。因为hover到太下边了,而长菜单收起了,短菜单并没有这么高的高度。
失去焦点的菜单https://www.zhihu.com/video/1569801247393226752因为一个菜单,比如用户管理(/user)下可能还包含用户详情(/user/detail/:id),用户列表(/user/list)多个页面,而具体判断当前页面处于哪个菜单有点太耦合业务了,不太好放在菜单组件来处理。参考了下antd的Menu也没处理,我也就没处理,其实要处理,只好把所有的[菜单]-> [路径] 的映射传入菜单,也可以解决。
开源代码:
https://github.com/n9e/fe-v5/tree/master/src/components/fc-menu我们的产品:Flashcat:让监控分析变简单
@fc-components/menu