vben-adminの初体验

618 阅读4分钟

该文章出于想使用vben的架构结果发现vben的接口处理是固定形式(需求不确定返回形式的接口处理)

了解使用

简单了解下vben架构

├── build # 打包脚本相关 
│   ├── config # 配置文件
│   ├── generate # 生成器
│   ├── script # 脚本
│   └── vite # vite配置
├── mock # mock文件夹,假的信息接口
├── public # 公共静态资源目录
├── src # 主目录
│   ├── api # 接口文件(管理的是后台中使用的 API ,放在这里管理更规范)
│   ├── assets # 资源文件
│   │   ├── icons # icon sprite 图标文件夹
│   │   ├── images # 项目存放图片的文件夹
│   │   └── svg # 项目存放svg图片的文件夹
│   ├── components # 公共组件(现有 vben 对 AntDesign 组件的二次封装,包括框架层面使用的菜单...)
│   ├── design # 样式文件
│   ├── directives # 指令
│   ├── enums # 枚举/常量(一般用不到)
│   ├── hooks # hook (组件层面,某些位置方便的使用框架中的某些功能,这里封装后并暴漏的出来)
│   │   ├── component # 组件相关hook
│   │   ├── core # 基础hook
│   │   ├── event # 事件相关hook
│   │   ├── setting # 配置相关hook
│   │   └── web # web相关hook
│   ├── layouts # 布局文件(整个框架中的页面布局控制)
│   │   ├── default # 默认布局
│   │   ├── iframe # iframe布局
│   │   └── page # 页面布局
│   ├── locales # 多语言
│   ├── logics # 逻辑
│   ├── main.ts # 主入口
│   ├── router # 路由配置(路由分两个部分,路由/菜单 必须要有路由,菜单才会生效,如果有菜单,没有路由,菜单是不会显示的)
│   ├── settings # 项目配置
│   │   ├── componentSetting.ts # 组件配置(组件封装的默认数据)
│   │   ├── designSetting.ts # 样式配置
│   │   ├── encryptionSetting.ts # 加密配置
│   │   ├── localeSetting.ts # 多语言配置
│   │   ├── projectSetting.ts # 项目配置
│   │   └── siteSetting.ts # 站点配置
│   ├── store # 数据仓库(数据存储)
│   ├── utils # 工具类
│   └── views # 页面(视图层,组件,页面都在这里面)
├── test # 测试(单元测试相关的)
│   └── server # 测试用到的服务
│       ├── api # 测试服务器
│       ├── upload # 测试上传服务器
│       └── websocket # 测试ws服务器
├── types # 类型文件
├── vite.config.ts # vite配置文件
└── windi.config.ts # windcss配置文件
  1. vben菜单分为前端和后端模式(由于前端模式作者是使用mock作为模拟数据,所以后端模式跟前端模式是区分开来的)
  2. 删除router/routes/module/demo下的跟后端模式没有关联的页面以及相关模块,当然api下的demo接口也可以清除,来使页面结构看起来没有那么冗杂

前期工作准备完毕,开始配置

  • 配置vite
    1. 切换环境
    • https需要做下面的操作 http则不需要
    • 由于整体接口都是使用/api所以可在.env文件中让 VITE_GLOB_API_URL=/api 这样会默认所有接口都在拼接/api
    • 接下来在vite中配置代理
    • 由于是使用的https协议,vite无法直接使用所以在server配置项中配置以下代码
        https: {
          cert: fs.readFileSync(path.join(__dirname, 'keys/cert.crt')),
          key: fs.readFileSync(path.join(__dirname, 'keys/cert.key')),
        }
    
    • 接下来就可以配置登录
  • 登录配置
    1. view/login/Login 是登陆主页 而登录模块是LoginFrom
    • 由于自定义提供的接口跟项目提供的形式不同 所以导致在userStore.login try抛出了异常
    • 异常原因是由于axios封装的返回跟提供的返回不同
    1. src\utils\http\axios\index.ts 文件内重写响应逻辑
    • 在54行解构data时 由于返回的数据结构与原结构不同所以这里使用
      // menuList是后面对接菜单接口所需要的所以它是非必须条件
      const { msg, success, menuList } = data;
      // 增加现在判断返回不满足
      let message: string;
      let code: number;
      // 错误提示也是200所以要额外判断success是否在
      if (res.status === 200) {
        if (success === false) {
          code = -1;
          message = msg;
        } else {
          code = 0;
        }
      } else if (res.status === 401) {
        code = 401;
      } else {
        code = -1;
      }
      // code的赋值跟ResultEnum有关
      // 这里逻辑可以根据项目进行修改
      const hasSuccess = data && code === ResultEnum.SUCCESS;
    
    • 注意data的类型 types\axios.d.ts 更改为所需要的类型,至此源文件更改完毕
    1. src\store\modules\user.ts login方法的逻辑已经完整,可以正常登录
  • 配置用户信息
    1. 经过解析分析发现 src\store\modules\user.ts 在登陆之后会调用获取用户信息接口
    • 由于提供的用户信息接口还需要提供用户信息,此处直接省去了调用获取用户接口
    • 登录接口返回的有用户信息,所以94行解构存储token中在将user解构出来
    • 调用afterLoginAction方法时传入user,调用getUserInfoAction方法传入user
      // 不调用接口
      // const userInfo = await getUserInfo();
    
      // 接口跟框架需求的数据不同,现在数据重赋值
      userInfo.realName = userInfo.name;
      userInfo.userId = userInfo.id;
      const { roles } = userInfo;
    
      // 重构用户权限内容
      for (let index = 0; index < roles.length; index++) {
        // 用户类型判断,新增直接加判断
        if (roles[index] === 'CERT_PROVINCE_BOSS_ADMIN') {
          roles[index] = { roleName: 'Super Admin', value: 'super' };
        }
      }
    
    • 有了用户信息发现没有菜单权限
    1. 转换菜单权限
    • 由于提供的是直接数组,无法满足下面的判断需求,所以将用户类型转化为跟框架类似的返回以满足判断
    • 需注意RoleInfo的类型结构是 src\api\sys\model\userModel.ts
    1. 至此菜单也拥有了
  • 配置为后端管理菜单
    1. 经过前面的判断发现 PermissionModeEnum.BACK 就是切换为后端模式的入口
    • src\settings\projectSetting.ts permissionMode 的值配置为 PermissionModeEnum.BACK 就可以切换为后端模式
    1. 切换为后端模式发现页面没有加载
  • 配置菜单接口
    1. 发现接口增加时间节点参数
    • src\utils\http\axios\index.ts 138行注释掉 在get请求后面增加时间节点参数
    1. 经过前面的经验发现返回数据增加了menuList数组,且不满足之前返回的判断
    • src\utils\http\axios\index.ts 上文提到menuList解构就用到了
    • 在返回之前增加一层菜单接口判断
       // 增加当前为菜单接口的过滤方法(框架提供的跟目前接口冲突)
      if (menuList) {
        return menuList;
      }
      return data;
    
    1. 至此菜单也出现了

存储问题处理

  • 接口配置完毕后,刷新后发现没有数据
    1. 经过分析发现是因为用户信息接口被弃用的原因
    2. 经过思考决定使用短暂存储session的方法去处理刷新后数据丢失的问题
    3. src\App.vue 增加一些逻辑
    • 导入 import { useUserStore } from '/@/store/modules/user';
      // 刷新页面前把用户信息数据放在session里并在刷新完毕
      const setUserStore = useUserStore();
      window.addEventListener('beforeunload', function () {
        window.sessionStorage.setItem('userInfo', JSON.stringify(setUserStore));
      });
      const getUserInfo: any = window.sessionStorage.getItem('userInfo');
      setUserStore.setUserInfo(JSON.parse(getUserInfo));
      // 加载完毕移除
      window.sessionStorage.removeItem('userInfo');
    
    • 刷新之前 => 存储store内的用户信息 => 刷新完毕 => store赋值完毕 => 卸载存储

很多无用文件依然没有清除完毕

结束