Vue实现登录功能

一、Vue登录逻辑梳理:

1、登录流程

  • 用户在前端输入用户名和密码,点击登录按钮。

登录成功后的逻辑:

主要功能和流程:

  1. 异步函数 signInSuccess:这是一个异步函数,使用了 async 关键字,意味着函数内部可能包含异步操作。

  2. 后端权限控制 :首先调用 initBackEndControlRoutes() 函数来初始化后端控制路由,并等待其返回结果。如果 isNoPower 为真(即没有权限),则显示警告消息,清除会话信息(可能是用户信息或令牌等)。

  3. 登录成功处理:如果有权限,继续执行登录成功后的逻辑。具体包括:

    • 初始化当前时间信息并格式化。
    • 检查路由中是否有 redirect 参数,如果有则根据参数进行路由跳转,否则跳转到根路径 /
    • 显示登录成功提示信息,包括当前时间和登录文本。
    • 启动加载状态,可能是为了防止页面首次加载时出现空白或显示加载状态。
  4. 路由跳转:根据条件进行路由跳转,可能是根据 URL 中的参数决定跳转目标。

  5. 消息提示 :使用 useMessage() 函数来显示不同类型的消息,包括警告和成功消息。

  6. 加载状态 :使用 NextLoading.start() 来启动加载状态,可能是为了提供更好的用户体验。

总体来说,这段代码主要负责处理用户登录成功后的一系列操作,包括权限控制、路由跳转、消息提示和加载状态管理。如果你有任何具体问题或需要进一步解释,请随时告诉我。

全局的加载状态管理功能:

NextLoading 的对象,用于管理页面的全局加载状态。让我来解释一下这段代码的主要功能和结构:

  1. 导入依赖 :代码中导入了 Vue 3 中的 nextTick 方法以及一个自定义的样式表 loading.scss

  2. 全局 Loading 对象NextLoading 对象包含两方法:

    • start() 方法 :用于创建加载状态。在页面中动态创建一个包含加载动画的元素,并插入到页面的顶部,显示加载状态。设置了 window.nextLoading 变量为 true,可能用于全局状态管理。
    • done(time) 方法 :用于移除加载状态。通过 nextTick 等待页面更新后再执行,可以传入一个延迟时间 time,在延迟后移除加载状态元素,并将 window.nextLoading 变量设置为 false
  3. 加载元素结构start() 方法中创建的加载状态元素包含了一组加载动画的 HTML 结构,通过设置不同的类名和样式来展示加载效果。

  4. 动态插入和移除 :在 start() 方法中,将创建的加载状态元素插入到页面的顶部,显示加载状态。在 done() 方法中,通过查询元素并移除的方式来隐藏加载状态。

  5. 全局状态管理 :通过设置 window.nextLoading 变量来记录加载状态,可能在其他地方用于判断页面是否处于加载状态。

这段代码的作用是在页面中实现一个全局的加载状态管理功能,通过调用 NextLoading.start()NextLoading.done() 方法来显示和隐藏加载状态。这样的实现可以提升用户体验,让用户清晰地知道页面正在加载中。

JS:

javascript 复制代码
/**
 * 页面全局 Loading
 * @method start 创建 loading
 * @method done 移除 loading
 */
const NextLoading = {
    // 创建 loading
    start: () => {
        const bodys = document.body;
        const div = document.createElement('div');
        div.setAttribute('class', 'loading-next');
        const htmls = `
            <div class="loading-next-box">
                <div class="loading-next-box-warp">
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                    <div class="loading-next-box-item"></div>
                </div>
            </div>
        `;
        div.innerHTML = htmls;
        bodys.insertBefore(div, bodys.childNodes[0]);
        window.nextLoading = true;
    },
    // 移除 loading
    done: (time = 0) => {
        setTimeout(() => {
            window.nextLoading = false;
            const el = document.querySelector('.loading-next');
            if (el) {
                el.parentNode.removeChild(el);
            }
        }, time);
    },
};

前端控制路由的初始化方法和相关功能的实现。它主要涉及到前端控制路由的权限管理和动态路由添加。以下是代码的详细介绍:

  1. 初始化前端控制路由initFrontEndControlRoutes 方法是用于初始化前端控制路由的方法。它包括界面 loading 动画开始执行、初始化用户信息、添加动态路由以及设置递归过滤有权限的路由到 Pinia 的 routesList 中。

  2. 添加动态路由setAddRoute 方法用于添加动态路由。它循环处理 baseRoutes 第一个顶级 children 的路由一维数组,并通过 router.addRoute 方法添加路由。

  3. 删除/重置路由frontEndsResetRoute 方法用于删除或重置路由。它也循环处理 baseRoutes 第一个顶级 children 的路由一维数组,并通过 router.removeRoute 方法删除路由。

  4. 过滤有权限的路由setFilterRouteEnd 方法用于获取有当前用户权限标识的路由数组,并进行对原路由的替换。它替换 baseRoutes 第一个顶级 children 的路由,并添加 notFoundAndNoPower 路由。

  5. 缓存多级嵌套数组处理后的一维数组setCacheTagsViewRoutes 方法用于缓存多级嵌套数组处理后的一维数组。它用于 tagsView、菜单搜索中,未过滤隐藏的路由。

  6. 设置递归过滤有权限的路由setFilterMenuAndCacheTagsViewRoutes 方法用于设置递归过滤有权限的路由到 Pinia 的 routesList 中,并缓存多级嵌套数组处理后的一维数组。

  7. 判断用户权限hasRoles 方法用于判断路由的 meta.roles 中是否包含当前登录用户的权限字段。

  8. 过滤有权限的路由setFilterHasRolesMenu 方法用于获取当前用户权限标识去比对路由表,设置递归过滤有权限的路由。

这些方法共同实现了前端控制路由的权限管理和动态路由添加的功能。

  • 前端发送登录请求到后端的登录接口,携带用户名和密码。
  • 后端接收请求,验证用户名和密码,验证成功后生成一个 token,并返回给前端。

2.Token 存储

前端接收到 token 后,将 token 存储到 localStorage 、sessionStorage和 Vuex (pinia)中。

2.1 封装 localStoragesessionStorage:

javascript 复制代码
import Cookies from "js-cookie";

const Local = {
    setKey(key) {
        return `${__NEXT_NAME__}:${key}`;
    },
    set(key, val) {
        window.localStorage.setItem(Local.setKey(key), JSON.stringify(val));
    },
    get(key) {
        let json = window.localStorage.getItem(Local.setKey(key));
        return JSON.parse(json);
    },
    remove(key) {
        window.localStorage.removeItem(Local.setKey(key));
    },
    clear() {
        window.localStorage.clear();
    },
};

const Session = {
    set(key, val) {
        if (key === 'token' || key === 'refresh_token') {
            Cookies.set(key, val);
        }
        window.sessionStorage.setItem(key, JSON.stringify(val));
    },
    get(key) {
        if (key === 'token' || key === 'refresh_token') return Cookies.get(key);
        let json = window.sessionStorage.getItem(key);
        return JSON.parse(json);
    },
    remove(key) {
        if (key === 'token' || key === 'refresh_token') return Cookies.remove(key);
        window.sessionStorage.removeItem(key);
    },
    clear() {
        Cookies.remove('token');
        Cookies.remove('refresh_token');
        Cookies.remove('tenantId');
        window.sessionStorage.clear();
    },
    getToken() {
        return this.get('token');
    },
    getTenant() {
        return Local.get('tenantId') ? Local.get('tenantId') : 1;
    },
};

2.前端在每次路由跳转时,检查 localStorage 中是否存在 token,如果不存在则跳转到登录页面。

3.请求头携带 Token

  • 在每次向后端发送请求时,前端在请求头中加入 token,以便后端验证用户身份。

4.后端验证 Token

  • 后端在接收到请求时,判断请求头中是否携带 token。
  • 如果有 token,后端验证 token 的有效性,验证成功则返回数据,验证失败(如 token 过期)则返回 401 状态码。
  • 如果请求头中没有 token,则返回 401 状态码。

5.401 状态码处理

  • 前端在接收到 401 状态码时,清除 localStorage 和 Vuex 中的 token 信息。
  • 前端跳转到登录页面,提示用户重新登录。
  • 可以考虑实现一个 token 刷新机制,尝试使用 refresh token 来获取新的 access token,避免用户频繁登录。
相关推荐
GISer_Jing5 分钟前
前端面试常考题目详解
前端·javascript
Boilermaker19921 小时前
【Java EE】SpringIoC
前端·数据库·spring
中微子1 小时前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10241 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y2 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁2 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry2 小时前
Fetch 笔记
前端·javascript
拾光拾趣录2 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟2 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan2 小时前
一文了解什么是Dart
前端·flutter·dart