el-menu:浩瀚无垠


el-menu:浩瀚无垠

0. 缘起

遇到了一个需要展现多级列表的需求,之前写的版本就是我嗯写死的二级菜单,现在想来个Updated版本,所以需要我这里调整。抄了组长整的无极列表组件,不过我还需要对项目兼容进行一些调整。

1. v-if与v-for的循环产生el-menu-item与el-submenu

这个版本的可以实现想要的无极效果,不过时不时element.js爆个堆栈溢出的错误,看的那叫个不爽啊。组长表示可以用高端的函数式组件,直接生成对应render模板就好。事实上那个方法确实比这个版本的好很多~~

Element NavMenu 无限级菜单 - tianyawhl的个人空间 - OSCHINA - 中文开源技术交流社区

2. 函数式组件

函数式组件,我们可以理解为没有内部状态,没有生命周期钩子函数,没有 this(不需要实例化的组件)

Vue JSX、自定义 v-model - 你的美好,我都记得 (ainyi.com)

2.1 何时用到函数式组件?

在作为包装组件时它们也同样非常有用。比如,当你需要做这些时:

  • 程序化地在多个组件中选择一个来代为渲染;
  • 在将 childrenpropsdata 传递给子组件之前操作它们。

2.2 数据传输

组件需要的一切都是通过 context 参数传递,它是一个包括如下字段的对象:

  • props:提供所有 prop 的对象
  • children:VNode 子节点的数组
  • slots:一个函数,返回了包含所有插槽的对象
  • scopedSlots:(2.6.0+) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。
  • data:传递给组件的整个数据对象,作为 createElement 的第二个参数传入组件
  • parent:对父组件的引用
  • listeners:(2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。这是 data.on 的一个别名。
  • injections:(2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的 property。

渲染函数 & JSX — Vue.js (vuejs.org)

2.3 封装组件





2.4 使用组件

注意这里需要将扁平结构转化为树形

JS树结构操作:查找、遍历、筛选、树结构和列表结构相互转换 - 沐码小站 (wintc.top)

   routers: {
      get() {
        let routers = this.$store.state.routers.map((key) => ({
          name: key.router.toUpperCase(),
          path: "/" + key.router,
          id: key.uiWebId,
          parentId: key.parentId,
          meta: {
            hidden: false,
            link: true,
            description: key.menuName,
          },
        }));
        let transferRouters = convertMenus(routers, "parentId");
        console.log('transferRouters: ', transferRouters);
        return transferRouters;

        function convertMenus(list, pid = "pid", id = "id") {
          let info = list.reduce(
            (map, node) => (
              (map[node[`${id}`]] = node), (node.routerChildren = []), map
            ),
            {}
          );
          return list.filter((node) => {
            info[node[`${pid}`]] &&
              info[node[`${pid}`]].routerChildren.push(node);
            return !node[`${pid}`];
          });
        }
      },
    },

2.5 补充的样式代码

CSS苦手,写这个真的头皮发麻,所以用了! important,丑陋至极!

.frame_window_out {

  .el-menu-demo {
    margin-left: 34%;
  }

  .el-menu.el-menu--horizontal {
    border: 0;
  }

  .el-submenu:focus .el-submenu__title,
  .el-submenu:hover .el-submenu__title {
    color: #ffffff;
    background-color: transparent;
  }

  .el-menu {
    background-color: transparent;

    .el-submenu:focus .el-submenu__title,
    .el-submenu:hover .el-submenu__title {
      background-color: rgba(23, 78, 112, 0.7) !important;
    }
    .el-menu-item,
    .el-submenu .el-submenu__title {
      color: #ffffff;
      height: 40px;
      margin: 8px;
      border-radius: 4px;
      line-height: 40px;

      i {
        color: #ffffff;
      }
    }

    .el-menu-item:hover,
    .el-menu-item:focus {
      background-color: transparent !important;
      background-position: center;
    }

    .el-menu-item-group {
      .el-menu-item-group__title {
        color: #ffffff;
      }
    }

    .el-menu--horizontal .el-menu-item:not(.is-disabled):focus,
    .el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
      background-color: #088dc1;
    }
  }
}

.menu-popup .el-menu--popup .el-menu-item {

  background-color: rgba(23, 78, 112, 0.7) !important;
  &:hover,
  &:focus {
    background-color: rgba(16, 130, 201, 0.7) !important;
  }
}

3. JSX

在Vue中使用JSX,很easy的 - 掘金 (juejin.cn)

Vue JSX、自定义 v-model - 你的美好,我都记得 (ainyi.com)