文章目录

  • 前言
  • 登陆
    • 点击登陆
    • validForm
    • Pinia
      • userStore.login
      • userStore.afterLoginAction
      • userStore.getUserInfoAction
  • 退出登陆
    • 退出系统
    • Pinia
      • userStore.confirmLoginOut
      • userStore.logout
  • 记住我
  • 尾巴

前言

本文章只是一个思路的梳理,只扒TS的逻辑过程(模板的暂时不涉及,以后有机会再补上吧),作为个人的源码学习记录,不喜勿喷。

源码来源 Vben Admin

登陆

点击登陆

点击登陆按钮的相关文件在src/views/sys/login/LoginForm.vue中,我们来逐句分析,遇到一些封装的地方再往下翻翻可以看到(建议复制一个相同页面用来往下翻找对照来看)。

import { useUserStore } from '/@/store/modules/user'; // 获取user相关的所有状态管理(Pinia)const formRef = ref(); // 获取表单实例const { validForm } = useFormValid(formRef); // 获取表单内容的hooksasync function handleLogin() {const data = await validForm(); // 首先获取表单内容,hooks逻辑看下面if (!data) return;try {loading.value = true; // 开启组件加载动画const userInfo = await userStore.login({ // 调用Pinia的登陆逻辑,逻辑看下面password: data.password,username: data.account,mode: 'none', //不要默认的错误提示});if (userInfo) {// 有用户信息,就提示登陆成功notification.success({message: t('sys.login.loginSuccessTitle'),description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`,duration: 3,});}} catch (error) {createErrorModal({title: t('sys.api.errorTip'),content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'),getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,});} finally {loading.value = false;}}

这里的整体大概逻辑就是:

  1. 获取表单输入内容
  2. 发送ajax登陆
  3. 接着去获取用户信息,有的话就登陆成功(具体怎么拿用户数据的逻辑在下面)

validForm

这个函数在src/views/sys/login/useLogin.vue中:

import { ref, computed, unref, Ref } from 'vue';export function useFormValid<T extends Object = any>(formRef: Ref<any>) {// 泛型T被约束成对象,但是这个等于any我还不知到啥意思,知道的可以评论下// 入参类型是具备响应式的任意类型async function validForm() {const form = unref(formRef);// unref官网解释:如果参数是一个 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 的语法糖函数。if (!form) return;const data = await form.validate(); // 自封组件的hooks,拿取输入的内容并校验(以后在讲自封组件)return data as T;}return { validForm }; // 做成异步调用返回出去
}

疑问:这里校验为什么还要再封一层而不直接调用呢?留个坑以后看他的自封组件后了解一下。

Pinia

user相关的状态管理actions方法,文件在src\store\modules\user.ts,

userStore.login

登陆逻辑。里面涉及到的api interface和请求在这里就不细讲了,放在以后管理api解析。token也是管理以后讲:

async login(params: LoginParams & { // LoginParams是入参的类型,以后会专门讲个vben是怎么管理api的。goHome?: boolean; // 合并入参:是否跳转到首页mode?: ErrorMessageMode; // 合并入参:},
): Promise<GetUserInfoModel | null> { // Promise的泛型代表promise变成成功态之后resolve的值, GetUserInfoModel是api的interfacetry {const { goHome = true, mode, ...loginParams } = params;const data = await loginApi(loginParams, mode); // 发送ajax请求,登陆const { token } = data;// save tokenthis.setToken(token); // token管理以后讲return this.afterLoginAction(goHome); // 调用登陆之后做的逻辑函数,后面讲} catch (error) {return Promise.reject(error);}
},

大概逻辑就是:

  1. 发送登陆ajax
  2. 设置token
  3. 调用登陆之后做的事情的函数,返回用户信息

userStore.afterLoginAction

调用登陆之后做的逻辑函数,之前很好奇为什么不直接把登陆后的逻辑写在点击登陆哪里,后来看到在权限控制哪里也调用了这个方法。所以专门封装成一个动作了。

async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> {if (!this.getToken) return null;// get user infoconst userInfo = await this.getUserInfoAction(); // 获取用户信息,下面讲const sessionTimeout = this.sessionTimeout; // state,是否登陆过期if (sessionTimeout) {this.setSessionTimeout(false); // 修改sessionTimeout} else {// 接下来都是权限和路由的处理。以后再讲。const permissionStore = usePermissionStore();if (!permissionStore.isDynamicAddedRoute) {const routes = await permissionStore.buildRoutesAction();routes.forEach((route) => {router.addRoute(route as unknown as RouteRecordRaw);});router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);permissionStore.setDynamicAddedRoute(true);}goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME)); // 跳转到首页}return userInfo;
},

大概逻辑:

  1. 获取用户信息
  2. 判断是否登陆过期
  3. 权限处理
  4. 返回用户信息

userStore.getUserInfoAction

获取用户信息

async getUserInfoAction(): Promise<UserInfo | null> {if (!this.getToken) return null;const userInfo = await getUserInfo(); // ajax请求,获取用户信息const { roles = [] } = userInfo; // 拿到角色,关于权限的以后再讲if (isArray(roles)) {const roleList = roles.map((item) => item.value) as RoleEnum[];this.setRoleList(roleList);} else {userInfo.roles = [];this.setRoleList([]);}this.setUserInfo(userInfo); // 设置用户信息,里面的关于权限以后再讲return userInfo;
},

大概逻辑:

  1. 发送ajax请求获取用户信息
  2. 角色权限数据处理
  3. 存储用户信息
  4. 返回用户信息

退出登陆

退出系统

在src\layouts\default\header\components\user-dropdown\index.vue文件中:

function handleLoginOut() {userStore.confirmLoginOut(); // 调用退出登陆确认框
}

Pinia

user相关的状态管理actions方法,文件在src\store\modules\user.ts,

userStore.confirmLoginOut

退出登陆确认框逻辑

confirmLoginOut() {const { createConfirm } = useMessage(); // 创建确认对话框 hooksconst { t } = useI18n(); // 多语言实例,以后讲createConfirm({iconType: 'warning',title: () => h('span', t('sys.app.logoutTip')),content: () => h('span', t('sys.app.logoutMessage')),onOk: async () => {await this.logout(true); // 调用对出登陆},});
},

userStore.logout

async logout(goLogin = false) {if (this.getToken) { // 有tokentry {await doLogout(); // 发送ajax注销} catch {console.log('注销Token失败');}}// 清除相关数据this.setToken(undefined);this.setSessionTimeout(false);this.setUserInfo(null);goLogin && router.push(PageEnum.BASE_LOGIN); // 是否需要跳转到登录页
},

记住我

居然没找到对应的逻辑。

尾巴

看了这个登陆处理的大概逻辑,有几个想法

  • 好像没看到加密传输处理
  • 把每个动作都很好的做了切割,命名见词答意
  • 如果在登陆逻辑内的权限处理也能统一封装成一个见词答意的方法就更好了

【场景方案】捋一捋Vben Admin之登陆方案(学习记录)相关推荐

  1. Vue vben admin - 新鲜出炉的高颜值管理后台UI框架,基于 Vue3 和 Ant Design Vue

    基于Vue3.0 / Vite / Ant Design 等火热开源项目构建,新鲜出炉,值得关注. 关于 Vue vben admin Vue Vben Admin 是一个基于 Vue3.0.Vite ...

  2. 乐鑫esp8266学习rtos3.0笔记第4篇:带你捋一捋微信公众号 airkiss 配网 esp8266 并绑定设备的过程,移植并成功实现在 esp8266 rtos3.1 sdk。(附带demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1. Esp8266之 搭建开发环境,开始一个"hello ...

  3. android+原点扩散动画,捋一捋Android的转场动画

    捋一捋Android的转场动画 由于录制的gif过大,导致CSDN部分gif无法显示,可以传送到GitHub查看本篇博客 背景 随着 Material Design设计概念的提出,使得很多的开发过程中 ...

  4. 小猪的Python学习之旅 —— 6.捋一捋Python线程概念

    小猪的Python学习之旅 -- 6.捋一捋Python线程概念 标签: Python 引言 从刚开始学习Python爬虫的时候,就一直惦记着多线程这个东西, 想想每次下载图片都是单线程,一个下完继续 ...

  5. 捋一捋PDF、PMF、CDF是什么

    总第230篇/张俊红 还记得前段时间看过一篇文章,就是调查大家疫情期间都干了什么,有一条是疫情期间终于弄清楚了PDF和CDF的区别.PDF.PMF.CDF这几个概念确实很容易混淆.今天就来捋一捋这几个 ...

  6. 捋一捋js面向对象的继承问题

    说到面向对象这个破玩意,曾经一度我都处于很懵逼的状态,那么面向对象究竟是什么呢?其实说白了,所谓面向对象,就是基于类这个概念,来实现封装.继承和多态的一种编程思想罢了.今天我们就来说一下这其中继承的问 ...

  7. 朵拉云提供最简单的免费虚拟化方案:Hyper-V Server + Windows Admin Center

    最简单的免费虚拟化方案:Hyper-V Server + Windows Admin Center 一机多用的同时,想要服务器尽可能的稳定.至于软硬件的选择就是另一个故事了,这里我们来谈谈虚拟化. 为 ...

  8. Vben Admin

    //项目结构 . ├── build # 打包脚本相关 │ ├── config # 配置文件 │ ├── generate # 生成器 │ ├── script # 脚本 │ └── vite # ...

  9. 【Vben Admin】

    Vben Admin 初体验 环境准备 安装依赖 yarn 安装 全局安装yarn 验证 目录说明 菜单 新增菜单 菜单排序 接口请求 axios配置 打包 环境准备 本地环境需要安装 Yarn1.x ...

  10. 分布式场景实战第六节 微服务数据治理方案

    16 数据一致性:下游服务失败上游服务如何独善其身? 前面三讲我们聊了微服务的 9 个痛点,有些痛点没有好的解决方案,而有些痛点刚好有一些对策,后面的课程我们就来讲解某些痛点对应的解决方案. 这一讲我 ...

最新文章

  1. jQuery:计算表中的行数
  2. 芯片巨人也要搞医疗?
  3. 和与余数的和同余理解_每日一题 | 第38期:数量关系之余数特性
  4. 4-1 复数类的运算符重载
  5. 8.1 A Bayesian Methodology for Systemic Risk Assessment in Financial Networks(3)
  6. 站着办公有助减轻体重
  7. Grafana Worldmap外网用户request地图监控
  8. php代码导入sql,php导入SQL文件(示例代码)
  9. 吉他谱----see you again
  10. 解决SpringBoot多模块发布时99%的问题?SpringBoot发布的8个原则和4个问题的解决方案
  11. AptanaStudio3+PHP程序远程调试的方法和步骤
  12. 软件自动化测试题,软件自动化测试模拟题.doc
  13. 在哪里搜python题_robots文件生成
  14. vue项目中使用axios发送请求
  15. 数据切分——MySql表分区概述
  16. 3709: [PA2014]Bohater
  17. mysql分区数据覆盖_彻底搞懂MySQL分区
  18. Word控件Spire.Doc 【文本】教程(14) ;如何用图片替换Word中的文字
  19. 空域图像增强-图像灰度变换
  20. vk和uview表单图片上传

热门文章

  1. 6-1 单链表逆转 (20 分)
  2. Python开发【模块】:Urllib(二)
  3. 金融套利策略:理解统计套利的工作原理
  4. 了不起的大中国—移动支付
  5. Exp3 免杀原理与实践 ——20164316张子遥
  6. 聚亚烷基二醇的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  7. Python操作word插入对象
  8. 计算机有两个桌面,你好,我的电脑有两个桌面怎么处理
  9. 简单的个人介绍网页【附代码】
  10. 安恒月赛-dasctf 部分writeup