iView 的 Menu 菜单展开后怎么保持高亮选中状态?
我在用 iView 的 Menu 组件做侧边栏导航,点击菜单项跳转路由后,页面刷新了,菜单就收起来了,而且当前页面对应的菜单项也没有高亮。我试过用 :active-name 绑定当前路由路径,但好像没生效。
这是我的菜单代码:
<Menu :active-name="currentPath" width="auto" @on-select="handleSelect">
<MenuItem name="/dashboard">首页</MenuItem>
<MenuItem name="/users">用户管理</MenuItem>
</Menu>
在 created 里我设置了 this.currentPath = this.$route.path,但刷新后高亮还是没了,是不是哪里漏了?
问题主要有两个地方:一个是 Menu 组件挂载时 active-name 还没更新进去,另一个是没有设置 open-names 来控制展开。
试试这个方案:
给 Menu 加上 ref 和 open-names 属性:
然后在 data 里加上 openNames 数组,关键是在 mounted 或 created 里手动调用更新方法:
核心就是那两个方法:updateActiveName() 和 updateOpened()。iView 内部缓存了状态,单纯改绑定的值它不认,必须手动调这两个方法强制刷新。
如果你是多层嵌套菜单,openNames 里要放所有父级菜单的 name,比如 ['system', 'user-manage'] 这样一路下去。
还有个常见的坑,如果你用了 keep-alive 缓存页面,切换时也要在 activated 钩子里再调一次这两个方法,不然从别的页面回来高亮又没了。
active-name是响应式的,但页面刷新时组件重新挂载,created里的赋值可能被后续路由守卫或异步逻辑覆盖,或者你绑定的值根本没跟上路由变化。首先确认你是不是用的 Vue Router,如果是的话,推荐用
active-name绑定当前路由的完整路径,但要确保这个值在页面刷新后能第一时间拿到。比如你可以这样写:
但要注意,iView 的 Menu 有个坑:它默认只认
name属性完全匹配的菜单项,所以如果你的路由是/users/1,而菜单项写的是/users,那肯定不亮。另外,如果你用的是 Vue Router 的 history 模式,还得保证菜单项的
name和路由的path严格一致(比如都带斜杠)。如果还是不行,可以加个
async created,等路由初始化完成再赋值:不过最稳妥的还是用
watch $route监听路由变化,配合beforeRouteUpdate(Vue Router 2.0+)做兜底:你试试先加个 watch,再检查下菜单项的
name是不是和路由 path 对得上——很多人的 bug 就出在这一步,看着一样,其实差个斜杠或者大小写。