当前位置: 首页 > news >正文

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


http://www.mrgr.cn/news/97560.html

相关文章:

  • 2025 数字中国创新大赛数字安全赛道数据安全产业积分争夺赛初赛-东部赛区WriteUp
  • C++第14届蓝桥杯b组学习笔记
  • xv6-labs-2024 lab2
  • 深入解析嵌入式Linux系统架构:从Bootloader到用户空间 - 结合B站视频教学
  • 【Android Audio】Parameter Framework - pfw
  • LeetCode 解题思路 33(Hot 100)
  • JavaScript基础--20-JavaScript 预编译机制深度解析
  • 【CPP】内存泄漏详解
  • Ollama
  • spring boot + Prometheus + Grafana 实现项目监控
  • Android 学习之 Navigation导航
  • PyTorch 笔记
  • 考研单词笔记 2025.04.07
  • 分割回文串 复原IP地址(Java)
  • 深入理解PCA降维:原理、实现与应用
  • Proteus vs Multisim:电路设计与仿真软件对比
  • Java 三大特性—多态
  • 高德地图 3D 渲染-区域纹理图添加
  • 文献分享: Muvera多向量到单向量的转化方法(Part3——引理证明的补充)
  • 沧州铁狮子