赞
踩
利用element-plus的布局组件实现: <el-container> 整个布局容器, <el-header> 顶部布局容器, <el-aside> 侧边布局容器 <el-main> 主要布局容器。 采用组件化思想,将header和aside组件化,方便布局。
- <template>
- <div class="common-layout">
- <el-container>
-
- <CommonAside />
-
- <el-container>
- <el-header>
- <CommonHeader />
- </el-header>
- <el-main>
- <router-view />
- </el-main>
- </el-container>
- </el-container>
- </div>
- </template>
- <script lang="ts" setup>
- import CommonAside from '../components/CommonAside.vue'
- import CommonHeader from '../components/CommonHeader.vue'
-
- </script>
- color: var(--el-text-color-primary);
- }</style>
侧边栏的布局,利用element-plus的el-menu组件实现。 el-menu组件实现第一级菜单,el-submenu实现第二级菜单。 el-menu-item实现菜单项,el-submenu-item实现二级菜单项。 el-menu-item-group实现菜单组,el-menu-item-group实现菜单组。
所有菜单内容存储在数组menuData中,通过v-for指令动态渲染。通过noChildren过滤出没有子菜单的菜单数据也就是一级菜单数据。 通过hasChildren过滤出有子菜单的菜单数据也就是二级菜单数据。
<component :is="item.icon" ></component>
这块实现参考文章:https://blog.csdn.net/qq_40190624/article/details/125019530 说的较为详细。
ai推荐使用:<el-icon><icon-svg :icon-class="item.icon" /></el-icon>
需要自定义的图标,可以到iconfont官网下载,然后放到static文件夹下,然后通过import引入。https://blog.csdn.net/qq_39246667/article/details/124347398 给出具体方法较为复杂.
- <template>
- <!-- <el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
- <el-radio-button :label="false">expand</el-radio-button>
- <el-radio-button :label="true">collapse</el-radio-button>
- </el-radio-group> -->
- <el-menu default-active="2" class="el-menu-vertical-demo" :collapse="isCollapse" @open="handleOpen"
- @close="handleClose">
- <el-menu-item v-for="item in noChildren()" :key="item.name" :index="item.name">
- <component :is="item.icon" style="width: 18px;height: 18px;"></component>
- <template #title>{{item.label}}</template>
- </el-menu-item>
- <el-sub-menu v-for="item in hasChildren()" :key="item.name" :index="item.label">
- <template #title>
- <el-icon>
- <component :is="item.icon" style="width: 18px;height: 18px;"></component>
- </el-icon>
- <span>{{item.label}}</span>
- </template>
- <el-menu-item-group v-for="subItem in item.children" :key="subItem.name">
- <el-menu-item :index="subItem.name">{{subItem.label}}</el-menu-item>
- </el-menu-item-group>
- </el-sub-menu>
- </el-menu>
- </template>
-
- <script lang="ts" setup>
- import { ref } from 'vue'
- import {
- Document,
- Menu as IconMenu,
- Location,
- Setting,
- } from '@element-plus/icons-vue'
-
- // 声明一个变量isCollapse,值为false
- const isCollapse = ref(false)
-
- const menuData = [
- {
- path: "/",
- name: "home",
- label: "首页",
- icon: 'Menu',
- url: "Home/Home",
- },
- {
- path: "/mall",
- name: "mall",
- label: "商品管理",
- icon: "Document",
- url: "MallManage/MallManage",
- },
- {
- path: "/user",
- name: "user",
- label: "用户管理",
- icon: "Setting",
- url: "UserManage/UserManage",
- },
- {
- label: "其他",
- icon: "location",
- children: [
- {
- path: "/page1",
- name: "page1",
- label: "首页",
- icon: "Setting",
- url: "Other/PageOne",
- },
- {
- path: "/page2",
- name: "page2",
- label: "首页",
- icon: "Setting",
- url: "Other/PageTwo",
- },
- ],
- },
- ]
- // 声明一个函数handleOpen,参数为key和keyPath,用于接收参数
- const handleOpen = (key: string, keyPath: string[]) => {
- console.log(key, keyPath)
- }
- // 声明一个函数handleClose,参数为key和keyPath,用于接收参数
- const handleClose = (key: string, keyPath: string[]) => {
- console.log(key, keyPath)
- }
- const noChildren = () => { return menuData.filter((item) => !item.children) }
- // 过滤出没有子菜单的菜单数据
-
- const hasChildren = () => { return menuData.filter((item) => item.children) }
- // 过滤出有子菜单的菜单数据
-
- </script>
-
- <style>
- .el-menu-vertical-demo:not(.el-menu--collapse) {
- width: 200px;
- min-height: 400px;
- }
- </style>
-
注意:index 项目必须唯一 :index="item.label" item.label选项各菜单都有且不同,子菜单项标题没有name,所以item.name报错。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。