stores/index.js
import {
	createStore
} from "vuex";
//计算高度
let height = window.innerHeight;
//计算分辨率
let width = window.innerWidth;
let activeIndex = localStorage.getItem("activeIndex");
if (activeIndex == null || activeIndex == "" || activeIndex == undefined) {
	activeIndex = "1";
}
//用户菜单
let menuList = localStorage.getItem("menuList");
if (menuList == undefined || menuList == "null" || menuList == null || menuList == "") {
	menuList = [];
} else {
	menuList = JSON.parse(menuList);
}
const store = createStore({
	state: function () {
		return {
			width: width,
			height: height,
            activeIndex:activeIndex,
            //当前用户的权限
			menuList: menuList,
		};
	},
	mutations: {
		setActiveIndex: function (state, value) {
			state.activeIndex = value;
			localStorage.setItem("activeIndex", value);
		},
        setMenuList: function (state, value) {
			state.menuList = value;
			localStorage.setItem("menuList", JSON.stringify(value));
		},
	},
	modules: {
	},
});
export default store;
	
 
home.vue
    <el-container :style="getStyle()">
        <!-- <el-header class="pageHeader">
            <el-row justify="end" style="height:100%"></el-row>
        </el-header> -->
        <el-container>
            <el-aside :style="asideStyle">
                <el-scrollbar :height="height - 64">
                    <the-menu @foldMenu="foldMenu"></the-menu>
                </el-scrollbar>
            </el-aside>
            <el-main style="background:#fff;">
				<router-view ></router-view>
			</el-main>
        </el-container>
    </el-container>
</template>
<script setup>
import stores from '../../stores/index.js'
import TheMenu from '@/components/TheMenu.vue'
import { computed, onMounted, reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const router = useRouter()
const route = useRoute()
const asideStyle = ref({})
onMounted( () => {
    getAsideStyle(0)
})
const getStyle = () => {
    let h = stores.state.height;
    return {
        height: h + "px"
    }
}
// flag:0-展开 1-折叠
let  getAsideStyle = (flag) => {
    var h = stores.state.height;
    var style = {
        width: flag == 0 ? "240px": "66px",
        height: h + "px",
        border: "none",
        backgroundColor: '#f7f9fc',
        zIndex: 99
    };
    asideStyle.value = style
}
const foldMenu = (state) => {
    debugger
    getAsideStyle(state)
}
const height = computed(() => {
    //将dept变量中stuffs列表的长度赋值给numberofStuff
    return stores.state.height
})
</script>
<style scoped lang="less">
.el-footer {
    display: flex;
    width: 100%;
    height: 2.375rem;
    color: white;
    font-size: 0.8rem;
    font-weight: 700;
    align-items: center;
    justify-content: center;
    background-color: #589957;
}
</style>
 
TheMenu.vue
<!--
  Author:lixg
  Date:2022-03-07 14:54
  Describe:菜单组件
-->
<template>
    <div class="menuBox">
        <el-menu v-on:select="handleSelect" :collapse="isCollapse" class="el-menu-vertical-demo" text-color="#03bf8a"
            active-text-color="#ffffff" :default-active="activeIndex" background-color="#f7f9fc">
            <el-menu-item v-bind:index="state.Menu.CompanyAccount.index" class="oneLevelMenu">
                <i class="el-icon-menu-default"></i>
                <template #title>{{ getMenuName(state.Menu.CompanyAccount) }}</template>
            </el-menu-item>
            <el-menu-item v-bind:index="state.Menu.HistoryAccount.index" class="oneLevelMenu">
                <i class="el-icon-menu-default"></i>
                <template #title>{{ getMenuName(state.Menu.HistoryAccount) }}</template>
            </el-menu-item>
        </el-menu>
        <div class="collapse_true" @click="foldMenu(1)" v-show="!isCollapse">
            <div v-for="i in 3"></div>
        </div>
        <div class="collapse_false" @click="foldMenu(0)" v-show="isCollapse">
            <div v-for="i in 3"></div>
        </div>
    </div>
</template>
<script setup>
import { computed, onMounted, reactive, ref, defineEmits } from 'vue'
import SetInfo from '../lib/setting.js'
import stores from '../stores/index.js'
import { useRoute, useRouter } from 'vue-router'
import { v4 as uuidv4 } from 'uuid';
const isCollapse = ref(false)
const router = useRouter()
const route = useRoute()
const emit = defineEmits(['foldMenu'])
const state = reactive({
    Menu: SetInfo.Menu
})
const activeIndex = computed(() => {
    return stores.state.activeIndex
})
let menuList = computed(() => {
    return stores.state.menuList
})
const handleSelect = (index) => {
    if (index == null) {
        index = 1;
    }
    stores.commit("setActiveIndex", index);
    var name = "";
    for (var key in state.Menu) {
        if (state.Menu[key].index == index) {
            name = state.Menu[key].name;
            break;
        }
        if (name != "") {
            break;
        }
    }
    router.push({
        name: name,
        params: { random: uuidv4() },
    });
}
const getMenuName = (menu) => {
    var menuInfo = menuList.value.find(item => {
        return item.title == menu.title;
    })
    if (menuInfo) {
        return menuInfo.title;
    }
    else {
        return menu.title;
    }
}
// 菜单折叠
const foldMenu = (state) => {
    isCollapse.value = state == 1 ? true : false;
    debugger
    emit("foldMenu", state)
}
</script>
<style scoped lang="less">
.el-menu {
    width: "240px",
}
.el-menu .is-active {
    background-color: #03bf8a;
}
.el-icon-menu-default {
    background: url(../img/LayoutContainer/menu-default.png) center no-repeat;
    // background-size: cover;
}
.el-icon-menu-default:before {
    content: "\8d3a";
    font-size: 14px;
    visibility: hidden;
}
.el-menu .is-active .el-icon-menu-default {
    background: url(../img/LayoutContainer/menu-active.png) center no-repeat;
    // background-size: cover;
}
.collapse_true {
    width: 220px;
    height: 28px;
    padding: 10px;
    background: #f0f1f2;
    bottom: 0;
    position: absolute;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-evenly;
    div {
        width: 40px;
        height: 3px;
        background-color: #999;
    }
}
.collapse_false {
    width: 25px;
    height: 28px;
    margin: 10px 20px;
    background: #f0f1f2;
    bottom: 0;
    position: absolute;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-evenly;
    div {
        width: 3px;
        height: 30px;
        background-color: #999;
    }
}
</style>
 
router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'layout',
      component: () => import('@/views/layout/LayoutContainer.vue'),
      children:[
        {
          path: '/companyAccount',
          name: 'companyAccount',
          component: () => import('@/views/layout/components/CompanyAccount.vue')
          
        },
        {
          path: '/historyAccount',
          name: 'historyAccount',
          component: () => import('@/views/layout/components/HistoryAccount.vue')
          
        }
      ]
    },
    
  ]
})
export default router
 
lib/setting.js
const SETTING = {
	//系统菜单配置示例
	Menu: { 
        CompanyAccount: {
			name: "companyAccount",
			title: "菜单1", 
			index: "0",
			children: []
		},
        HistoryAccount: {
			name: "historyAccount",
			title: "菜单2", 
			index: "1",
			children: []
		},
    }
}
export default SETTING 
 

 


















