Element: [Bug Report] NavMenu: Problem with active menu with 'beforeRouteLeave()' vue-router

Created on 13 Nov 2017  ·  4Comments  ·  Source: ElemeFE/element

Element UI version

2.0.4

OS/Browsers version

Win10 / Chrome 62

Vue version

2.5.3

Reproduction Link

https://jsfiddle.net/marceloavf/8xrk1n9f/310/

Steps to reproduce

  • Try to change the route to another page by clicking the NavMenu (/about)
  • Cancel the change, the route still the same but the menu goes to the route that you have cancelled

What is Expected?

  • Follow the exactly route change, if you cancel in beforeRouteLeave, the active route should stay the same

What is actually happening?

  • It's changing the active menu to the wrong route instead stay the same
menu pending

Most helpful comment

@marceloavf,I finally find the solution. Just remove the default-active attribute, and add "is-active" class by yourself. Here is my code:

<el-menu :default-openeds="onRouteKeys" class="el-menu-style" router :collapse="sidebar.collapsed && !device.isMobile" @select="handleSelect">
   <template v-for="item in menuList">
      <sub-menu :param="item" :class="{'is-active2': onRoutes === item.href}"></sub-menu>
  </template>
</el-menu>

<script>
export default {
  data() {
    return {};
  },
  computed: {
    onRoutes() {
      return this.$route.path;
    },
  }
}
</script>

menuList is the routes I defined, every element has a attribute "href", such as:

const routerArr = [{
  "id": 1,
  "parentId": null,
  "sort": 0,
  "name": "推广管理",
  "href": "/spread",
  "icon": "iconfont icon-spread",
  "children": [],
  "isShow": "1"
}]

if $route.path === item.href , add a diffrent class name(here I call "is-active2", don't be same as the default active class name)

All 4 comments

I realize that the problem is with handleItemClick(item) in packages/menu/src/menu.vue

To change the activeIndex it first need to check if this.router is true, so then it'll need to wait for some beforeRoute... or keep track of actual this.$route.path

handleItemClick(item) {
  let { index, indexPath } = item;
  if (!this.router) {
    this.activeIndex = item.index;
  }
  this.$emit('select', index, indexPath, item);
  if (this.mode === 'horizontal' || this.collapse) {
    this.openedMenus = [];
  }
  if (this.router) {
    this.activeIndex = this.$route.path;
    this.routeToItem(item);
  }
},

Any advice ?

I have the same problem. The only resolution I can found is changing the class name of the el-sub-menu element, but it will bring new problems.

@marceloavf,I finally find the solution. Just remove the default-active attribute, and add "is-active" class by yourself. Here is my code:

<el-menu :default-openeds="onRouteKeys" class="el-menu-style" router :collapse="sidebar.collapsed && !device.isMobile" @select="handleSelect">
   <template v-for="item in menuList">
      <sub-menu :param="item" :class="{'is-active2': onRoutes === item.href}"></sub-menu>
  </template>
</el-menu>

<script>
export default {
  data() {
    return {};
  },
  computed: {
    onRoutes() {
      return this.$route.path;
    },
  }
}
</script>

menuList is the routes I defined, every element has a attribute "href", such as:

const routerArr = [{
  "id": 1,
  "parentId": null,
  "sort": 0,
  "name": "推广管理",
  "href": "/spread",
  "icon": "iconfont icon-spread",
  "children": [],
  "isShow": "1"
}]

if $route.path === item.href , add a diffrent class name(here I call "is-active2", don't be same as the default active class name)

handleSelect(v) {
if (v !== this.$route.path) {
this.$refs.menu.activeIndex = this.$route.path
}
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chenzhe-pro picture chenzhe-pro  ·  3Comments

smallpath picture smallpath  ·  3Comments

mochenxm picture mochenxm  ·  3Comments

yuchonghua picture yuchonghua  ·  3Comments

no5no6 picture no5no6  ·  3Comments