SpringBoot+Vue 登录(含验证码)、注册功能

您所在的位置:网站首页 前后端分离登录注册教程 SpringBoot+Vue 登录(含验证码)、注册功能

SpringBoot+Vue 登录(含验证码)、注册功能

2024-07-14 02:49| 来源: 网络整理| 查看: 265

一、初始化项目

参考下面文章,初始vue项目并且引入ElementUI组件

网页制作神器—ElementUI(小白入门超详细)

并且参考基于Axios完成前后端分离项目数据交互 完成 request 请求工具的封装。

最终Vue.js 框架的应用程序的入口文件 main.js 的代码如下:

import Vue from 'vue' import App from './App.vue' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import '@/assets/css/global.css' import '@/assets/css/iconfont/iconfont.css' import '@/assets/css/theme/index.css' import request from "@/utils/request"; // 首先,导入了 Vue、App 组件、router、ElementUI 组件库以及相关CSS 文件。 // 其中,Vue 是 Vue.js 框架的核心库,App 是根组件,router 是路由配置文件,ElementUI 是基于 Vue.js 的 UI 组件库,包括一些常用的界面元素和样式。 //设置了 Vue.config.productionTip 的值为 false,这是对 Vue 配置项的修改,表示阻止在生产环境下产生提示信息。 Vue.config.productionTip = false // 通过 Vue.use(ElementUI, { size: 'small' }) 使用 ElementUI 插件,并设置全局的默认组件尺寸为 small。 Vue.use(ElementUI, { size: 'small' }); // 通过Vue.prototype.request=request将自定义的request对象挂载到Vue实例的原型上,以便在组件中可以通过this.request 访问到该对象。 // 这个request对象可能是用于发送HTTP请求的工具类或者封装了接口请求的方法。 Vue.prototype.$request=request // 创建了一个新的 Vue 实例,配置了 router 和 App 组件,并通过 $mount 方法将实例挂载到 id 为 app 的 HTML 元素上,实现应用程序的渲染和启动。 new Vue({ router, render: h => h(App) // 行代码导入了名为 App 的根组件,并在 render 函数中将其渲染到页面上。h 是 createElement 的别名,用于创建虚拟 DOM 元素 }).$mount('#app')

        render: h => h(App) 是 Vue.js 中的渲染函数 (render function) 的书写方式。它使用箭头函数的语法规则,表示一个匿名函数,接收一个参数 h,并返回 h(App)。在 Vue.js 中,组件的模板可以通过 template 属性来定义,也可以使用渲染函数进行动态渲染。渲染函数可以通过编程方式创建虚拟 DOM,并最终渲染成实际的 DOM 元素。在这里,h 实际上是 createElement 的缩写,它是一个用于创建虚拟 DOM 元素的函数。h(App) 表示调用 createElement 函数来创建一个根据 App 组件生成的虚拟 DOM 对象。

        所以,render: h => h(App) 的意思是将 App 组件渲染为虚拟 DOM 元素,并最终展示在页面上。这种写法在单文件组件中常见,用于使用渲染函数进行动态渲染的情况。

当然还要引入一个验证码插件:ValidCode.vue

{{item.code}} export default { name: 'validCode', data () { return { length: 4, codeList: [] } }, mounted () { this.createdCode() }, methods: { refreshCode () { this.createdCode() }, createdCode () { let len = this.length, codeList = [], chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789', charsLen = chars.length // 生成 for (let i = 0; i < len; i++) { let rgb = [Math.round(Math.random() * 220), Math.round(Math.random() * 240), Math.round(Math.random() * 200)] codeList.push({ code: chars.charAt(Math.floor(Math.random() * charsLen)), color: `rgb(${rgb})`, padding: `${[Math.floor(Math.random() * 10)]}px`, transform: `rotate(${Math.floor(Math.random() * 90) - Math.floor(Math.random() * 90)}deg)` }) } // 指向 this.codeList = codeList // 将当前数据派发出去 this.$emit('update:value', codeList.map(item => item.code).join('')) }, getStyle (data) { return `color: ${data.color}; font-size: ${data.fontSize}; padding: ${data.padding}; transform: ${data.transform}` } } } .ValidCode{ display: flex; justify-content: center; align-items: center; cursor: pointer; } .ValidCode span { display: inline-block; font-size: 18px; }

在登录、注册界面处进行引用: import ValidCode from "@/conponents/ValidCode";即可

二、登录界面: 欢迎登录后台管理系统 登 录 还没有账号?请 注册 忘记密码 取 消 确 定 import ValidCode from "@/conponents/ValidCode"; // 在components属性中,将ValidCode作为一个组件注册进来。这样就可以在模板中使用标签。 export default { name: "Login", components: { ValidCode }, data() { // 验证码校验 const validateCode = (rule, value, callback) => { if (value === '') { callback(new Error('请输入验证码')) } else if (value.toLowerCase() !== this.code) { callback(new Error('验证码错误')) } else { callback() } } return { forgetUserForm: {}, // 忘记密码的表单数据 forgetPassDialogVis: false, code: '', // 验证码组件传递过来的code user: { code: '', // 表单里用户输入的code 验证码 username: '', password: '' }, // trigger属性指定了触发校验的事件类型,这里是在字段失去焦点时触发校验(blur事件)。 rules: { username: [ { required: true, message: '请输入账号', trigger: 'blur' }, ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, ], code: [ { validator: validateCode, trigger: 'blur' } ], } } }, created() { }, methods: { handleForgetPass() { // 初始化表单的数据 this.forgetUserForm = {} this.forgetPassDialogVis = true }, resetPassword() { this.$request.put('/password', this.forgetUserForm).then(res => { if (res.code === '200') { this.$message.success('重置成功') this.forgetPassDialogVis = false } else { this.$message.error(res.msg) } }) }, getCode(code) { this.code = code.toLowerCase() }, login() { this.$refs['loginRef'].validate((valid) => { if (valid) { // 验证通过 this.$request.post('/login', this.user).then(res => { if (res.code === '200') { this.$router.push('/') this.$message.success('登录成功') localStorage.setItem("honey-user", JSON.stringify(res.data)) // 存储用户数据 } else { this.$message.error(res.msg) } }) } }) } } }

        这是一个使用Vue.js编写的登录页面组件,主要包括一个表单和验证码功能。用户可以输入账号、密码和验证码进行登录操作。

        在模板部分,使用了Flex布局将登录框居中显示,并设置了背景颜色。登录框内部分为左右两个部分,左侧为图片展示,右侧为登录表单。登录表单使用了Element UI组件库的el-form和el-input组件,分别用于输入账号、密码和验证码。验证码部分还引入了自定义组件ValidCode来生成验证码。登录按钮点击后会触发login方法进行登录操作。下方还有一个注册和忘记密码的链接。

        在脚本部分,定义了validateCode方法来验证用户输入的验证码是否正确,并在data中定义了相关数据和验证规则。getCode方法用于接收验证码组件传递过来的验证码值。login方法调用后台接口进行登录操作,登录成功后跳转到首页,并将用户数据存储在本地。

$router.push('/register') 是Vue.js中的路由跳转方法。在这段代码中,点击注册链接时会调用$router.push('/register')方法,将当前页面的路由跳转到/register,即注册页面。

$router 是Vue Router提供的路由实例,它包含了一些用于导航的方法,如push用于向history栈中添加新的记录,并跳转到指定的地址。

所以,$router.push('/register') 的作用是跳转到注册页面。当用户点击“还没有账号?请注册”时,就会触发这个方法并跳转到注册页面。

三、注册界面 欢迎注册后台管理系统 注 册 已经有账号了?请 登录 // export default 的作用是将整个组件对象作为模块的默认导出,方便其他文件引入和使用。 export default { name: "Register", data() { // 验证码校验 const validatePassword = (rule, confirmPass, callback) => { if (confirmPass === '') { callback(new Error('请确认密码')) } else if (confirmPass !== this.user.password) { callback(new Error('两次输入的密码不一致')) } else { callback() } } return { user: { username: '', password: '', confirmPass: '' }, rules: { username: [ { required: true, message: '请输入账号', trigger: 'blur' }, ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, ], confirmPass: [ { validator: validatePassword, trigger: 'blur' } ], role: [ { required: true, message: '请选择角色', trigger: 'blur' }, ], } } }, created() { }, methods: { register() { this.$refs['registerRef'].validate((valid) => { if (valid) { // 验证通过 this.$request.post('/register', this.user).then(res => { if (res.code === '200') { this.$router.push('/login') this.$message.success('注册成功') } else { this.$message.error(res.msg) } }) } }) } } }  四、后端接口 @RestController public class WebController { @Resource UserService userService; @PostMapping("/login") public Result login(@RequestBody User user) { if (StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getPassword())) { return Result.error("数据输入不合法"); } user = userService.login(user); return Result.success(user); } @AuthAccess @PostMapping("/register") public Result register(@RequestBody User user) { if (StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getPassword()) || StrUtil.isBlank(user.getRole())) { return Result.error("数据输入不合法"); } if (user.getUsername().length() > 10 || user.getPassword().length() > 20) { return Result.error("数据输入不合法"); } user = userService.register(user); return Result.success(user); } }

当然,此处还要引入一个 国产的工具类依赖:(或者使用别的工具包也行)

cn.hutool hutool-all 5.8.18 @Service public class UserService { @Autowired UserMapper userMapper; // 验证用户账户是否合法 public User login(User user) { // 根据用户名查询数据库的用户信息 User dbUser = userMapper.selectByUsername(user.getUsername()); if (dbUser == null) { // 抛出一个自定义的异常 throw new ServiceException("用户名或密码错误"); } if (!user.getPassword().equals(dbUser.getPassword())) { throw new ServiceException("用户名或密码错误"); } // 生成token String token = TokenUtils.createToken(dbUser.getId().toString(), dbUser.getPassword()); dbUser.setToken(token); return dbUser; } public User register(User user) { User dbUser = userMapper.selectByUsername(user.getUsername()); if (dbUser != null) { // 抛出一个自定义的异常 throw new ServiceException("用户名已存在"); } user.setName(user.getUsername()); userMapper.insert(user); return user; } }

 全局异常和自定义异常:

package com.example.springboot.exception; import com.example.springboot.common.Result; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class GlobalException { @ExceptionHandler(ServiceException.class) @ResponseBody public Result serviceException(ServiceException e) { return Result.error(e.getCode(), e.getMessage()); } @ExceptionHandler(Exception.class) @ResponseBody public Result globalException(Exception e) { e.printStackTrace(); return Result.error("500", "系统错误"); } } package com.example.springboot.exception; import lombok.Getter; @Getter public class ServiceException extends RuntimeException { private final String code; public ServiceException(String msg) { super(msg); this.code = "500"; } public ServiceException(String code, String msg) { super(msg); this.code = code; } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3