从0-1搭建一个web项目(页面布局详解)详解

本章分析页面布局详解详解

ObJack-Admin一款基于 Vue3.3、TypeScript、Vite3、Pinia、Element-Plus 开源的后台管理框架。在一定程度上节省您的开发效率。另外本项目还封装了一些常用组件、hooks、指令、动态路由、按钮级别权限控制等功能。感兴趣的小伙伴可以访问源码点个赞 地址

在这里插入图片描述
所有的动态路由都添加在了layout组件下,所以直接打开layout查看,路径为 layouts/index.vue

此处逻辑很简单就不细说了,就是通过 component 动态加载组件下边的四种布局结构。

const LayoutComponents: Record<LayoutType, Component> = {
  vertical: LayoutVertical,
  classic: LayoutClassic,
  transverse: LayoutTransverse,
  columns: LayoutColumns
};

大家可以发现,默认加载的是 vertical: LayoutVertical 组件,所以我们打开这个文件查看一下。

基本布局就是下边这样的

<el-container class="layout">
    <el-aside>
        logo和菜单
     </el-aside>
 
    <el-container>
        头部、主体内容、底部
    </el-container>
</el-container>
  1. 菜单分析
<el-menu
     :router="false"
     :default-active="activeMenu"
     :collapse="isCollapse"
     :unique-opened="accordion"
     :collapse-transition="false"
      >
      <SubMenu :menu-list="menuList" />
</el-menu>

首先看一下 menuList 怎么来的。

const menuList = computed(() => authStore.showMenuListGet);

通过这句代码可以发现是通过 pinia 获取来的。

接着查找,找到 auth.ts 文件,路径为 stores/modules/auth.ts

// 菜单权限列表 ==> 左侧菜单栏渲染,需要剔除 isHide == true
    showMenuListGet: state => getShowMenuList(state.authMenuList),

可以看到是通过 getShowMenuList 方法返回来的。

分析 getShowMenuList 方法之前我们先看一下 authMenuList 是怎么来的。

async getAuthMenuList() {
      const { data } = await getAuthMenuListApi();
      this.authMenuList = data;
    },

加载动态路由的时候已经调用了此方法,在 dynamicRouter 文件中。

await authStore.getAuthMenuList();

接着找到 getAuthMenuListApi 方法

export const getAuthMenuListApi = () => {
  // return http.get<Menu.MenuOptions[]>(PORT1 + `/menu/list`, {}, { loading: false });
  // 如果想让菜单变为本地数据,注释上一行代码,并引入本地 authMenuList.json 数据
  return authMenuList;
};

这就是authMenuList的封装

好了,接下来咱们分析一下 getShowMenuList 方法。

export function getShowMenuList(menuList: Menu.MenuOptions[]) {
  let newMenuList: Menu.MenuOptions[] = JSON.parse(JSON.stringify(menuList));
  return newMenuList.filter(item => {
    item.children?.length && (item.children = getShowMenuList(item.children));
    return !item.meta?.isHide;
  });
}

首先把 menuList 深拷贝 赋值给 newMenuList。(如果大家不懂何为深拷贝的话,可以自行去查找相关资料)

接下来就是递归调用此方法,过滤掉到 isHide=true 的数据, 因为 isHide 为 true 的话代表隐藏菜单,不需要展示。

想了想,担心有的同学看不懂递归的这一部分逻辑,还是展开说说吧。

    1. 调用数组filter方法遍历筛选对应的数组。
    1. item.children?.length 此处的?写法就是判断children是否存在,存在的话就取length,不存在的话就不往下走了,下边的 item.meta?.isHide 也如此。
    1. item.children = getShowMenuList(item.children) 这段代码的意思就是将 getShowMenuList 方法的结果赋值给item.children,那getShowMenuList的返回结果是什么呢?其实就是每次循环 isHide 不为 true 的数据。
      接下来就分析菜单是怎么渲染上去的,查看 SubMenu 文件,路径在 /layouts/components/Menu/SubMenu.vue
<template v-for="subItem in menuList" :key="subItem.path">
    <el-sub-menu v-if="subItem.children?.length" :index="subItem.path">
      <template #title>
        <el-icon v-if="subItem.meta.icon">
          <component :is="subItem.meta.icon"></component>
        </el-icon>
        <span class="sle">{{ subItem.meta.title }}</span>
      </template>
      <SubMenu :menu-list="subItem.children" />
    </el-sub-menu>
    <el-menu-item v-else :index="subItem.path" @click="handleClickMenu(subItem)">
      <el-icon v-if="subItem.meta.icon">
        <component :is="subItem.meta.icon"></component>
      </el-icon>
      <template #title>
        <span class="sle">{{ subItem.meta.title }}</span>
      </template>
    </el-menu-item>
  </template>

其实这一部门逻辑也很简单,主要是循环判断有没有children 子目录,有的话就调用 el-sub-menu 组件,没有的话就调用 el-menu-item 组件,其中值得一说的是 下边这一段代码。

<component :is="subItem.meta.icon"></component>

大家应该还记得在 main.js 中 通过循环创建了 icon 公共组件,这里就是加载对应的icon组件。

至此,动态菜单就完成了。

2. 头部
这一部分逻辑也简单,大家有不懂得可以私信。

说一下面包屑是怎么渲染的吧,重点说一下下面这部分。

const breadcrumbList = computed(() => {
  let breadcrumbData = authStore.breadcrumbListGet[route.matched[route.matched.length - 1].path] ?? [];
  // 🙅‍♀️不需要首页面包屑可删除以下判断
  if (breadcrumbData[0].path !== HOME_URL) {
    breadcrumbData = [{ path: HOME_URL, meta: { icon: "HomeFilled", title: "首页" } }, ...breadcrumbData];
  }
  return breadcrumbData;
});
 
    1. 每次从 authStore.breadcrumbListGet 中获取当前路由的最后一个path 作为 key 的面包屑数据
    1. ?? 是 空值合并运算符 ,意思就是如果 ?? 左侧的结果是null或者undefined 的话,就取 ?? 右侧的数据,上边代码就是如果从 authStore.breadcrumbListGet 获取不到对应数据的话,那么本次就是空数据。
    1. 接下来就是给 breadcrumbData 添加了一条首页的面包屑,使用的三点运算符。

在这里插入图片描述
如碰到其他的问题 可以私下我 一起探讨学习
如果对你有所帮助还请 点赞 收藏谢谢~!
关注收藏博客 作者会持续更新…

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 01:24:04       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 01:24:04       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 01:24:04       45 阅读
  4. Python语言-面向对象

    2024-07-12 01:24:04       55 阅读

热门阅读

  1. 搜维尔科技:触觉反馈数据手套CyberGlove击鼓测试

    2024-07-12 01:24:04       17 阅读
  2. c语言变量修饰词

    2024-07-12 01:24:04       19 阅读
  3. 文心一言使用指南

    2024-07-12 01:24:04       23 阅读
  4. Redis数据同步

    2024-07-12 01:24:04       23 阅读
  5. 11、中台-DDD-几种微服务架构模型对比分析

    2024-07-12 01:24:04       22 阅读
  6. shark云原生-日志体系-ECK

    2024-07-12 01:24:04       18 阅读
  7. 9. 机器人数目

    2024-07-12 01:24:04       16 阅读
  8. Mysql-索引应用

    2024-07-12 01:24:04       19 阅读