Vue3+Vite+TypeScript+Element Plus开发-06.Header响应式菜单缩展
系列文档目录
Vue3+Vite+TypeScript安装
Element Plus安装与配置
主页设计与router配置
静态菜单设计
Pinia引入
Header响应式菜单缩展
Mockjs引用与Axios封装
登录设计
文章目录
目录
系列文档目录
文章目录
前言
一、Header响应
二、Aside呈现
三、Main.vue调整
四、运行效果
前言
本章节重点介绍通过点击按钮来切换 Pinia store 中的 isCollapse 状态,从而实现菜单的收缩与展开。
一、Header响应
1.在Header上增加按钮
1.1修改src\componets\MainHdrCont.vue
重点是按钮菜单显示与按钮事件
// 定义按钮文本,根据 store.isCollapse 的值动态设置
const bntMenuText = computed(() => {return store.isCollapse ? 'expand' : 'collapse';
});
// 定义单击事件的处理函数
function handleMenu() {store.isCollapse =! store.isCollapse// 在这里可以添加更多逻辑,例如切换菜单状态
}
完整代码:
<template><!-- 顶部导航栏 --><div class="header-layout"><div class="header-left"><div class="mb-4"> <el-button type="primary" :key="bntMenuText" @click="handleMenu">{{bntMenuText}}</el-button></div></div><div class="header-right"><el-dropdown><span class="el-dropdown-link"><el-avatar :size="30" src="../assets/vue.svg" /><el-icon><ArrowDown /></el-icon></span><template #dropdown><el-dropdown-menu><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>设置</el-dropdown-item><el-dropdown-item>退出登录</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></div></template>
<script lang="ts" setup>
import { ref,computed,defineComponent } from 'vue';
import { useAllDataStore } from '@/stores';const store = useAllDataStore();// 定义按钮文本,根据 store.isCollapse 的值动态设置
const bntMenuText = computed(() => {return store.isCollapse ? 'expand' : 'collapse';
});// 定义单击事件的处理函数
function handleMenu() {store.isCollapse =! store.isCollapse// 在这里可以添加更多逻辑,例如切换菜单状态
}
/*
export const MainAHdrCont = defineComponent({name: 'MainAHdrCont'
});
*/
</script><style scoped>
.header-layout {display: flex; justify-content: space-between; /* 使 header-left 和 header-right 分别靠左和靠右 */align-items: center;width: 100%; /* 确保 header 占据整个容器宽度 */}.header-left {display: flex;align-items: center;}.header-right {display: flex;align-items: center;}</style>
二、Aside呈现
1.src\componets\MainAsideCont.vue代码呈现
原来代码就存在,理论上不需要调整,重点部分:
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 180px;min-height: 400px;
}
.el-menu-vertical-demo.el-menu--collapse {width: 60px; /* 收缩时的宽度 */
}
完整代码:
<template> <el-menu:default-active="activeIndex"class="el-menu-vertical-demo":collapse="isCollapse"><h3 :key="TitleText">{{TitleText}}</h3><!-- 渲染没有子菜单的项 --><el-menu-itemv-for="item in noChilden":key="item.index":index="item.index"@click="handlemenu(item)"><component class="icon" :is="item.icon"></component><span>{{ item.label }}</span></el-menu-item><!-- 渲染有子菜单的项 --><el-sub-menuv-for="item in hasChilden":key="item.index":index="item.index"><template #title><component class="icon" :is="item.icon"></component><span>{{ item.label }}</span></template><el-menu-itemv-for="subItem in item.children":key="subItem.index":index="subItem.index"@click="handlemenuchild(item, subItem)"><span>{{ subItem.label }}</span></el-menu-item></el-sub-menu></el-menu>
</template><script lang="ts" setup>
import { ref, computed, onMounted } from 'vue';
import { defineComponent } from 'vue';
import { useRouter } from 'vue-router';
import {Document,Setting,
} from '@element-plus/icons-vue';import { useAllDataStore } from '@/stores';interface MenuItem {index: string;label: string;icon?: any;children?: MenuItem[];
}const menuData = ref<MenuItem[]>([{ index: 'Home', label: '首页', icon: Document },{index: 'SysSettings',label: '系统设置',icon: Setting,children: [{ index: 'UserInfo', label: '个人资料' },{ index: 'AccountSetting', label: '账户设置' },],},
]);const hasChilden = computed(() => menuData.value.filter(item => item.children && item.children.length > 0));
const noChilden = computed(() => menuData.value.filter(item => !item.children || item.children.length === 0));const activeIndex = ref('Home');
const router = useRouter();const handlemenu = (item: MenuItem) => {router.push(item.index);
};const handlemenuchild = (item: MenuItem, subItem: MenuItem) => { router.push(subItem.index);
};// const isCollapse = ref(true)
const store = useAllDataStore();
const TitleText = computed(() => {return store.isCollapse ? '平台' : '测试平台管理';
});const isCollapse = computed(() => store.isCollapse);
/*
// 使用 defineComponent 显式命名组件
export const MainAsideCont = defineComponent({name: 'MainAsideCont'
});
*/</script><style>
.el-menu {height: 100%; /* 设置整个布局的高度为 100%,确保布局占满整个视口 */border-right: none; /* 去掉右边框 */
}
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 180px;min-height: 400px;
}
.el-menu-vertical-demo.el-menu--collapse {width: 60px; /* 收缩时的宽度 */
}.icon {margin-right: 8px; /* 图标与文字之间的间距 */font-size: 18px; /* 图标的大小 */width:18px;height:18px;size:8px;color: #606266; /* 图标的默认颜色 */vertical-align: middle; /* 垂直居中对齐 */
}/* 鼠标悬停时的样式 */
.icon:hover {color: #409eff; /* 鼠标悬停时图标的颜色 */
}</style>
三、Main.vue调整
重点增加:width="ContAsideWidth",当紧缩的时候,调整Aside宽度
<el-aside :width="ContAsideWidth">
const ContAsideWidth = computed(() => {return store.isCollapse ? '60px' : '180px';
});
完整代码:
<template><div class="common-layout"><el-container class="container-aside" ><el-aside :width="ContAsideWidth"><MainAsideCont /> </el-aside><el-container><el-header><MainHdrCont /></el-header><el-main><router-view></router-view></el-main></el-container></el-container></div></template><script lang="ts" setup>import { defineComponent, computed } from 'vue';import MainAsideCont from '@/components/MainAsideCont.vue';import MainHdrCont from '@/components/MainHdrCont.vue'import { useAllDataStore } from '@/stores';const store = useAllDataStore();const ContAsideWidth = computed(() => {return store.isCollapse ? '60px' : '180px';
});</script><style lang="less" scoped>.common-layout {height: 100%; /* 设置整个布局的高度为 100%,确保布局占满整个视口 */width: 100%; /* 设置整个布局的宽度为 100%,确保布局占满整个视口 */.container-aside {height: 100%; /* 确保内部的 el-container 也占满整个父容器的高度 */}.el-header {background-color: #141515 ; /* 设置表头的背景色为深黑色 fff 141515*/color: #fff; /* 设置表头文字颜色为白色,以便在深色背景上更清晰 */display: flex; /* 使用 flex 布局,方便对齐内容 */align-items: center; /* 垂直居中对齐内容 */justify-content: center; /* 水平居中对齐内容 */font-size: 18px; /* 设置文字大小为 18px */font-weight: bold; /* 设置文字为加粗 */}.el-aside {background-color:rgba(242, 242, 242, 0.19); /* 设置侧边栏的背景色为浅灰色 */color: #333; /* 设置侧边栏文字颜色为深灰色 */display: flex; /* 使用 flex 布局,方便对齐内容 */ align-items: center; /* 垂直居中对齐内容 */justify-content: center; /* 水平居中对齐内容 */font-size: 16px; /* 设置文字大小为 16px */font-weight: normal; /* 设置文字为正常粗细 */height: 100%; /* 确保侧边栏高度占满 */}.el-main {background-color: #fff; /* 设置主内容区域的背景色为白色 */color: #333; /* 设置主内容区域文字颜色为深灰色 */padding: 20px; /* 添加内边距,使内容不紧贴边缘 */font-size: 14px; /* 设置文字大小为 14px */}}</style>
四、运行效果
点击expand