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

发布于:2025-03-04 ⋅ 阅读:(103) ⋅ 点赞:(0)

前言

在现代 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('登录成功');
                // 保存 token
                localStorage.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 mapper
  PUBLIC "-//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 {

    @Autowired
    private UserDao userDao;

    @Override
    public boolean register(User user) {
        return userDao.registerUser(user) > 0;
    }

    @Override
    public 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 {

    @Autowired
    private 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.Driver

mybatis.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/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc
           http://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 开发的需求。

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


网站公告

今日签到

点亮在社区的每一天
去签到