效果图
CustomLeftMenu.vue
右边浮动大白块,分页模式显示二级、三级菜单
<template>
<div class="menuPage">
<div class="page" v-for="(item, i) in pageList" :key="i">
<div v-for="(menu, j) in menuArray" :key="j">
<div
v-if="
j + 1 >= i * colCount + 1 && j + 1 < i * colCount + 1 + colCount
"
>
<h3
class="title" style="margin:0px"
v-if="menu.type == 'title'"
>
{
{ menu.data.meta.title }}
</h3>
<div class="menu" v-if="menu.type == 'menu'">
<span @click="handleChild(menu.pdata, menu.data)">{
{
menu.data.meta.title
}}</span>
</div>
<div class="kong" v-if="menu.type == 'kong'">
<span> </span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "CustomLeftMenu",
props: {
//一列显示几个
colCount: {
type: Number,
require: true,
default: () => {
return 6;
},
},
// 菜单数据
menuList: {
type: Array,
require: true,
default: [],
},
},
mounted() {
//重新组装数据
try{
for (var rootMenu of this.menuList) {
this.menuArray.push({ type: "title", data: rootMenu });
for (var menu of rootMenu.children) {
if(menu.hidden==true){
continue;
}
this.menuArray.push({ type: "menu", data: menu, pdata: rootMenu });
}
//补空
this.menuArray.push({ type: "kong", data: null });
}
//分页
var page = Math.ceil(this.menuArray.length / this.colCount);
for (var i = 0; i < page; i++) {
this.pageList.push(i + 1);
}
}catch{
}
},
data() {
return {
//重新组装的数据
menuArray: [],
//可以分几页
pageList: [],
};
},
methods: {
handleChild(root, child) {
this.$emit("change-child", root, child);
},
},
};
</script>
<style lang="scss" scoped>
.menuPage {
display: flex;
justify-content: center;
align-items: flex-start;
margin: 10px 0px 10px 10px;
}
.page {
margin-right: 10px;
}
.title {
border-left: 4px solid #304156;
padding-left: 10px;
height: 20px;
line-height: 20px;
font-weight: bold;
font-size: 16px;
text-align: left;
}
.menu {
width: 120px;
height: 25px;
color: #676767;
padding-left: 5px;
padding-top: 2px;
margin-top: 5px;
margin-bottom: 5px;
white-space:nowrap; /*不换行 */
overflow:hidden; /*内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
}
.menu:hover{
background-color: #304156;
color: white;
}
.kong {
height: 20px;
color: #676767;
padding-left: 5px;
padding-top: 2px;
margin-top: 5px;
margin-bottom: 5px;
}
</style>
index.vue
一级菜单+二级菜单
<template>
<div class="custom-menu-container">
<logo v-if="showLogo" :collapse="isCollapse" />
<div class="custom-menu-wrapper">
<div
:class="[
'custom-menu-item',
{ 'small-coll': isCollapse },
{ 't-active': currentIndex === index },
]"
v-for="(item, index) in menuList"
:key="index"
@mouseleave="handleHide"
@mouseover="showToggle(item, index)"
>
<h3 :class="['custom-menu-title']">
<template v-if="isCollapse">
<item-icon v-if="item.meta" :icon="item.meta && item.meta.icon" />
</template>
<template v-else>
<item-icon
v-if="item.meta"
:icon="item.meta && item.meta.icon"
:title="item.meta.title"
/>
</template>
</h3>
<i
class="el-icon-caret-right arrow-icon"
v-if="!isCollapse"
@mouseover="showToggle(item, index)"
></i>
<div
@mouseover="showToggle(item, index)"
@mouseleave="handleHide"
:style="'top:'+getMenuHeight(index,menuList.length)+'px'"
:class="[
'dynamic-menu-child',
{ 'dynamic-active': currentIndex === index },
{ 'space-left': isCollapse },
]"
>
<i
class="el-icon-close arrow-close"
@click="handleHide"
title="点击关闭"
></i>
<div class="conten-list">
<CustomLeftMenu
:menuList="item.children"
:colCount="10"
@change-child="handleGrandIitem"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import path from "path";
import { mapGetters, mapState } from "vuex";
import CustomLeftMenu from "./CustomLeftMenu";
import Empty from "./Empty";
import MenuItem from "./MenuItem";
import ItemIcon from "./ItemIcon";
import Logo from "./Logo";
export default {
components: { CustomLeftMenu, Empty, MenuItem, ItemIcon, Logo },
data() {
return {
tempList: [],
isShowChildren: false,
currentIndex: -1,
childrenMenu: null, // 当前子菜单
};
},
props: {
menuList: {
type: Array,
default: () => [],
},
},
computed: {
...mapState(["settings"]),
...mapGetters(["sidebarRouters", "sidebar"]),
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
isCollapse() {
return !this.sidebar.opened;
},
},
methods: {
getMenuHeight(index,menuLength){
if(index ==menuLength - 1){
return -286;
}
if(index ==menuLength - 2){
return -251;
}
return 0;
},
handleChildIitem(value) {
try {
this.$router.push(path.resolve(this.childrenMenu.path, value.path));
setTimeout(() => {
this.handleHide();
}, 500);
} catch (error) {
console.log(error);
}
},
handleGrandIitem(root,node) {
try {
if(node.query==undefined){
node.query="{}";
}
var url =path.resolve(this.childrenMenu.path, `${root.path}/${node.path}`);
var query=JSON.parse(node.query);
this.$router.push({path:url,query:query});
setTimeout(() => {
this.handleHide();
}, 1000);
} catch (error) {
console.log(error);
}
},
showToggle(item, index) {
this.currentIndex = index;
this.childrenMenu = item;
// this.isShowChildren = true
},
handleHide() {
// this.isShowChildren = false
// console.log('handleHide')
this.currentIndex = -1;
},
},
};
</script>
<style lang="scss" scoped>
@import "@/assets/styles/custom-menu.scss";
@import "./style.scss";
.menu-items {
display: block;
}
::v-deep .custom-sub-menu-item .sub-menu-item-title {
display: block;
}
::v-deep .custom-sub-menu-item {
color: #bfcbd9;
}
.custom-menu-container .custom-menu-item .dynamic-menu-child .conten-list {
min-height: 0px;
padding-left: 10px;
}
</style>
最外层调用,给菜单传数据
<template>
<div style="background-color:#304156;">
<!-- <div v-if="user.menuMode==='menuFold'" :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg"
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuText : 'rgba(0,0,0,.65)'"
:unique-opened="true"
:active-text-color="settings.theme"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item
v-for="(route, index) in sidebarRouters"
:key="route.path + index"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</div> -->
<!-- 自定义菜单 -->
<custom-menus :menuList="menuList"></custom-menus>
</div>
</template>
<script>
import { mapGetters, mapState } from "vuex";
import Logo from "./Logo";
import SidebarItem from "./SidebarItem";
import variables from "@/assets/styles/variables.scss";
// import CustomMenus from '@/components/CustomMenus';
import CustomMenus from '../CustomMenus';
export default {
components: { SidebarItem, Logo, CustomMenus },
data() {
return {
menuList:[]
}
},
computed: {
...mapState(["settings", "user"]),
...mapGetters(["sidebarRouters", "sidebar"]),
activeMenu() {
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables;
},
isCollapse() {
return !this.sidebar.opened;
},
},
methods:{
getCount(list){
var count=0;
for(var item of list){
const arrays=item.children ?? [];
count+=arrays.length;
count+=this.getCount(arrays);
}
return count;
}
},
mounted() {
this.menuList = this.sidebarRouters.filter(e => e.hidden === false)
for(var item of this.menuList){
const arrays=item.children ?? [];
var count=arrays.length;
count+=this.getCount(arrays);
item.meta.count=count;
}
},
};
</script>
今天的文章vue左侧菜单栏实现_怎么关闭自定义菜单栏分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88217.html