后台管理模版geeker-admin从0-1解构(分析路由)

最近一直想找一个好的后台管理模版,经过筛选,最后确定了geeker-admin,原因是作者的思路太值得学习了。

由于我也是带着学习的想法来的,所以会一步一步分析作者的思路并记录下来,所以基础不太好的同学非常值得一看。

话不多说,咱们开始吧。

哦,对了,先把地址贴出来,大家可以动动手指去给作者一个star,毕竟好的作品不能被埋没,还是需要大家的支持的。

<https://gitee.com/HalseySpicy/Geeker-Admin>

1.拉取项目
git clone https://gitee.com/HalseySpicy/Geeker-Admin.git
2.安装依赖
npm install
3.目录分析(借用作者的图)

Geeker-Admin
├─ .husky                  # husky 配置文件
├─ .vscode                 # VSCode 推荐配置
├─ build                   # Vite 配置项
├─ public                  # 静态资源文件(该文件夹不会被打包)
├─ src
│  ├─ api                  # API 接口管理
│  ├─ assets               # 静态资源文件
│  ├─ components           # 全局组件
│  ├─ config               # 全局配置项
│  ├─ directives           # 全局指令文件
│  ├─ enums                # 项目常用枚举
│  ├─ hooks                # 常用 Hooks 封装
│  ├─ languages            # 语言国际化 i18n
│  ├─ layouts              # 框架布局模块
│  ├─ routers              # 路由管理
│  ├─ stores               # pinia store
│  ├─ styles               # 全局样式文件
│  ├─ typings              # 全局 ts 声明
│  ├─ utils                # 常用工具库
│  ├─ views                # 项目所有页面
│  ├─ App.vue              # 项目主组件
│  ├─ main.ts              # 项目入口文件
│  └─ vite-env.d.ts        # 指定 ts 识别 vue
├─ .editorconfig           # 统一不同编辑器的编码风格
├─ .env                    # vite 常用配置
├─ .env.development        # 开发环境配置
├─ .env.production         # 生产环境配置
├─ .env.test               # 测试环境配置
├─ .eslintignore           # 忽略 Eslint 校验
├─ .eslintrc.cjs           # Eslint 校验配置文件
├─ .gitignore              # 忽略 git 提交
├─ .prettierignore         # 忽略 Prettier 格式化
├─ .prettierrc.cjs         # Prettier 格式化配置
├─ .stylelintignore        # 忽略 stylelint 格式化
├─ .stylelintrc.cjs        # stylelint 样式格式化配置
├─ CHANGELOG.md            # 项目更新日志
├─ commitlint.config.cjs   # git 提交规范配置
├─ index.html              # 入口 html
├─ LICENSE                 # 开源协议文件
├─ lint-staged.config.cjs  # lint-staged 配置文件
├─ package-lock.json       # 依赖包包版本锁
├─ package.json            # 依赖包管理
├─ postcss.config.cjs      # postcss 配置
├─ README.md               # README 介绍
├─ tsconfig.json           # typescript 全局配置
└─ vite.config.ts          # vite 全局配置文件
4.分析main.js

上部分的一系列import就不说了,就是导入一些依赖和插件

下面这句是抛出一个未捕获的全局错误

app.config.errorHandler = errorHandler;

接下来就是循环注册全局组件

Object.keys(Icons).forEach(key => {
  app.component(key, Icons[key as keyof typeof Icons]);
});
5.分析路由

我始终相信,只有了解了路由的逻辑,才能更清楚的了解一个项目,接下来咱们一起看

打开 routers/index.ts文件

const mode = import.meta.env.VITE_ROUTER_MODE;  //此处VITE_ROUTER_MODE是hash
const routerMode = {
  hash: () => createWebHashHistory(),
  history: () => createWebHistory()
};

const router = createRouter({
  history: routerMode[mode](),
  routes: [...staticRouter, ...errorRouter],
  strict: false,
  scrollBehavior: () => ({ left: 0, top: 0 })
});

1.history定义了路由模式,不懂得可以看下边

2.routes定义了静态路由,根据连接可以找到 modules/staticRouter.ts

3.strict:严格模式
scrollBehavior:切换新页面,定义页面的位置

4.路由守卫
其实这一部分没啥说的,作者注释的非常清楚,主要说一下第6部分吧。

  // 6.如果没有菜单列表,就重新请求菜单列表并添加动态路由
  if (!authStore.authMenuListGet.length) {
    await initDynamicRouter();
    return next({ ...to, replace: true });
  }

首先是异步加载initDynamicRouter方法,打开initDynamicRouter看看具体逻辑,位置在 modules/dynamicRouter.ts

第一部分是异步获取菜单权限列表和按钮权限列表。

const userStore = useUserStore();
const authStore = useAuthStore();

第二部分判断有没有权限,没有权限的话清除token,返回登录页并且抛出一个promist错误。

 if (!authStore.authMenuListGet.length) {
      ElNotification({
        title: "无权限访问",
        message: "当前账号无任何菜单权限,请联系系统管理员!",
        type: "warning",
        duration: 3000
      });
      userStore.setToken("");
      router.replace(LOGIN_URL);
      return Promise.reject("No permission");
    }

第三部分就是加载动态路由,首先看一下authStore.flatMenuListGet是怎么来的,经过搜索发现是调用了如下的方法,位置在 stores/modules/auth

flatMenuListGet: state => getFlatMenuList(state.authMenuList),

继续深入查找getFlatMenuList方法

export function getFlatMenuList(menuList: Menu.MenuOptions[]): Menu.MenuOptions[] {
  let newMenuList: Menu.MenuOptions[] = JSON.parse(JSON.stringify(menuList));
  return newMenuList.flatMap(item => [item, ...(item.children ? getFlatMenuList(item.children) : [])]);
}

这一部分可能有同学看不懂,我来解释一下。

这部分主要就是递归将数组扁平化,扁平化的意思就是将多维数组转换成一位数组,类似这样:

[1,2,[3,4]] => [1,2,3,4]

具体是用过数组的flatMap方法来实现的,flatMap方法对数组中的每个元素应用给定的回调函数,然后将结果展开一级,返回一个新数组。

const arr = [1, 2, [3], [4, 5]];
const res = arr.flatMap(item => item);
console.log(res);  // [1,2,3,4,5]

由于flatMap每次只能展开一级,所以需要递归调用。

至此,就已经拿到了authStore.flatMenuListGet的数据。

接着往下走

item.children && delete item.children

这一句就是删除children,因为拿到的是扁平化的数组,所以删处多余的children。

接下来就是动态导入对应的component路径。

最后将路由添加到layout组件下。

至此,动态路由导入成功。

最后登录页也没啥细说的了,因为initDynamicRouter咱们已经分析完了,其余的都是很简单的逻辑,大家一看就懂了。

未完待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值