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 何时用到函数式组件?
在作为包装组件时它们也同样非常有用。比如,当你需要做这些时:
- 程序化地在多个组件中选择一个来代为渲染;
- 在将
children
、props
、data
传递给子组件之前操作它们。
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)