Commit 133893b6 authored by 赵伟庚's avatar 赵伟庚

update:菜单管理左侧树形,交互

parent b07a29b8
...@@ -326,9 +326,17 @@ div { ...@@ -326,9 +326,17 @@ div {
} }
/* 设置tree的样式 */ /* 设置tree的样式 */
.el-tree {
position: static!important;
}
.el-tree-node__content{ .el-tree-node__content{
height: 36px; height: 36px;
} }
.el-tree-node__content:hover {
background-image: linear-gradient(90deg,
rgba(255, 255, 255, 0.05) 83%,
rgba(0, 0, 0, 0.05) 86%);
}
/* .usrrole .el-tree-node:focus>.el-tree-node__content{ /* .usrrole .el-tree-node:focus>.el-tree-node__content{
background: rgb(248, 249, 253) !important; background: rgb(248, 249, 253) !important;
} }
...@@ -1466,7 +1474,7 @@ border-radius:8px; ...@@ -1466,7 +1474,7 @@ border-radius:8px;
.flex_left { .flex_left {
background-color: #fff; background-color: #fff;
height: calc(100% - 20px); height: calc(100% - 16px);
width: 320px; width: 320px;
box-shadow: 0px 1px 4px 0px box-shadow: 0px 1px 4px 0px
rgba(0, 7, 101, 0.15); rgba(0, 7, 101, 0.15);
...@@ -1476,7 +1484,7 @@ border-radius:8px; ...@@ -1476,7 +1484,7 @@ border-radius:8px;
} }
.flex_right { .flex_right {
background-color: #fff; background-color: #fff;
height: calc(100% - 20px); height: calc(100% - 16px);
flex: 1; flex: 1;
box-shadow: 0px 1px 4px 0px box-shadow: 0px 1px 4px 0px
rgba(0, 7, 101, 0.15); rgba(0, 7, 101, 0.15);
...@@ -1485,15 +1493,19 @@ border-radius:8px; ...@@ -1485,15 +1493,19 @@ border-radius:8px;
} }
.tree::-webkit-scrollbar { .tree::-webkit-scrollbar {
width: 5px; width: 6px;
height: 5px; height: 6px;
} }
.tree::-webkit-scrollbar-thumb { .tree::-webkit-scrollbar-thumb {
background: #bcc1d0; background: #bcc1d0;
border-radius: 10px; border-radius: 10px;
height: 5px; height: 6px;
} }
.tree::-webkit-scrollbar-track { .tree::-webkit-scrollbar-track {
background: transparent; background: transparent;
border-radius: 2px; border-radius: 2px;
} }
.label-text {
font-size: 14px;
color: #404a62;
}
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
</div> </div>
<div class="flex_right"> <div class="flex_right">
<div class="main_container"> <div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入能力名称"> <bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入关键字">
<template v-slot:left_action> <template v-slot:left_action>
<div class="apaas_button"> <div class="apaas_button">
<el-button class="register_btn" type="primary" @click="register"> <el-button class="register_btn" type="primary" @click="register">
...@@ -179,7 +179,7 @@ const state = reactive({ ...@@ -179,7 +179,7 @@ const state = reactive({
timer: null, // 定时器 timer: null, // 定时器
headers: [ headers: [
{ {
label: "业务分类名称", label: "名称",
prop: "name", prop: "name",
}, },
{ {
......
<template> <template>
<div class="detail_container"> <div class="page_container">
菜单管理 <div class="bg-breadcrumb">
<el-breadcrumb separator="/">
<el-breadcrumb-item> 开发管理 </el-breadcrumb-item>
<el-breadcrumb-item > 菜单管理 </el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="flex_row">
<div class="flex_left">
<div class="tree_content">
<div class="search">
<el-input
v-model="search"
placeholder="请输入内容"
:prefix-icon="Search"
/>
</div>
<div class="tree">
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
:default-expand-all="true"
:highlight-current="true"
node-key="menu_id"
ref="menuTree"
>
<template #default="{ node, data }">
<div class="custom-tree-node" pointer-events="none">
<span
class="label-text text_clip"
:title="data.menu_name"
>{{ data.menu_name }}</span
>
</div>
<span class="tree-action-box">
<bg-icon
@click.stop="showAction($event, data,node)"
class="tree-more"
icon="#bg-ic-s-more"
></bg-icon>
</span>
</template>
</el-tree >
<Teleport to="body">
<div
class="tree-action"
ref="treeAction"
v-show="actionFlag"
:style="{ top: acTop, left: acLeft,bottom:acBottom }"
>
<div class="action" @click="fileAction(1,selectData,selectParentData)">
新建本级
</div>
<div class="action" @click="fileAction(2,selectData,selectParentData)">
新建下级
</div>
<div class="action" @click="fileAction(3,selectData,selectParentData)">
删除
</div>
<div class="action" :class="{'disable':moveIndex==0}" @click="fileAction(4,selectData,selectParentData,moveIndex==0)">
上移
</div>
<div class="action" :class="{'disable': !selectParentData ? moveIndex == data.length - 1 : moveIndex==selectParentData.Child.length-1}" @click="fileAction(5,selectData,selectParentData,!selectParentData ? moveIndex == data.length - 1 : moveIndex==selectParentData.Child.length-1)" >
下移
</div>
</div>
</Teleport>
</div>
</div>
</div>
<div class="flex_right">
<div class="main_container">
</div>
</div>
</div>
</div> </div>
</template> </template>
<script > <script setup>
import { reactive, toRefs, ref, } from '@vue/reactivity' import { Search } from '@element-plus/icons-vue'
import { getCurrentInstance } from 'vue' import { reactive, toRefs, ref, nextTick, computed, onBeforeMount, onBeforeUnmount } from 'vue'
import { computed, onBeforeMount } from '@vue/runtime-core'
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
export default { import { ElMessage } from 'element-plus'
components: { import axios from '../../../../request/http.js'
const router = useRouter();
const menuTree = ref(null)
const treeAction = ref(null)
const acTop = ref('');
const acLeft = ref('');
const acBottom = ref('');
const actionFlag = ref(false)
const state = reactive({
data: [],
search: "",
selectData:null,
selectParentData:null,
treeAction,
menuTree,
bottomGap:30,//弹窗吸底高度
defaultProps: {
children: 'Child',
label: 'menu_name',
}, },
setup() { actionDataIndex: 0,
})
const moveIndex = computed({
get: () => {
let index = 0
if(state.selectData) {
console.log(state.selectData)
findIndex(state.selectData.menu_id,state.data)
index = state.actionDataIndex
}
return index
}
})
const getMenuTree = () => {
axios
.get(`/apaas/system/v5/menu/tree`)
.then((res) => {
if (res.data.code == 200) {
state.data = res.data.data || []
nextTick().then(() => {
state.menuTree && state.menuTree.setCurrentKey(state.data[0].menu_id);
handleNodeClick(state.data[0]);
})
}else {
ElMessage.error(res.data.data)
}
})
}
const findIndex= (code,arr) => {
arr.forEach((e,i) => {
if (e.menu_id == code) {
state.actionDataIndex = i
console.log(e,i)
}else {
if (e.Child && e.Child.length > 0) {
findIndex(code,e.Child)
}
}
})
}
const showAction = (e, data,node) => {
acTop.value = ''
acLeft.value = ''
acBottom.value = ''
const rect = e.target.getBoundingClientRect(); //获取点击的dom的位置
var allHeight = document.body.scrollHeight
console.log(rect, data,node);
onBeforeMount(() => { actionFlag.value = true;
state.selectData = data
if(node.parent.data.Child){
state.selectParentData = node.parent.data
}else{
//没有children则是最上层元素
state.selectParentData = null
}
nextTick().then(()=>{
setTimeout(()=>{
var height = window.getComputedStyle(state.treeAction).height
height = parseInt(height)
//判断弹窗位置是否超过屏幕,超过则吸底展示
if(height+rect.y - 17>allHeight-state.bottomGap){
acBottom.value = state.bottomGap+ "px";
acLeft.value = rect.x + 35 + "px";
}else{
acTop.value = rect.y - 17 + "px";
acLeft.value = rect.x + 35 + "px";
}
}) })
return { })
...toRefs(), };
const handleNodeClick = (data) => {
if (state.selectData && state.selectData.menu_id == data.menu_id) {
return
}
state.selectData = data
console.log(data)
closeAction()
}
const fileAction = (val,data,parent,disabled=false) => {
if (val == 1) {
console.log("新建本级", data ,parent,disabled)
test()
}else if (val == 2) {
console.log("新建下级",data,parent,disabled)
test()
}else if (val == 3) {
console.log("删除",data,parent,disabled)
test()
}else if (val == 4) {
console.log("上移",data,parent,disabled)
test()
if (disabled) {
return
} }
}, test()
}else {
console.log("下移",data,parent,disabled)
if (disabled) {
return
}
test()
}
}
const test = () => {
console.log("执行了")
}
const closeAction = () => {
actionFlag.value = false;
} }
onBeforeMount(()=>{
window.addEventListener("click", closeAction)
window.addEventListener("scroll", closeAction,true)
getMenuTree()
})
onBeforeUnmount(()=>{
window.removeEventListener('click', closeAction);
window.removeEventListener('scroll', closeAction);
})
const {
data,
search,
defaultProps,
selectParentData,
selectData,
} = toRefs(state)
</script> </script>
<style lang="scss" scoped> <style scoped>
.tree_content {
overflow: hidden;
height: calc(100% - 4px);
position: relative;
}
.search {
padding: 16px 16px 10px;
}
.tree {
overflow: auto;
height: calc(100% - 65px);
}
.tree :deep().el-tree-node .el-tree-node__content {
padding: 0 16px!important;
}
.tree :deep() .el-tree-node>.el-tree-node__children {
overflow: unset;
padding-left: 16px;
}
.tree-action-box {
display: none;
position: absolute;
right: 0px;
background-color: #f2f3f7;
width: 44px;
text-align: center;
height: 36px;
line-height: 36px;
}
.tree .el-tree-node__content:hover .tree-action-box {
display: inline-block;
}
.tree-more {
font-size: 12px;
color: #3759be;
}
.tree-action {
width: 144px;
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
padding: 4px 0;
border-radius: 4px;
position: fixed;
z-index: 9;
}
.tree-action .action {
width: 100%;
height: 34px;
line-height: 34px;
padding-left: 16px;
font-size: 14px;
color: #202531;
cursor: pointer;
}
.tree-action .action:hover {
background-color: #f2f3f7;
color: #3759be;
}
.tree-action .disable{
cursor: not-allowed;
color: #616f94;
}
.tree-action .disable:hover{
background-color: #fff;
color: #616f94;
}
.main_container {
padding: 15px;
height: 100%;
}
.table_container {
height: calc(100% - 30px);
overflow: auto;
}
.pagination_box {
position: sticky;
margin-top: 16px;
bottom: 0px;
background-color: #fff;
z-index: 1024;
height: 40px;
line-height: 40px;
padding-top: 8px;
}
.bg-pagination {
bottom: unset
}
</style> </style>
\ No newline at end of file
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