#### 页面layout布局
1.在elementPlus中找到对应的layout布局,在Main.vue的template中写入
<div class="common-layout">
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-container>
<el-header>Header</el-header>
<el-main>Main</el-main>
</el-container>
</el-container>
</div>
2.将style.css中的默认样式全部删除,引入样式
3.将components清空,新建一个aside.vue,内容与app.vue相同
4.在elementPlus中找到侧栏代码,将menu部分复制下来放到aside.vue的template中写入
<el-menu
active-text-color="#ffd04b"
background-color="#545c64"
class="el-menu-vertical-demo"
default-active="2"
text-color="#fff"
@open="handleOpen"
@close="handleClose"
>
<el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>Navigator One</span>
</template>
<el-menu-item-group title="Group One">
<el-menu-item index="1-1">item one</el-menu-item>
<el-menu-item index="1-2">item two</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group Two">
<el-menu-item index="1-3">item three</el-menu-item>
</el-menu-item-group>
<el-sub-menu index="1-4">
<template #title>item four</template>
<el-menu-item index="1-4-1">item one</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<el-icon><document /></el-icon>
<span>Navigator Three</span>
</el-menu-item>
<el-menu-item index="4">
<el-icon><setting /></el-icon>
<span>Navigator Four</span>
</el-menu-item>
</el-menu>
5.在aside.vue中script定义函数
const handleOpen = () => {}
const handleClose = () =>{}
6.在main.vue中script部分引入
import Aside from '../components/aside.vue';
7.在main.vue中 template部分修改
<!-- <el-aside width="200px">Aside</el-aside> -->
<Aside />
8.运行查看
#### aside样式调整和treeMenu组件
1.自主命名aside.vue中的class——“aside-container”
2.终端下载 cnpm i less@4.2.0
3.在aside.vue的style标签里添加lang=“less”
<style lang="less" scoped>
.aside-container{
height: 100%;
}
</style>
4.main.vue加入
<style lang="less" scoped>
.common-layout {
height: 100%;
.el-container {
height: 100%;
}
}
</style>
5.在aside.vue的template中添加导航的logo并增加样式
6.在components中创建treeMenu.vue文件
treeMenu.vue内容
<template>
<template>
<el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>Navigator One</span>
</template>
<el-menu-item-group title="Group One">
<el-menu-item index="1-1">item one</el-menu-item>
<el-menu-item index="1-2">item two</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group Two">
<el-menu-item index="1-3">item three</el-menu-item>
</el-menu-item-group>
<el-sub-menu index="1-4">
<template #title>item four</template>
<el-menu-item index="1-4-1">item one</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<el-icon><document /></el-icon>
<span>Navigator Three</span>
</el-menu-item>
<el-menu-item index="4">
<el-icon><setting /></el-icon>
<span>Navigator Four</span>
</el-menu-item>
</template>
</template>
<script setup>
</script>
<style scoped>
</style>
aside.vue内容
<template>
<el-menu
active-text-color="#ffd04b"
background-color="#545c64"
class="aside-container"
default-active="2"
text-color="#fff"
@open="handleOpen"
@close="handleClose"
>
<!-- 添加logo -->
<p class="logo-lg">DIDI陪诊</p>
<TreeMenu />
</el-menu>
</template>
<script setup>
//引入treeMenu
import TreeMenu from './treeMenu.vue'
//展开指定的子菜单
const handleOpen = () => {}
//关闭指定的子菜单
const handleClose = () =>{}
</script>
<style lang="less" scoped>
.aside-container{
height: 100%;
.logo-lg {
font-size: 20px;
text-align: center;
height: 50px;
line-height: 50px;
color: #fff;
}
}
</style>
#### treeMenu组件递归实现
1.修改router的index.js部分,将对应的路由添加上;
2.在views创建文件夹和index.vue,内容和app.vue相同,并引入到index.js中
3.在aside.vue中引入userouter,创建一个router实例
4.在控制台查看option中router的数据,在aside.vue引入reactive,创建响应式数据。
拿到它的第一项的子元素,通过赋值组件通信将数据传给子组件
5.在子组件获取数据,也就是对treeMenu进行操作
6.菜单的复用应该考虑父级组件递归方式
treeMenu.vue代码呈现
<template>
<!-- <el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>Navigator One</span>
</template>
<el-menu-item-group title="Group One">
<el-menu-item index="1-1">item one</el-menu-item>
<el-menu-item index="1-2">item two</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group Two">
<el-menu-item index="1-3">item three</el-menu-item>
</el-menu-item-group>
<el-sub-menu index="1-4">
<template #title>item four</template>
<el-menu-item index="1-4-1">item one</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<el-icon><document /></el-icon>
<span>Navigator Three</span>
</el-menu-item> -->
<template v-for="(item,index) in props.menuData">
<!-- 没子菜单的情况 -->
<el-menu-item
v-if="!item.children || item.children.length == 0"
:index="`${ props.index }-${item.meta.id}`"
:key="`${ props.index }-${item.meta.id}`">
<!-- <el-icon><setting /></el-icon>
<span>Navigator Four</span> -->
<el-icon size="20">
<!-- 动态组件 -->
<component :is="item.meta.icon">
</component>
</el-icon>
<span>{{ item.meta.name }}</span>
</el-menu-item>
<!-- 有子菜单的情况 -->
<el-sub-menu
v-else
:index="`${ props.index }-${item.meta.id}`">
<template #title>
<el-icon size="20">
<!-- 动态组件 -->
<component :is="item.meta.icon">
</component>
</el-icon>
<span>{{ item.meta.name }}</span>
</template>
<tree-menu
:index="`${ props.index }-${item.meta.id}`"
:menuData="item.children"/>
</el-sub-menu>
</template>
</template>
<script setup>
import { useTemplateRef } from 'vue';
const props = defineProps(['menuData','index'])
console.log(props,'props')
</script>
<style scoped>
</style>
解释代码:
这段 Vue.js 模板代码用于动态生成菜单项,支持展示子菜单。它使用了 Element Plus 组件库中的
el-menu-item
和el-sub-menu
组件,并且通过v-for
遍历props.menuData
数组生成菜单。以下是对每个部分的详细解释:代码结构解析
<template v-for="(item, index) in props.menuData">
- 这行代码表示对
props.menuData
数组中的每一项进行循环遍历。item
是当前循环的菜单项对象,index
是当前项的索引。没有子菜单的情况 (
<el-menu-item>
)<el-menu-item v-if="!item.children || item.children.length === 0" :index="`${ props.index }-${item.meta.id}`" :key="`${ props.index }-${item.meta.id}`"> <el-icon size="20"> <!-- 动态组件 --> <component :is="item.meta.icon"> </component> </el-icon> <span>{{ item.meta.name }}</span> </el-menu-item>
v-if="!item.children || item.children.length === 0"
: 这个条件判断用来确定当前菜单项是否有子菜单。如果item.children
为空或未定义,则表示当前菜单项没有子菜单。:index="
props.index−props.index−{item.meta.id}"
:el-menu-item
的:index
属性用来唯一标识菜单项。它结合了父组件的props.index
和当前菜单项的item.meta.id
以确保唯一性。:key="
props.index−props.index−{item.meta.id}"
::key
属性用于优化 Vue 的渲染性能,确保每个菜单项在 DOM 中有唯一的标识。<el-icon size="20">
:el-icon
用于展示图标。通过动态组件<component :is="item.meta.icon">
来根据item.meta.icon
的值动态选择要显示的图标组件。<span>{{ item.meta.name }}</span>
: 显示菜单项的名称。有子菜单的情况 (
<el-sub-menu>
)<el-sub-menu v-else :index="`${ props.index }-${item.meta.id}`"> <template #title> <el-icon size="20"> <!-- 动态组件 --> <component :is="item.meta.icon"> </component> </el-icon> <span>{{ item.meta.name }}</span> </template> <tree-menu :index="`${ props.index }-${item.meta.id}`" :menuData="item.children"/> </el-sub-menu>
v-else
: 这个指令用于处理在没有子菜单的情况下的反向情况,即当前菜单项有子菜单时的渲染。:index="
props.index−props.index−{item.meta.id}"
: 类似于el-menu-item
,为el-sub-menu
提供唯一标识。<template #title>
: 定义el-sub-menu
的标题部分。在el-sub-menu
组件内,这部分用作菜单项的可展开标题。<el-icon size="20">
: 与上面的el-menu-item
相同,用于显示图标。<component :is="item.meta.icon">
: 动态选择图标组件。<span>{{ item.meta.name }}</span>
: 显示子菜单的名称。<tree-menu :index="
props.index−props.index−{item.meta.id}" :menuData="item.children"/>
: 递归渲染子菜单,tree-menu
是一个自定义组件,用于显示item.children
里的子菜单项。总结
这段代码使用 Vue.js 的
v-for
指令来循环渲染菜单项,依据菜单项是否有子菜单来分别使用el-menu-item
和el-sub-menu
组件。它还通过动态组件<component :is="item.meta.icon">
实现了图标的动态选择,使得菜单具有灵活的显示效果。