情景
Vue+Element 实现管理页面菜单栏,
点击菜单时 router 改变 hash 访问不同子组件。
但是改变 hash 时菜单栏展开状态和 highlight 并不会同步,
需要手动实现。
Try Try See
第一反应是通过 onhashchange 监听 hash 的变化,
讲 location.hash.slice(2)
推给 menu 的 default-active
即可。
此时通过手动输入 url 或者前进后退时均可正常加载对应状态,但是通过组件中的 link 访问时,menu 的状态没有改变。
加入 alert 验证发现没有触发 hashchange。
Why
Seafault 的解释是
Vue-Router 底层调用的是
history.pushState
查阅 MDN 发现
注意
pushState()
绝对不会触发 hashchange 事件,即使新的 URL 与旧的 URL 仅哈希不同也是如此。
Solution
Vue-Router 的文档中给出两个方案
- watch $route 对象
const User = {
template: '...',
watch: {
$route(to, from) {
// react to route changes...
}
}
}
- 使用 beforeRouteUpdate
const User = {
template: '...',
beforeRouteUpdate(to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
此时还有最后一个问题,直接访问带 hash 的路径时,菜单的状态也不正确,
设置一个变量 activePath 来控制 default-active
在 created()
中加入 this.activePath = location.hash.slice(2)
在构建元素时修改菜单状态
另外
原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。