返回

一探 ElMenu 中的NavItem重现mount 的深层原因

前端

在 ElMenu 中,我们经常会遇到这样的场景:点击菜单项时,NavItem 会重新 mount。这可能会导致一些性能问题,尤其是当菜单项数量很多时。那么,是什么原因导致了这种情况呢?让我们一探究竟。

首先,让我们来看看 ElMenu 的组件结构。基本的结构如下:

<el-menu>
  <el-menu-item>...</el-menu-item>
  <el-menu-item>...</el-menu-item>
  ...
</el-menu>

当我们点击一个菜单项时,ElMenu 会触发一个名为 handleItemClick 的方法。在这个方法中,ElMenu 会更新 activeIndex 属性,并根据 activeIndex 的值来决定哪个菜单项是活动的。

handleItemClick(index) {
  this.activeIndex = index;
}

然后,ElMenu 会渲染 NavItem 组件。NavItem 组件是菜单项的实际内容,它会根据 activeIndex 属性来决定是否显示。

<template>
  <li :class="['el-menu-item', {
    'is-active': index === activeIndex
  }]">
    <slot></slot>
  </li>
</template>

NavItem 组件中,我们使用 v-if 指令来控制是否显示组件。

<template>
  <li v-if="index === activeIndex" :class="['el-menu-item', {
    'is-active': index === activeIndex
  }]">
    <slot></slot>
  </li>
</template>

activeIndex 属性发生变化时,v-if 指令会重新计算,从而导致 NavItem 组件重新 mount。

所以,问题就出在 activeIndex 属性上。当我们点击一个菜单项时,activeIndex 属性会更新,从而导致 NavItem 组件重新 mount。

为了解决这个问题,我们可以使用 keep-alive 指令来缓存 NavItem 组件。这样,NavItem 组件就不会在每次更新时重新 mount 了。

<template>
  <keep-alive>
    <el-menu-item v-if="index === activeIndex" :class="['el-menu-item', {
      'is-active': index === activeIndex
    }]">
      <slot></slot>
    </el-menu-item>
  </keep-alive>
</template>

通过使用 keep-alive 指令,我们可以解决 NavItem 组件重新 mount 的问题,从而提高性能。