一个左侧导航栏的选中状态把我迷得颠三倒四

10,410 阅读3分钟

事情是这样的 👇

前段时间我用arco.design这个组件库默认的模板项目开放,刚开始需求是这样的:总共八个页面,其中四个显示在导航栏,四个不在导航栏显示,可以导航的页面里又有俩个需要登录才能访问,俩个不登录就能访问。听着是有些绕不过开发起来不是SO EASY吗😎

我用的是vue版本的,说白了就一个知识点——路由和菜单。凭借我的聪明才智,肯定一看就会。

路由

首先,需要先了解一下路由表的配置。基本的路由配置请参阅 Vue-Router 官方文档

// 在本例子中,页面最终路径为 /dashboard/workplace
export default {
 path: 'dashboard',
 name: 'dashboard', // 路由名称
 component: () => import('@/views/dashboard/index.vue'),
 meta: {
   locale: 'menu.dashboard',
   requiresAuth: true,
   icon: 'icon-dashboard',
 },
 children: [
   {
     path: 'workplace',
     name: 'workplace',
     component: () => import('@/views/dashboard/workplace/index.vue'),
     meta: {
       locale: 'menu.dashboard.workplace',
       requiresAuth: true,
       roles: ['admin'],
       hideInMenu: false,
     },
   },
 ],
};

路由 Meta 元信息

参数名说明类型默认值
roles配置能访问该页面的角色,如果不匹配,则会被禁止访问该路由页面string[]-
requiresAuth是否需要登录鉴权booleanfalse
icon菜单配置iconstring-
locale一级菜单名(语言包键名)string-
hideInMenu是否在左侧菜单中隐藏该项boolean-
hideChildrenInMenu强制在左侧菜单中显示单项boolean-
activeMenu高亮设置的菜单项string-
order排序路由菜单项。如果设置该值,值越高,越靠前number-
noAffix如果设置为true,标签将不会添加到tab-bar中boolean-
ignoreCache如果设置为true页面将不会被缓存boolean-

hideInMenu 控制菜单显示, requiresAuth 控制是否需要登录,没错,以上知识点完全够我用了🤏🤏🤏🤏

三下五除二就开发完成了,正当我沉浸在成功的喜悦时,测试给我提了个bug。

说导航栏目切换,选中状态有俩个正常,俩个不正常,切换页面导航没选中,再点一次才会选中。我擦👏👏👏👏👏,我傻眼了😧😧😧

到底哪里出了问题,我哪里写错了呢,人家官方肯定没问题,于是我开始寻找。是路由名称重复了,还是那个组件写的有问题,还好有俩个正常的,我仔细比对一下不就好了吗,我可真是个小机灵鬼。

就这样,我又一次为我的自大付出了汗水,对比了一天,我感觉好像真不是我写的有问题,不过还是有收获的,我发现requiresAuth 设置为true的导航正常,requiresAuth设置为false的不正常。抱着怀疑的态度我开始找原来模板项目中处理requiresAuth的代码。最后在components》menu》index.vue文件下发现一个方法:

listenerRouteChange((newRoute) => {
   const { requiresAuth, activeMenu, hideInMenu } = newRoute.meta;
   if (requiresAuth && (!hideInMenu || activeMenu)) { 
     const menuOpenKeys = findMenuOpenKeys(
       (activeMenu || newRoute.name) as string
     );

     const keySet = new Set([...menuOpenKeys, ...openKeys.value]);
     openKeys.value = [...keySet];

     selectedKey.value = [
       activeMenu || menuOpenKeys[menuOpenKeys.length - 1],
     ];
   }
 }, true);

这... ... 我人麻了,这不是只有requiresAuth 为true的时候才会有效吗?他为啥这么写呢?还是我复制项目的时候复制错了?然后我改成了

listenerRouteChange((newRoute) => {
   const { requiresAuth, activeMenu, hideInMenu } = newRoute.meta;
   if ((requiresAuth === true || requiresAuth === false) && (!hideInMenu || activeMenu)) { 
     const menuOpenKeys = findMenuOpenKeys(
       (activeMenu || newRoute.name) as string
     );

     const keySet = new Set([...menuOpenKeys, ...openKeys.value]);
     openKeys.value = [...keySet];

     selectedKey.value = [
       activeMenu || menuOpenKeys[menuOpenKeys.length - 1],
     ];
   }
 }, true);

🙈🙈🙈🙈🙈看出来我改哪里了吗,考考你们的眼力,我改的方法是不是很nice。 反正好使了,下班!!!!