Commit c6218fb5 authored by tianhongyang's avatar tianhongyang

左侧菜单封装

parent a3dec409
...@@ -1074,6 +1074,8 @@ export function addTreeLevel(tree, startLevel = 1, removeEmptyChildren = true) { ...@@ -1074,6 +1074,8 @@ export function addTreeLevel(tree, startLevel = 1, removeEmptyChildren = true) {
removeEmptyChildren && !tree.children?.length ? delete tree.children : null; removeEmptyChildren && !tree.children?.length ? delete tree.children : null;
} }
} }
return tree;
} }
/** /**
...@@ -1087,10 +1089,12 @@ export function addNodeParent(tree, parent = null) { ...@@ -1087,10 +1089,12 @@ export function addNodeParent(tree, parent = null) {
addNodeParent(node, parent); addNodeParent(node, parent);
}); });
} else if (Object.prototype.toString.call(tree) == "[object Object]") { } else if (Object.prototype.toString.call(tree) == "[object Object]") {
tree["parent"] = parent; tree["parent"] = JSON.parse(JSON.stringify(parent));
if (tree?.children?.length) { if (tree?.children?.length) {
addNodeParent(tree.children, tree); addNodeParent(tree.children, tree);
} }
} }
return tree;
} }
\ No newline at end of file
...@@ -2,7 +2,16 @@ ...@@ -2,7 +2,16 @@
<div class="feed-summary-container"> <div class="feed-summary-container">
<div class="feed-summary-inner"> <div class="feed-summary-inner">
<div class="left-side-menu"> <div class="left-side-menu">
<project-side-menu :menuTree="menuTreeList" :unique-opened="false" :default-active="defaultActive"></project-side-menu> <project-side-menu :menuTree="menuTreeList" :unique-opened="false" :default-active="defaultActive">
<template slot="房建类成本科目-1">
<img src="@/assets/images/projectCostLedger/icon_cost_detail_2.svg" alt="">
<div class="project-sub-menu-title-text">房建类成本科目</div>
</template>
<template slot="未归类项目-1">
<img src="@/assets/images/projectCostLedger/icon_cost_detail_3.svg" alt="">
<div class="project-sub-menu-title-text">未归类项目</div>
</template>
</project-side-menu>
</div> </div>
</div> </div>
</div> </div>
...@@ -60,15 +69,15 @@ export default { ...@@ -60,15 +69,15 @@ export default {
}, },
{ {
nodeName: "专业分包工程", nodeName: "专业分包工程",
id: "2", id: "2-1",
}, },
{ {
nodeName: "实体工程材料(土建)", nodeName: "实体工程材料(土建)",
id: "3", id: "3-1",
}, },
{ {
nodeName: "其他直接费成本", nodeName: "其他直接费成本",
id: "4", id: "4-1",
}, },
] ]
}, },
......
...@@ -3,15 +3,37 @@ ...@@ -3,15 +3,37 @@
<template> <template>
<!-- 有下级菜单 --> <!-- 有下级菜单 -->
<template v-if="checkHasChidren"> <template v-if="checkHasChidren">
<el-submenu :index="menuItem.nodeValue" ref="projectSubMenuItem" class="project-sub-menu-item"> <el-submenu :index="menuItem.nodeValue" ref="projectSubMenuItem" class="project-sub-menu-item"
:class="`project-sub-menu-item-level-${menuItem.level}`" :disabled="menuItem.originData && menuItem.originData.disabled">
<template slot="title"> <template slot="title">
<i class="el-icon-location"></i> <!-- 预留插槽 -->
<span>111</span> <div class="project-sub-menu-title" :class="{'project-sub-menu-title-next' : menuItem.level !== 1}" :style="menuStyles(menuItem)">
<slot :name="`${menuItem.nodeName}-${menuItem.level}`" :data="menuItem">
<img src="" alt="" v-if="menuItem.originData && menuItem.originData.icon">
<div class="project-sub-menu-title-text">{{menuItem.nodeName}}</div>
</slot>
</div>
</template> </template>
<!-- 子集递归 -->
<project-menu-item v-for="(child,index) of menuItem.children" :menuItem="child" :key="child.nodeValue"></project-menu-item>
</el-submenu> </el-submenu>
</template> </template>
<!-- 无子集菜单 -->
<template v-else> <template v-else>
<el-menu-item :index="menuItem.nodeValue" class="project-only-menu-item" :class="`project-only-menu-item-level-${menuItem.level}`"
:disabled="menuItem.originData && menuItem.originData.disabled">
<template slot="title">
<div class="project-only-menu-title-container">
<!-- 预留插槽 -->
<div class="project-only-menu-title" :class="{'project-only-menu-title-next' : menuItem.level !== 1}" :style="menuStyles(menuItem)">
<slot :name="`${menuItem.nodeName}-${menuItem.level}`" :data="menuItem">
<img src="" alt="" v-if="menuItem.originData && menuItem.originData.icon">
<div class="project-only-menu-title-text">{{menuItem.nodeName}}</div>
</slot>
</div>
</div>
</template>
</el-menu-item>
</template> </template>
</template> </template>
</div> </div>
...@@ -39,11 +61,25 @@ export default { ...@@ -39,11 +61,25 @@ export default {
computed: { computed: {
checkHasChidren() { checkHasChidren() {
return !!(this.menuItem && this.menuItem?.children && this.menuItem.children.length); return !!(this.menuItem && this.menuItem?.children && this.menuItem.children.length);
} },
}, },
//方法集 //方法集
methods: { methods: {
menuStyles(menuItem) {
const { level } = menuItem;
const styles = {
};
let paddingLeft = 0;
if (level == 1) {
paddingLeft = 12;
styles["font-weight"] = "bold";
} else {
paddingLeft = (level - 1) * 12 + 20;
}
styles["padding-left"] = `${paddingLeft}px`;
return styles;
}
}, },
} }
</script> </script>
......
...@@ -3,7 +3,11 @@ ...@@ -3,7 +3,11 @@
<el-menu mode="vertical" class="project-side-menu-instance" :unique-opened="uniqueOpened" :default-active="defaultActive" @select="menuSelect" <el-menu mode="vertical" class="project-side-menu-instance" :unique-opened="uniqueOpened" :default-active="defaultActive" @select="menuSelect"
@open="subMenuOpen" @close="subMenuClose"> @open="subMenuOpen" @close="subMenuClose">
<template v-for="(item,index) of tempMenuTree"> <template v-for="(item,index) of tempMenuTree">
<project-menu-item :menuItem="item" :key="item.nodeValue"></project-menu-item> <project-menu-item :menuItem="item" :key="item.nodeValue">
<template :slot="`${item.nodeName}-${item.level}`" slot-scope="scope">
<slot :name="`${scope.data.nodeName}-${scope.data.level}`" :data="scope.data"></slot>
</template>
</project-menu-item>
</template> </template>
</el-menu> </el-menu>
</div> </div>
...@@ -88,7 +92,27 @@ export default { ...@@ -88,7 +92,27 @@ export default {
this.$emit("close", menuPath); this.$emit("close", menuPath);
}, },
menuSelect(menuPath) { menuSelect(menuPath) {
this.$emit("select", menuPath); const result = this.getCurrentData(menuPath);
this.$emit("select", menuPath, result);
},
getCurrentData(only) {
const _tempTree = JSON.parse(JSON.stringify(this.tempMenuTree));
if (_tempTree) {
function findNode(tree = [], target) {
if (tree instanceof Array) {
for (const item of tree) {
if (item.nodeValue === target) return item;
if (item.children instanceof Array && item.children.length) {
const _temp = findNode(item.children, target);
if (_temp) return _temp;
}
}
}
}
const result = findNode(_tempTree, only);
return result;
}
return null;
}, },
// 初始化树形结构 // 初始化树形结构
initMenuTree(array = []) { initMenuTree(array = []) {
...@@ -98,7 +122,6 @@ export default { ...@@ -98,7 +122,6 @@ export default {
this.tempMenuOptions = _options; this.tempMenuOptions = _options;
// 映射配置 // 映射配置
const resultData = this.mapDataByMenuOptions(JSON.parse(JSON.stringify(this.comMenuTree)), _options); const resultData = this.mapDataByMenuOptions(JSON.parse(JSON.stringify(this.comMenuTree)), _options);
console.log(resultData);
if (resultData) { if (resultData) {
this.tempMenuTree = resultData; this.tempMenuTree = resultData;
} }
...@@ -116,7 +139,7 @@ export default { ...@@ -116,7 +139,7 @@ export default {
// 分组源数据 // 分组源数据
const _groupData = this.groupData(menuList, options); const _groupData = this.groupData(menuList, options);
// 映射过后的树 // 映射过后的树
const _mapedData = this.mapData(_groupData, options); const _mapedData = this.mapData(JSON.parse(JSON.stringify(_groupData)), options);
// 处理层级 以及删除空children // 处理层级 以及删除空children
return this.buildTree(_mapedData); return this.buildTree(_mapedData);
}, },
...@@ -162,9 +185,9 @@ export default { ...@@ -162,9 +185,9 @@ export default {
buildTree(mapedData) { buildTree(mapedData) {
if (mapedData?.length) { if (mapedData?.length) {
// 添加层级 // 添加层级
addTreeLevel(mapedData); const levelResult = addTreeLevel(mapedData);
addNodeParent(mapedData); const parentResult = addNodeParent(levelResult);
return mapedData; return parentResult;
} }
} }
}, },
...@@ -183,10 +206,48 @@ export default { ...@@ -183,10 +206,48 @@ export default {
overflow: auto; overflow: auto;
/* 重置一级二级菜单 高度行高 */ /* 重置一级二级菜单 高度行高 */
.project-menu-item-container {
/* 有下级菜单 */
.project-sub-menu-item { .project-sub-menu-item {
& > .el-submenu__title { & > .el-submenu__title {
height: 32px; height: 32px;
line-height: 32px; line-height: unset;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 12px;
padding-left: 0px !important;
.project-sub-menu-title {
display: flex;
align-items: center;
width: calc(100% - 12px);
height: 100%;
color: #232323;
font-size: 13px;
font-weight: 350;
.project-sub-menu-title-text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
& > img {
width: 16px;
height: 16px;
margin-right: 4px;
}
}
.el-submenu__icon-arrow {
right: 12px;
font-size: 12px;
position: static;
margin-top: 0px;
width: 12px;
min-width: 12px;
}
&:hover { &:hover {
background-color: unset; background-color: unset;
...@@ -198,6 +259,74 @@ export default { ...@@ -198,6 +259,74 @@ export default {
} }
} }
} }
/* 无下级菜单 */
.project-only-menu-item {
height: unset;
line-height: unset;
font-size: unset;
padding: 0px !important;
color: unset;
cursor: unset;
position: unset;
white-space: unset;
/* 选中 */
&.is-active {
.project-only-menu-title-container {
background-color: unset;
background: linear-gradient(
91deg,
rgba(0, 129, 255, 0.1) 0%,
rgba(0, 129, 255, 0) 100%
);
.project-only-menu-title {
color: #0081ff;
}
}
}
.project-only-menu-title-container {
height: 32px;
line-height: unset;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 12px;
padding-left: 0px !important;
&:hover {
background-color: unset;
background: linear-gradient(
91deg,
rgba(0, 129, 255, 0.1) 0%,
rgba(0, 129, 255, 0) 100%
);
}
.project-only-menu-title {
display: flex;
align-items: center;
width: 100%;
height: 100%;
color: #232323;
font-size: 13px;
font-weight: 350;
cursor: pointer;
.project-only-menu-title-text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
& > img {
width: 16px;
height: 16px;
margin-right: 4px;
}
}
}
}
}
} }
} }
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment