11. element动态数据路由,侧边栏的点击效果以及刷新页面效果不丢失

381 阅读2分钟

需求:

项目首页的侧边栏数据,是需要通过接口获取进行配置(不同类型的用户看到的侧边路由不一样)。

因为element的导航菜单的样式与需求有些不一致:

1.一级菜单(工作台、消息中心)的点击样式与sub菜单的一级菜单(权限管理)需要保持一致,这里element的sub菜单的点击样式是没有的,需要单独修改

2.sub菜单的二级菜单(权限管理、用户管理)的点击样式,element默认与一级菜单一致,这里需要单独对sub菜单中的二级菜单进行修改

动态数据路由的效果.gif

el-menu的注意方法

ref: 方便调用指定菜单的close方法

default-active: 当前激活菜单的index

open:展开sub菜单的回调函数,可以获取到对应的 index、path

el-menu-item的注意方法

click: 方便点击一级菜单时,关闭展开的sub菜单

<el-menu
    ref="elMenus"
      unique-opened
      class="el-menu-vertical-demo"
      :router="true"
      :default-active="defaultActive"
      @open="handleOpen"
      @select="handleSelect"
    >
      <template v-for="(item, index) in menuList">
        <!-- 一级菜单 -->
        <el-menu-item v-if="item.childList.length == 0" :key="index + 'index'" :index="item.path" @click="operation('close', item)">
          <img :src="require('../../assets/images/' + item.icon)" class="ico" />
          <span slot="title" class="font-r">{{ item.menu_name }}</span>
        </el-menu-item>
        <!-- submenu菜单 -->
        <el-submenu v-else class="sub-menu" :key="index" :index="item.path">
          <template slot="title">
            <img :src="require('../../assets/images/' + item.icon)" class="ico" />
            <span slot="title" class="font-r">{{ item.menu_name }}</span>
          </template>
          <el-menu-item-group>
            <el-menu-item
              v-for="(item2, index) of item.childList"
              :key="index + '12'"
              :index="item2.path"
              class="sub-item"
            >
              <span slot="title" class="font-r">{{ item2.menu_name }}</span>
            </el-menu-item>
          </el-menu-item-group>
        </el-submenu>
      </template>
    </el-menu>

配置方法

  1. 监听路由:获取到的新路由直接复制给defaultActive,因为每个一级菜单的index都配置了对应的pathdefaultActive直接激活对应的index,显示激活样式

  2. operation: 点击一级菜单时,关闭sub菜单

  3. handleOpen: 点击sub的一级菜单时,根据自带的index或者path,直接路由跳转到默认选中的二级菜单路由,因为监听了路由,自动激活样式

watch: {
    $route: {
      handler(newValue) {
        this.$nextTick(() => {
          this.defaultActive = newValue.path;
        });
      },
      immediate: true,
    },
  },
  
  methods: {
  // 1. 点击一级菜单时,关闭sub菜单
    operation(type, item) {
      // 关闭二级菜单
      if (type === 'close') {
        this.$refs.elMenus.close('/permission-manage');
      }
    },
  // 2.点击sub的一级菜单时,根据自带的index或者path,直接路由跳转到默认选中的二级菜单路由,因为监听了路由,自动激活样式
    handleOpen(path) {
      // this.defaultActive = '';
      this.$router.push({ path: path });
    },
  },

修改样式

// 1. 一级菜单激活样式
.el-menu-item {
    &.is-active {
      background-color: #4faa3d;
      span {
        color: #ffffff;
      }
    }
    &:hover {
      background-color: #4faa3d;
      span {
        color: #ffffff;
      }
    }
  }

// 2. sub菜单的一级菜单激活样式

  :deep(.sub-menu) {
  // 2.1 sub一级菜单的展开样式
    &.is-opened {
      .el-submenu__title {
        color: #ffffff;
        background-color: #4faa3d;
      }
    }
  // 2.2 sub一级菜单的鼠标移上样式
    .el-submenu__title:hover,
    .el-submenu__title.is-active {
      color: #ffffff;
      background-color: #4faa3d;
    }
  // 2.3 隐藏一级菜单的箭头
    .el-submenu__icon-arrow {
      display: none;
    }
    
    .el-menu-item-group {
      .el-menu-item {
        width: 148px;
        margin-bottom: 5px;
        padding: 0;
        min-width: 0;
        cursor: pointer;
      }
  // 2.4 sub菜单的子菜单的激活样式
      .sub-item:hover,
      .sub-item.is-active {
        position: relative;
        background-color: #fafafa;
        cursor: pointer;
        span {
          color: #4faa3d;
        }
      }
    }
  }