首页  

RuoYi-Vue3 登录 前端代码笔记     所属分类 vue 浏览量 108
若依前后端分离版,前端Vue3版本
https://github.com/yangzongzhuan/RuoYi-Vue3



RUOYI-VUE3/src/views/login.vue

验证码
function getCode() {
  getCodeImg().then(res => {
    captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
    if (captchaEnabled.value) {
      codeUrl.value = "data:image/gif;base64," + res.img; //后端返回的验证码图片base64
      loginForm.value.uuid = res.uuid;
    }
  });
}
//页面初始化, 获取验证码
getCode();

getCodeImg()方法封装在 RUOYI-VUE3/src/api/login.js

// 获取验证码
export function getCodeImg() {
  return request({
    url: '/captchaImage',
    headers: {
      isToken: false
    },
    method: 'get',
    timeout: 20000
  })
}

前端Vue和后端Springboot交互 使用axios
getCodeImg()方法内还有一个 request() 封装在 RUOYI-VUE3/src/utils/request.js

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: import.meta.env.VITE_APP_BASE_API,
  // 超时
  timeout: 10000
})

VITE_APP_BASE_API 常量定义

dev环境  .env.development

前端请求url为:http://localhost/dev-api/captchaImage

request.js 封装了一个baseURL, 然后getCodeImg()方法里写了/captchaImage接口地址


反向代理
后端运行在localhost:8080端口上,前端运行在localhost:80端口上。
浏览器访问的是前端项目,如果要调用后端接口,会跨域。
跨域问题可以由后端解决:写一个允许跨域的配置类
跨域问题也可以由前端解决:反向代理。

反向代理配置
RUOYI-VUE3/vite.config.js


// vite 相关配置
    server: {
      port: 80,
      host: true,
      open: true,
      proxy: {
        // https://cn.vitejs.dev/config/#server-proxy
        '/dev-api': {
          target: 'http://localhost:8080',
          changeOrigin: true,
          rewrite: (p) => p.replace(/^\/dev-api/, '')
        }
      }
    },

'/dev-api' 是代理的前缀路径,表示所有以 ‘/dev-api’ 开头的请求都会被代理。
target: 'http://localhost:8080' 指定了代理的目标地址,即真实的后端服务地址。
changeOrigin: true 通常是设置为 true,以便确保请求头中的 Host 字段保持一致,防止一些反向代理的问题。
rewrite: (p) => p.replace(/^\/dev-api/, '') 用于重写请求路径,它将路径中的 ‘/dev-api’ 前缀去掉,以适应后端的实际路径

/dev-api/captchaImage
请求代理到 http://localhost:8080/captchaImage


登录
和验证码一样的流程,登录功能主要由handleLogin()方法实现

userStrore 
RUOYI-VUE3/src/store/module/user.js 
Vuex的用法

Vuex
集中式状态管理
当应用变得复杂时,组件之间共享状态可能变得困难。
Vuex 提供了一个集中式的状态管理机制,使状态的变化可预测且容易调试。

全局访问
通过 Vuex,可以在任何组件中访问相同的状态。
在组件之间共享数据,而不需要通过繁琐的组件通信来传递数据。

状态持久化
Vuex 将状态持久化到本地存储,以便在页面刷新或重新加载时仍然保留应用的状态。

userStrore
const useUserStore = defineStore(
  'user',
  {
    state: () => ({
      token: getToken(),
      name: '',
      avatar: '',
      roles: [],
      permissions: []
    }),
    actions: {
       login(userInfo) {
    		// ...
  		},
  		getInfo() {
    		// ...
  		},
  		logOut() {
    		// ...
  		}
    }
  }
)
export default useUserStore



defineStore 是 Vuex4 中新引入的函数,用于创建 store 模块。
'user'是模块的名称
state 中定义了用户模块的初始状态,包括 token、name、avatar、roles 和 permissions 等初始状态信息。
action中定义登录相关的 actions
最后导出useUserStore,在应用的其他地方可以引入并使用这个 store 模块


外层login(userInfo) 方法.
根据传入的用户信息构建并返回一个Promise,它是es6提供的异步处理的对象
里面的login(username, password, code, uuid) 和前面的getCodeImg()方法一样,在RUOYI-VUE3/src/api/login.js中,封装的一个request

	login(userInfo) {
        const username = userInfo.username.trim()
        const password = userInfo.password
        const code = userInfo.code
        const uuid = userInfo.uuid
        return new Promise((resolve, reject) => {
          login(username, password, code, uuid).then(res => {
            setToken(res.token)
            this.token = res.token
            resolve()
          }).catch(error => {
            reject(error)
          })
        })
      },

登录成功后,后端返回Token.

import Cookies from 'js-cookie'

const TokenKey = 'Admin-Token'

export function getToken() {
  return Cookies.get(TokenKey)
}

export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

export function removeToken() {
  return Cookies.remove(TokenKey)
}


setToken(res.token) 把后端返回的Token放到Cookies中

Vue Router
//使用 Vue Router 中的 useRouter 函数创建了一个 router 对象。
const router = useRouter()

常见用法

// 字符串
router.push('home')
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
//对象
router.push({ path: redirect.value || "/" });

router的 push方法和replace方法的详细用法
https://blog.csdn.net/sunhuaqiang1/article/details/85220888

点击登录后,后端业务会去验证:验证码、账号、密码,正确就登录成功。
后端登录方法中还会调用recordLoginInfo()方法记录登录信息,写入日志。

获取用户角色和权限
登录成功后,还会调用getInfo 和getRouters
它们是在RUOYI-VUE3/src/permission.js 中被调用的
beforeEach 是 Vue Router 提供的全局前置守卫函数,前端每个页面进行跳转前都会执行这个函数。

router.beforeEach((to, from, next) => {
  NProgress.start()
  if (getToken()) {
    to.meta.title && useSettingsStore().setTitle(to.meta.title)
    /* 如果即将进入的路由是 /login,则直接重定向到根路径 /,表示已经登录的情况下不允许再访问登录页面。*/
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      //如果角色信息未获取,则去请求user_info和路由表
      if (useUserStore().roles.length === 0) {
        isRelogin.show = true
        // 判断当前用户是否已拉取完user_info信息
        useUserStore().getInfo().then(() => {
          isRelogin.show = false
          usePermissionStore().generateRoutes().then(accessRoutes => {
            // 根据roles权限生成可访问的路由表
            accessRoutes.forEach(route => {
              if (!isHttp(route.path)) {
                router.addRoute(route) // 动态添加可访问路由表
              }
            })
            next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
          })
        }).catch(err => {
          useUserStore().logOut().then(() => {
            ElMessage.error(err)
            next({ path: '/' })
          })
        })
      } else {
        next()
      }
    }
  } else {
    // 没有token
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登录白名单,直接进入
      next()
    } else {
      next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

上一篇     下一篇
vue2 vue3 比较

vue3 核心技术

vue3 vite 和 Vue-CLI

vue3 技术栈

JdbcTemplate BeanPropertyRowMapper 使用

家常炒挂面