基于 Vue 和 SSM 的前后端分离项目实战:登录与注册功能实现

文章目录

    • 前言
    • 项目概述
    • 前端部分(Vue)
      • 1. 项目初始化
      • 2. 页面布局
        • Login.vue
        • Register.vue
      • 3. 路由配置
      • 4. 主组件
    • 后端部分(SSM)
      • 1. 项目结构
      • 2. 数据库设计
      • 3. MyBatis 配置
      • 4. DAO 层
      • 5. Service 层
      • 6. Controller 层
      • 7. 配置文件
      • 8. Spring 配置
      • 9. Servlet 配置
      • 10. 部署到 Tomcat
    • 总结

前言

在现代 Web 开发中,前后端分离架构已经成为主流。前端负责页面展示和交互,后端提供数据接口,二者通过 API 进行通信。本文将通过一个实战小项目,详细介绍如何使用 Vue.js 搭建前端界面,以及使用 SSM 框架(Spring、SpringMVC、MyBatis)构建基于 Tomcat 部署的后端服务,实现登录和注册功能。

项目概述

我们将构建一个简单的用户管理系统,包含用户注册和登录功能。前端使用 Vue.js 框架,后端使用 SSM 框架进行开发,并通过 Tomcat 部署后端服务。通过这个项目,可以深入理解前后端分离的开发模式以及各个框架的使用方法。

前端部分(Vue)

1. 项目初始化

首先,使用 Vue CLI 创建一个新的 Vue 项目:

vue create user-management

选择默认的配置或者根据自己的需求进行定制。创建完成后,进入项目目录:

cd user-management

然后安装所需的依赖:

npm install axios vue-router element-ui
  • axios 用于发送 HTTP 请求。
  • vue-router 用于实现页面路由。
  • element-ui 是一个基于 Vue 的 UI 组件库,用于快速构建页面。

2. 页面布局

src/views 目录下创建两个视图文件:Login.vueRegister.vue,分别用于登录和注册页面。

Login.vue
<template><div class="login-container"><el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="80px"><el-form-item label="用户名" prop="username"><el-input v-model="loginForm.username"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" v-model="loginForm.password"></el-input></el-form-item><el-button type="primary" @click="submitLogin">登录</el-button></el-form></div>
</template><script>
export default {data() {return {loginForm: {username: '',password: ''},rules: {username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' }]}};},methods: {submitLogin() {this.$refs.loginForm.validate((valid) => {if (valid) {// 调用后端接口axios.post('/api/login', this.loginForm).then(response => {if (response.data.success) {this.$message.success('登录成功');// 保存 tokenlocalStorage.setItem('token', response.data.token);this.$router.push('/home');} else {this.$message.error(response.data.message);}});}});}}
};
</script>
Register.vue
<template><div class="register-container"><el-form :model="registerForm" :rules="rules" ref="registerForm" label-width="80px"><el-form-item label="用户名" prop="username"><el-input v-model="registerForm.username"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" v-model="registerForm.password"></el-input></el-form-item><el-form-item label="确认密码" prop="confirmPassword"><el-input type="password" v-model="registerForm.confirmPassword"></el-input></el-form-item><el-button type="primary" @click="submitRegister">注册</el-button></el-form></div>
</template><script>
export default {data() {return {registerForm: {username: '',password: '',confirmPassword: ''},rules: {username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' }],confirmPassword: [{ required: true, message: '请确认密码', trigger: 'blur' }]}};},methods: {submitRegister() {this.$refs.registerForm.validate((valid) => {if (valid) {if (this.registerForm.password !== this.registerForm.confirmPassword) {this.$message.error('两次密码不一致');return;}// 调用后端接口axios.post('/api/register', this.registerForm).then(response => {if (response.data.success) {this.$message.success('注册成功');this.$router.push('/login');} else {this.$message.error(response.data.message);}});}});}}
};
</script>

3. 路由配置

src/router/index.js 中配置路由:

import Vue from 'vue';
import VueRouter from 'vue-router';
import Login from '../views/Login.vue';
import Register from '../views/Register.vue';
import Home from '../views/Home.vue';Vue.use(VueRouter);const routes = [{path: '/',redirect: '/login'},{path: '/login',component: Login},{path: '/register',component: Register},{path: '/home',component: Home}
];const router = new VueRouter({mode: 'history',routes
});export default router;

4. 主组件

src/App.vue 中设置主组件:

<template><div id="app"><router-view></router-view></div>
</template>

后端部分(SSM)

1. 项目结构

后端项目采用 Maven 构建,主要模块包括:

  • src/main/java/com/example/usermanagement/controller:控制器层,处理前端请求。
  • src/main/java/com/example/usermanagement/service:服务层,处理业务逻辑。
  • src/main/java/com/example/usermanagement/dao:数据访问层,使用 MyBatis 操作数据库。
  • src/main/resources/mapper:MyBatis 的 XML 映射文件。
  • src/main/resources/application.properties:配置文件。

2. 数据库设计

创建一个名为 user_management 的数据库,包含一个 user 表:

CREATE TABLE user (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,password VARCHAR(100) NOT NULL
);

3. MyBatis 配置

src/main/resources/mapper/UserMapper.xml 中配置 MyBatis 的 SQL 映射:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.usermanagement.dao.UserDao"><insert id="registerUser" parameterType="com.example.usermanagement.model.User">INSERT INTO user (username, password) VALUES (#{username}, #{password})</insert><select id="getUserByUsername" parameterType="String" resultType="com.example.usermanagement.model.User">SELECT * FROM user WHERE username = #{username}</select></mapper>

4. DAO 层

创建 UserDao 接口:

package com.example.usermanagement.dao;import com.example.usermanagement.model.User;public interface UserDao {int registerUser(User user);User getUserByUsername(String username);
}

5. Service 层

创建 UserService 接口及其实现类 UserServiceImpl

package com.example.usermanagement.service;import com.example.usermanagement.model.User;public interface UserService {boolean register(User user);boolean login(String username, String password);
}
package com.example.usermanagement.service.impl;import com.example.usermanagement.dao.UserDao;
import com.example.usermanagement.model.User;
import com.example.usermanagement.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Overridepublic boolean register(User user) {return userDao.registerUser(user) > 0;}@Overridepublic boolean login(String username, String password) {User user = userDao.getUserByUsername(username);return user != null && user.getPassword().equals(password);}
}

6. Controller 层

创建 UserController

package com.example.usermanagement.controller;import com.example.usermanagement.model.User;
import com.example.usermanagement.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api")
public class UserController {@Autowiredprivate UserService userService;@PostMapping("/register")public Result register(@RequestBody User user) {if (userService.register(user)) {return new Result(true, "注册成功");} else {return new Result(false, "注册失败");}}@PostMapping("/login")public Result login(@RequestBody User user) {if (userService.login(user.getUsername(), user.getPassword())) {return new Result(true, "登录成功", "token");} else {return new Result(false, "用户名或密码错误");}}class Result {private boolean success;private String message;private Object data;public Result(boolean success, String message) {this.success = success;this.message = message;}public Result(boolean success, String message, Object data) {this.success = success;this.message = message;this.data = data;}// Getter 和 Setter 方法}
}

7. 配置文件

src/main/resources/application.properties 中配置数据库连接和 MyBatis:

spring.datasource.url=jdbc:mysql://localhost:3306/user_management
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Drivermybatis.mapper-locations=classpath:mapper/*.xml

8. Spring 配置

创建 Spring 配置文件 spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.example.usermanagement"/><mvc:annotation-driven/><!-- 数据源配置 --><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="url" value="${spring.datasource.url}"/><property name="username" value="${spring.datasource.username}"/><property name="password" value="${spring.datasource.password}"/><property name="driverClassName" value="${spring.datasource.driver-class-name}"/></bean><!-- MyBatis SqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="mapperLocations" value="classpath:mapper/*.xml"/></bean><!-- MyBatis Mapper 扫描 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.example.usermanagement.dao"/></bean>
</beans>

9. Servlet 配置

web.xml 中配置 Servlet 和 Spring 上下文:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="3.1"><display-name>User Management</display-name><!-- Spring 上下文 --><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring-config.xml</param-value></context-param><!-- Spring 监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- Spring MVC DispatcherServlet --><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/api/*</url-pattern></servlet-mapping><!-- 跨域支持 --><filter><filter-name>corsFilter</filter-name><filter-class>org.apache.catalina.filters.CorsFilter</filter-class><init-param><param-name>cors.allowed.origins</param-name><param-value>*</param-value></init-param><init-param><param-name>cors.allowed.methods</param-name><param-value>GET,POST,PUT,DELETE,OPTIONS</param-value></init-param><init-param><param-name>cors.allowed.headers</param-name><param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value></init-param></filter><filter-mapping><filter-name>corsFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>

10. 部署到 Tomcat

  1. 将后端项目打包成 WAR 文件。
  2. 将 WAR 文件部署到 Tomcat 的 webapps 目录。
  3. 启动 Tomcat,访问项目。

总结

通过以上步骤,我们实现了一个基于 Vue 和 SSM 框架的前后端分离项目,完成了用户登录和注册功能。前端使用 Vue.js 构建了友好的用户界面,后端使用 SSM 框架提供了稳定的数据服务,并通过 Tomcat 进行部署。这种架构清晰、易于维护,适合现代 Web 开发的需求。

在实际开发中,还可以进一步优化,例如添加用户角色管理、密码加密、验证码等功能,以提高系统的安全性和用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/896862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows安装nvm【超详细图解】

目录 前言 一、NVM下载 方式一&#xff1a;官网下载 方式二&#xff1a;GitHub 下载 二、NVM安装 镜像源配置 三、Node安装 四、环境变量配置 前言 NVM&#xff08;Node Version Manager&#xff09;是一个命令行工具&#xff0c;用于在一台计算机上轻松管理和切换多…

KVM虚拟机磁盘创建探究-2

使用 virt-install 命令自动创建磁盘镜像和使用 qemu-img 手动创建磁盘镜像&#xff0c;在磁盘镜像本身格式和基本功能上是一致的&#xff0c;但在一些特性如初始占用磁盘空间、创建时的可配置性等方面存在区别&#xff0c;下面以 QCOW2 格式磁盘镜像为例进行详细说明。 初始占…

京准电钟:NTP校时服务器于安防监控系统应用方案

京准电钟&#xff1a;NTP校时服务器于安防监控系统应用方案 京准电钟&#xff1a;NTP校时服务器于安防监控系统应用方案 NTP校时服务器在安防监控系统中的应用方案主要通过高精度时间同步技术&#xff0c;解决设备间时间差异问题&#xff0c;确保日志、录像等数据的时间一致性…

递归遍历目录 和 普通文件的复制 [Java EE]

递归遍历目录 首先 先列出当前目录所包含的内容 File[] files currentDir.listFiles();if (files null || files.length 0) {// 若是空目录或非法目录, 则直接返回return;} 然后 遍历列出的文件, 分情况两种讨论 for (File f: files) {// 加个日志, 方便查看程序执行情…

NO.19十六届蓝桥杯模拟赛第三期上

1 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问&#xff0c; 2024 的最大的质因数是多少&#xff1f; 答&#xff1a;23 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false)…

Linux网络_应用层自定义协议与序列化_守护进程

一.协议 协议是一种 "约定". socket api 的接口, 在读写数据时, 都是按 "字符串" 的方式来发送接 收的. 如果我们要传输一些 "结构化的数据" 怎么办呢? 其实&#xff0c;协议就是双方约定好的结构化的数据 像下面&#xff0c;两端都知道数据结构…

SQL命令详解之多表查询(连接查询)

目录 1 简介 2 内连接查询 2.1 内连接语法 2.2 内连接练习 3 外连接查询 3.1 外连接语法 3.2 外连接练习 4 总结 1 简介 连接的本质就是把各个表中的记录都取出来依次匹配的组合加入结果集并返回给用户。我们把 t1 和 t2 两个表连接起来的过程如下图所示&#xff1a; …

001-码云操作

码云操作 一、配置公钥1.官网地址1.进入 git bash2.查看生成的公钥3.设置到 Gitee4.测试 二、初始化一个项目1.新建仓库 一、配置公钥 方便后续提交代码不用填写密码 1.官网地址 官网地址&#xff1a;https://gitee.com/Git码云教程&#xff1a;https://gitee.com/help/arti…

30.[前端开发-JavaScript基础]Day07-数组Array-高阶函数-日期Date-DOM

JavaScript的DOM操作 &#xff08;一&#xff09; 1 什么是DOM&#xff1f; 认识DOM和BOM 深入理解DOM 2 认识DOM Tree DOM Tree的理解 3 DOM的整体结构 DOM的学习顺序 DOM的继承关系图 document对象 4 节点、元素导航 节点&#xff08;Node&#xff09;之间的导航&…

【自学笔记】Spring基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Spring 基础知识点总览1. Spring 框架简介2. IoC&#xff08;控制反转&#xff09;与 DI&#xff08;依赖注入&#xff09;2.1 IoC 容器2.2 依赖注入方式示例代码&a…

WordPress多语言插件GTranslate

GTranslate是一个免费的WordPress多语言插件&#xff0c;它允许您将网站内容翻译成多种语言。这个插件提供了一个简单易用的界面&#xff0c;让您可以在WordPress后台直接进行翻译操作。以下是GTranslate插件的一些主要特点&#xff1a; 免费使用&#xff1a;GTranslate插件完…

数列极限入门习题

数列极限入门习题 lim ⁡ n → ∞ ( 1 1 2 1 3 ⋯ 1 n ) 1 n \lim\limits_{n\rightarrow\infty}(1 \frac{1}{2}\frac{1}{3}\cdots\frac{1}{n})^{\frac{1}{n}} n→∞lim​(121​31​⋯n1​)n1​ lim ⁡ n → ∞ ( 1 n 1 1 n 2 ⋯ 1 n n ) \lim\limits_{n\rightarrow\…

嵌入式学习前要了解的基础知识

一、电压和电流 在嵌入式开发中&#xff0c;电压和电流是两个基本的电气概念&#xff0c;对于理解和设计电子电路至关重要。它们直接影响到嵌入式系统的性能、功耗、可靠性和安全性。 电压&#xff08;Voltage&#xff09; 电压是电场力推动电荷移动的能力&#xff0c;通常以…

机器学习:强化学习的epsilon贪心算法

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是一种机器学习方法&#xff0c;旨在通过与环境交互&#xff0c;使智能体&#xff08;Agent&#xff09;学习如何采取最优行动&#xff0c;以最大化某种累积奖励。它与监督学习和无监督学习不同&#xff0c;强调试错…

Spring学习笔记03——Spring Boot的文件结构

Spring boot常见的文件结构&#xff1a; src/ ├── main/ │ ├── java/ │ │ └── com.example.demo/ │ │ ├── DemoApplication.java # 主入口 │ │ ├── config/ # 配置类 │ │ ├── controller/ …

谈谈 HTTPS 的工作原理,SSL / TLS 握手流程是什么?

一、HTTPS 核心机制&#xff1a;非对称加密 对称加密 HTTPS HTTP over TLS/SSL&#xff0c;通过 ​混合加密体系​ 解决三大问题&#xff1a; ​防窃听​ - 对称加密传输内容&#xff08;如 AES&#xff09;​防篡改​ - 数字签名验证数据完整性​防冒充​ - 数字证书验证服…

共轭梯度法笔记

一、梯度下降法 x k 1 x k − α ∇ f ( x k ) x_{k1} x_k - \alpha \nabla f(x_k) xk1​xk​−α∇f(xk​) 这是普通的梯度下降公式&#xff0c;有两个量是关键&#xff0c;步长 α \alpha α和方向 ∇ f ( x k ) \nabla f(x_k) ∇f(xk​)。这里的方向直接选择了梯度方向&…

ubuntu 启动不起来,光标闪烁 解决方法

ubuntu 启动不起来&#xff0c;光标闪烁 进不了系统&#xff0c;解决方法 按ctrl alt f2&#xff0c;进入终端&#xff0c;登录。 jounal -b 查看启动日志。 发现是找不到显卡驱动程序。 解决方法&#xff1a; 卸载nvidia程序。 sudo systemctl stop gdm # 适用于GNOME…

CSS - 妙用Sass

官方文档&#xff1a;https://www.sass.hk/docs/ 1.例1&#xff1a; each $theme in $themeList {$themeKey: map-get($theme, key);media screen and (weex-theme: $themeKey) {.btnText {max-width: 150px;include font(map-get($theme, medFont),map-get($theme, subFontS…

chromadb向量数据库使用 (2)

目录 代码代码解释**1. 导入 chatGLM 嵌入函数****2. 创建 ChromaDB 客户端和集合****3. 查询集合中的数据数量****4. 添加数据到集合****5. 获取已存储的文档****6. 更新文档****7. 再次获取数据&#xff0c;验证更新结果****8. 删除某个文档****9. 获取已删除的文档****总结*…