目录
该页面三个结构:侧边栏、导航栏、后台系统
1.布局
使用Element里的Container布局容器中的。
el-container是Element plus所提供的容器组件,el-aside是侧边栏组件。两栏布局,aside在左边,container在右边。
由于container会根据内部有没有header组件来决定,如果有就会变成上下垂直布局,没有的话就变成左右水平布局,所以container所包裹的header在上面,main在下面。(官方文档中有说明)
2.修改样式
改变它们的高度
3.路由跳转
把固定的main改成 router-view容器组件来进行子路由的管理跳转。
4.封装组件
导航栏和侧边栏都需要JS交互的,并且侧边栏还要有权限的一个划分,分登录的角色不同所看到的侧边栏的内容就有所不同,所以这个侧边栏会有大量的数据交互以及遍历、循环等等,如果都写在MainBox.vue里面就会导致页面代码看起来特别特别乱,因此我们应尽可能的进行封装组件。以后如果再复用的话就更加方便了。那么我们就把header和aside部分都给它封装成单独的组件,在去MainBox.vue里面去引用组件即可。
- 组件封装规则:
MainBox.vue是视图级别的组件放在view视图文件进行管理
侧边栏组件和导航栏组件是属于这个组件自己内部消化的或者未来可能会被复用的,我们把它们放在components文件,因为没有,我们要自己在src文件夹里面创建。
4.1创建组件
在components文件夹中创建MainBox文件夹,再在MainBox文件夹中创建SideMenu.vue和TopHeader.vue两个组件。
4.2导入组件
因为我们用的是setup这种方式导入既自动组成,所以我们可以直接去使用了。
4.3使用组件
我们会发现页面效果和之前不一样了。因为布局发生了改变,变成水平布局,我们之前在上面说过在el-container中没有发现el-header或el-footer布局就会发生改变。所以我们要在el-container增加direction属性。
4.4使用组件—导航栏TopHeader组件
退出事件剪切到TopHeader中,ManBox.vue中就剩两个导入组件了。
4.5使用组件—侧边栏 SideMenu组件
我们之前做的前端定义好然后我们根据当前登录用户的身份去匹配如果有我们页面就渲染。但是侧边栏的东西是可以改变的,这就是我们的权限列表信息。所以我们将来在权限列表中,我们可以进行更新维护的,之后我们改变名称或者图标,用户管理那里都会显示的。因此我们先在前端那定义好是没用,侧边栏信息我们不能把它固定写死,侧边栏中的数据是要从后端返回来的,我们在侧边栏中需要拿到将来权限列表信息所管理的这个数组信息给我们,根据这个数据信息改成首页一用户管理一,我们进行遍历显示的时候才能显示首页一用户管理一,这样的话才能做到真正的权限列表的管理会映射到我们的左边的侧边栏中,所以我们需要提前拿到未来管理的权限列表。
在正常的前后端协作开发中,我们的前端和后端需要提前创建好我们交互的JSON数据,我们交换的数据格式未来可能会有点变动,但不至于变动太多,到时候稍微一连调就行了,所以我们前期一定会有这种文件的,那这样的话我们就可以实现这个侧边栏的一个开发了。
4.5.1.创建JSON文件
在public文件夹中创建right.json文件。
我们将来在权限列表中进行权限名称和图标的修改最终都会映射到JSON文件中,而JSON文件中的数据改变将会直接影响侧边栏的一个变化,那么它的数据格式是什么呢?如下代码
[
{
"title":"首页",
"path":"/index",
"icon":"HomeFilled",
"children":[]
},
{
"title":"用户管理",
"path":"/user-manage",
"icon":"User",
"children":[
{
"title":"用户列表",
"path":"/user-manage/list",
"icon":"List"
}
]
},
{
"title":"权限管理",
"path":"/right-manage",
"icon":"Key",
"children":[
{
"title":"角色列表",
"path":"/right-manage/rolelist",
"icon":"List"
},
{
"title":"权限列表",
"path":"/right-manage/rightlist",
"icon":"List"
}
]
},
{
"title":"实验室管理",
"path":"/lab-manage",
"icon":"OfficeBuilding",
"children":[
{
"title":"实验室列表",
"path":"/lab-manage/lablist",
"icon":"List"
},
{
"title":"添加实验室",
"path":"/lab-manage/addlab",
"icon":"List"
}
]
},{
"title":"预约管理",
"path":"/book-manage",
"icon":"UploadFilled",
"children":[
{
"title":"审核列表",
"path":"/book-manage/auditlist",
"icon":"List"
},
{
"title":"预约列表",
"path":"/book-manage/booklist",
"icon":"List"
},
{
"title":"预约实验室",
"path":"/book-manage/addbook",
"icon":"List"
}
]
}
]
有了上面的那些数据我们就离侧边栏的渲染又进了一步。上面的属性名字都是和后端提前约定好的,它将来从数据库查了回来返回给你的接口一定要是这些字段,这样的话以后我们就可以直接替换JSON,直接换成真实的后端接口就可以了。
我们一会前端一会后端,有了这样的JSON文件就可以辅助我们进行这样一个开发的进程。
从上面的代码中可以发现用户管理、权限管理、实验室管理、预约管理都写了一个不是真正的路径,那是为什么呢?因为如果没有的话,我们将来在创建侧边栏中会连外面那一个submenu都创建不出来。一个连一级路径都没有的怎么去创建里面的内容。submenu它是要匹配到外面这样一个一级路径,才能创建出二级菜单。
4.5.2.获取数据JSON
4.5.2.1.导入一个生命周期
之后我们要进入SideMenu这个组件中的时候,就要取到这些数据为我们所用。在SideMenu组件中导入一个生命周期。
4.5.2.2.导入Axios
请求rights.json,如果这个JSON能请求回来的话,将来我们的的后端返回的形式跟它一样,我们只需要替换这里的一个接口就可以了。
4.5.3. 页面渲染数据
4.5.3.1.使用element plus组件
例如:
(页面控制台中报警告是因为我们没有引入图标;侧边导航栏中间的线条是因为我们没有给它设置高度。)
4.5.3.2.动态创建
拿着现有的这些数据和组件创建动态侧边栏。
接下来就是我们典型的vue的遍历循环,根据这个res.data 数组的长度遍历出来,如果将来children是空的话就渲染el-menu-item,如果children属性不为空的情况下,它就是渲染el-sub-menu这个组件。可以看出这个就是典型的一个for循环的一个处理规则。
1)保存数据
为了让它保存下来,那对应的我们就要提前定义好这个datalist的ref,一开始是个空数组,等数据回来之后赋值给datalist.value,从而将数据进行保存。
2)用datalist进行循环
条件:我们首先要进行一个循环,我们肯定不能在<el-sub-menu index="1">里面进行v-for和v-if判断,因为v-for和v-if不能同时使用,如果同时使用会引发不可预期的错误。
最好的方案就是写一个template,为什么不使用其他标签呢?因为template属于包装元素,它最终不会形成真实的节点渲染出来,你可以认为这是个快递盒子,拆了之后我们要的是里面的东西。所以对template进行一个v-for的一个遍历。
下面用了两个for循环嵌套。
3)设置icon
icon本身就是一个字符串,我们不能写成{item.icon},这样写的话页面渲染出来的写它的字符串,它们要求的必须是这样<icon-menu>一个组件的名字。那这里我们该怎么去做呢?
在我们的vue中的话我们有一个component组件,component是vue的一个动态组件,有一个is属性,属性值是谁,这个组件是谁。可以称之为”component是个随风草,风怎么吹它就怎么动,你说它是谁它就是谁“。
我们可以去做个映射文件或者不用setup语法换成最原始的写法,当然也是基于compositionAPI去写的。
因为在setup语法中它这个is后面绑定的是这个组件的实例对象,这里出来了一个极大的矛盾,那就是从后端返回来的是一个字符串。我们用<component :is="data.icon">发现页面也没渲染出来图标。因为用了setup语法所以我们这里必须要找到这个字符串它所对应的那个组件的名字,而且是那个组件的那个类的那个名字,你要放进来才行。
一个映射文件就是你给我字符串,将来我在script里有个对象可以读这个字符串,它给我返回的是它对应的导入进来的组件实例就可以了。
这里的思路就是通过component动态加载,但由于setup的一个限制只能放上这个组件导入进来,组件实例还不能是字符串,所以我们就在从后来拿到了是字符串,我们通过mapIcons这个对象一映射拿到的就是User对应的这个导入进来这个组件实例了。
4)点击跳转路径
5)default-active
我们现在一刷新就会没有自己展开也没有高亮了,那么现在就会用到default-active。
default-active的值我们用当前路由的值去匹配index,我们知道index的值正好我们设置的路径,所以在这获取了当前的路径并且index就是路径,完美匹配,自动展开。
4.5.3.3.权限验证
用上面角色登录,页面就渲染拥有自己权限的信息,而不是像现在一样,不管是管理员登录还是教室登录页面都是渲染的全部信息。
1)check判断
2)checkAuth里怎么去做?
去获取当前用户的它的一个rouse字段,所以跟之前一样导入我们的pinia管理的useUserStore。
includes去判断path在不在includes包含中,如果数组包含它,它就能创建就是true,不包含就是false。
我们看页面渲染发现我们用教师身份登录的话,审核列表还是被创建了,那是因为什么呢?因为我们并没有在二级菜单那里进行checkAuth判断。那么我们要对它也进行if判断。
我们还是用template包装元素,我们把v-for剪切到包装元素里面,用包装元素进行遍历这个children。然后我们再渲染el-menu-item。el-menu-item不一定渲染成功,主要是根据我们的v-if进行判断。
我们可以看到已经没有创建审核列表了。