手把手教你用 Spring Boot 从零开发「手迹」应用:完整前后端配置指南


后端不背锅
原创
发布时间: 2026-03-22 21:25:39 | 阅读数 0收藏数 0评论数 0
封面
本教程将带你从零开始,一步步搭建一个完整的 JWT 登录系统。不需要你有 Spring Security 基础,我们会从最基本的配置开始,逐步深入到 JWT 认证原理。每章都有完整的代码和详细的注释,跟着做就能跑起来。
1

项目介绍

现在的项目是一个基于 Maven 的多模块工程,整体结构是这样的:

  1. handwriting-blog:这是整个项目的父工程,用来统一管理各个子模块的依赖和配置。
  2. handwriting-common:公共模块,放一些工具类、常量、通用响应封装这些大家都会用到的东西。
  3. handwriting-domain:实体类模块,主要定义数据库对应的实体(Entity)。
  4. handwriting-security:安全核心模块,负责权限控制、认证逻辑等和安全相关的内容。
  5. handwriting-user:用户模块,处理用户相关的业务逻辑,比如注册、登录、信息管理等。
  6. handwriting-auth:验证码模块,专门处理图形验证码、短信验证码之类的验证功能。
  7. handwriting-web:Web 入口模块,也就是整个应用的启动入口,包含 Controller 层和对外暴露的接口。

接下来我会一个一个模块地给你讲解怎么创建、怎么组织代码,以及每个模块里该放些什么内容。

2

创建项目

选择左上角的文件->新建->项目,进入到新建项目部分,输入项目名称以及安装位置。这块就使用maven创建,JDK版本使用的17,可以更换其他的版本,最后点击创建按钮。

创建完成之后选中 src删除,其他内容保留。

把这段内容放到"pom.xml"文件中,粘贴之后点击右上角的刷新按钮。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.handwriting</groupId>
<artifactId>handwriting-blog</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>3.4.2</spring-boot.version>
<spring-web.version>3.4.2</spring-web.version>
<spring-test.version>3.4.2</spring-test.version>
<spring-security.version>3.4.2</spring-security.version>
<mp.version>3.5.7</mp.version>
<mysql.version>8.0.31</mysql.version>
<lombok.version>1.18.42</lombok.version>
<email.version>3.4.2</email.version>
<redis.version>3.4.2</redis.version>
<log4j.version>1.2.12</log4j.version>
<jjwt-api.version>0.12.3</jjwt-api.version>
<jjwt-impl.version>0.12.3</jjwt-impl.version>
<jjwt-jackjson.version>0.12.3</jjwt-jackjson.version>
</properties>

<dependencyManagement>
<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-web.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring-security.version}</version>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>3.4.2</version>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mp.version}</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>

<dependency>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-domain</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-user</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>${email.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${redis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-test.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt-api.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt-impl.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt-jackjson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>


</project>

目前父工程已创建完成。

3

创建子模块

在右上角找到设置->项目结构,找到项目设置下的模块,点击"+"添加新建模块,其中有两个地方需要注意,名称是当前子模块的名称,父项就是选择我们刚刚创建的模块,然后创建完成。进入到项目设置页面,点击右下角的应用,在选中确定完成子项的创建。

4

handwriting-common公共模块

只保留图中的文件目录,其他的删除。找到当前项目的pom.xml文件。把一下内容添加。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-blog</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>handwriting-common</artifactId>
<description>公共模块 - 工具类、枚举、统一响应</description>

<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Spring Boot Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>

<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
</dependencies>
</project>

handwriting-common 模块是项目的公共工具库,主要包含以下内容:

  1. config
  2. mp # MyBatis 配置相关
  3. CustomMetaObjectHandler.java # 自定义元对象处理器,实现字段自动填充
  4. redis # Redis 相关配置
  5. RedisConfig.java # Redis 配置类
  6. WebMvcConfig.java # Spring MVC 配置(如跨域、静态资源)
  7. enums
  8. EmailTemplateEnum.java # 邮件模板枚举
  9. ResultCode.java # 接口返回状态码枚举
  10. exception
  11. GlobalExceptionHandler.java # 全局异常处理器,统一返回格式
  12. result
  13. R.java # 统一响应结果类(类似 ResponseEntity)
  14. utils
  15. CaptchaUtils.java # 验证码生成工具
  16. RedisUtils.java # Redis 操作封装工具
ZIP
handwriting-common.zip
37.75KB
5

handwriting-domain实体类

继续创建子模块,模块名称“handwriting=domain”,以下内容添加到pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-blog</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>handwriting-domain</artifactId>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-common</artifactId>
</dependency>
</dependencies>
</project>

handwriting-domain模块是项目的实体类,主要包含以下内容:

  1. domain
  2. base #基类
  3. BaseEntity # 通用字段
  4. user # user目录
  5. user # 用户信息
  6. dto 用于接受前端返回的信息


6

security配置

创建子模块,模块名称“handwriting-security”,并把内容添加到pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-blog</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>handwriting-security</artifactId>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>


<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-domain</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
</dependency>
</dependencies>

</project>

handwriting-security 模块说明

这个模块是整个项目的安全核心模块,主要负责用户认证、权限控制和 JWT相关逻辑。它不直接处理业务,而是为其他模块提供安全支持。

  1. config/ —— 配置类
  2. JwtConfig.java
  3. JWT 的配置类,定义了 token 的过期时间、签名密钥、加密算法等参数。
  4. SecurityConfig.java
  5. Spring Security 的核心配置类,用来设置哪些接口需要认证、哪些不需要,以及如何进行身份验证和授权。
  6. domain/ —— 实体领域类
  7. MyUserDetails.java
  8. 自定义的用户详情类,实现了 UserDetails 接口,用于封装用户信息(如用户名、密码、角色等),供 Spring Security 使用。
  9. filter/ —— 过滤器
  10. AuthenticationTokenFilter.java
  11. 自定义的过滤器,拦截请求,解析请求头中的 JWT Token,并验证其有效性。如果验证通过,就把用户信息放入上下文中,后续流程就能获取用户身份。
  12. util/ —— 工具类
  13. JwtUtils.java
  14. JWT 工具类,封装了生成 token、解析 token、验证 token 等常用方法,方便在其他地方调用。


7

web模块

创建子模块,模块名称“handwriting-web”,并把内容添加到pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-blog</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<packaging>jar</packaging>
<artifactId>handwriting-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>handwriting-web</name>
<description>handwriting-web</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>

<!-- 用户模块 -->
<dependency>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-user</artifactId>
</dependency>

<!-- 认证模块(验证码) -->
<dependency>
<groupId>com.handwriting</groupId>
<artifactId>handwriting-code</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>

<!-- MySQL -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>

<!-- JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</build>

</project>

handwriting-web 模块说明

这是整个项目的 Web 入口模块,也是 Spring Boot 应用的启动入口。它负责对外暴露接口,接收前端请求,并协调其他模块完成业务处理。

  1. controller
  2. auth
  3. CaptchaController ##验证码控制器
  4. user
  5. LoginController ##登录、注册控制器
  6. handwritingWebAppliction.java 启动类
  7. 这是整个应用的主类,带有 @SpringBootApplication 注解,用来启动 Spring Boot 服务。它会自动扫描并加载所有子模块中的组件(如配置、Service、Controller 等)。是整个项目运行的起点。

resources —— 资源文件

  1. application.yml
  2. 主配置文件,定义了数据库连接、服务器端口、Redis 配置等全局参数。
  3. application-dev.yaml
  4. 开发环境专用配置文件,通常用于区分不同环境(开发、测试、生产),比如开发时用本地数据库,生产用远程数据库。
8

配置文件

// appliction.yml
server:
port: 8080
servlet:
context-path: /api

spring:
profiles:
active: dev # 激活开发环境

mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:mapper/**/*.xml

# JWT 配置
jwt:
# 秘钥(生产环境请使用环境变量)
secret-key: Uz1ABUDk7uIu3sRKiER6zGfVkRGY1NZED4p47gOpJwx9Tr7cwpJzxgN18MLmFvRpfg0wVvk6CfQyA7UU3XbNBlBSlv5TVVle2vpIvh4zJqGXAxcF2unCu6wCEvZxGuwv2FRC9g5Fn8iQQLG2dYCdvtt2dPx6ozArIjUcmLMCaZO2n4EOdAtkGvqwyScgwt583IF3yefbT8Gy813qUhHzmrMlL8nMGXMxL8RGhJfcEsEsW7ckgchVyPgVQWF1JSue
# Access Token 过期时间(1 小时)
access-token-expiration: 3600000
# Refresh Token 过期时间(7 天)
refresh-token-expiration: 604800000
# Token 前缀
token-prefix: "Bearer "
# Token 请求头名称
token-header: Authorization


// appliction-dev.yaml
spring:
# 数据源配置(用于连接 MySQL 数据库)
datasource:
# 数据库用户名
username: root
# 数据库密码
password: 1234
# JDBC 驱动类名(
driver-class-name: com.mysql.cj.jdbc.Driver
# 数据库连接 URL
# hand-writing 是数据库名;useUnicode 和 characterEncoding 确保使用 UTF-8 编码;
# useSSL=false 表示不使用 SSL 连接(开发环境常用);
# allowMultiQueries=true 允许一次执行多条 SQL 语句;
# allowPublicKeyRetrieval=true 允许从服务器获取公钥(解决某些认证问题)
url: jdbc:mysql://localhost:3306/hand-writing?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true

# 邮件服务配置(使用 QQ 邮箱 SMTP)
mail:
# SMTP 服务器地址(QQ 邮箱)
host: smtp.qq.com
# 使用的协议
protocol: smtp
# 发件人邮箱账号(需开启 SMTP 服务)
username: 2623481720@qq.com
# SMTP 授权码(不是邮箱登录密码!此处为 QQ 邮箱生成的授权码)
password: mjoywqcwezxudihi
# 默认邮件编码
default-encoding: utf-8
# SMTP 服务器端口(465 用于 SSL 加密)
port: 465
# 启用 SSL 加密传输(QQ 邮箱要求)
ssl:
enabled: true

# Redis 配置
data:
redis:
# Redis 服务器地址(本地)
host: 127.0.0.1
# Redis 端口号(默认 6379)
port: 6379
# 使用的数据库编号(Redis 默认有 0~15 号数据库)
database: 0
# Redis 密码(若未设置密码可删除此行或留空)
password: 123456



ZIP
handwriting.zip
344.51KB
9

数据库创建

打开 Navicat 工具,点击“连接”,选择数据库类型为 MySQL。接着填写连接名称,并输入你的数据库账号和密码,完成连接配置。

创建好连接后,右键点击该连接,选择“新建数据库”。在弹出的窗口中,输入你想要的数据库名称,并将字符集设置为 utf8mb4,然后确认创建即可。

10

创建前端项目

打开WebStorm开发工具新建项目,选择vite分类新建项目。

  1. 位置:项目的创建位置
  2. 解释器:使用node创建,我目前的版本使用的22.18.0
  3. vite:vite创建指令
  4. 模版:使用vue模版创建项目
  5. 最后勾选“使用ts模版创建”
  6. 点击创建按钮
  7. 会进入终端:Instakk with npm and start now?选择"No"
  8. 选择终端选项卡,输入pnpm i 安装相关依赖
  9. 补充依赖: pnpm i vue-router@4 pinia element-plus axios 在终端安装这个依赖。
11

封装axios

在src目录下新目录utils,新建文件reuest.ts。

import axios from "axios";
import {delToken, getToken} from "@/utils/auth.ts";
import {ElMessage} from "element-plus";
import router from "@/router";

const baseURL = import.meta.env.VITE_API_BASE_URL;
export const request = axios.create({
baseURL,
// 请求过期时间 超过时间则失败
timeout: 10000
});
// 处理每一个请求
request.interceptors.request.use(config => {
// 放入token 用于后端接口校验
if (getToken() != null) {
config.headers.Authorization = `${getToken()}`;
}
return config;
}, error => {
Promise.reject(error)
})

// 处理请求响应的内容
request.interceptors.response.use(response => {
return response;
}, async (error) => {
const {response} = error;
// 默认错误消息
let message = "请求失败,请稍后重试";

if (response) {
const {status} = response;
switch (status) {
case 400:
message = "请求参数错误";
break;
case 401:
// 未授权:清除 token 并跳转登录
delToken(); // 或你使用的存储方式
router.push("/login");
message = "登录已过期,请重新登录";
break;
case 403:
router.push("/login");
message = "权限不足,请重新登录";
break;
case 404:
message = "请求资源不存在";
break;
case 500:
message = "服务器内部错误";
break;
default:
message = `请求失败 (${status})`;
}
} else if (error.request) {
// 请求已发出但无响应(如网络中断、超时)
message = "网络连接异常,请检查网络";
}

// 统一弹出错误提示
ElMessage.error(message);
throw error;
})


12

路由守卫

在src下新建目录router

import {createRouter, createWebHistory} from "vue-router";
import {getToken} from "@/utils/auth.ts";


const routes = [
{path: '/', component: () => import("@/view/home/index.vue")},
{path: '/login', component: () => import("@/view/login/index.vue")},
{path: '/register', component: () => import("@/view/register/index.vue")},
{path: '/forgetPassword', component: () => import("@/view/forgetPassword/index.vue")},
{
path: '/:pathMatch(.*)*',
name: '404',
component: () => import("@/view/404/index.vue"),
meta: {title: '404'}
}

]


const router = createRouter({
history: createWebHistory(),
routes
});


// 白名单
const whiteList = ['register', 'login', 'forgetPassword', '/']

router.beforeEach((to, from, next) => {

// 用户已登录
if (getToken() != null && to.path === '/login' || from) {
// 调整到首页
next({path: '/'})
return
}

// 白名单直接放行
if (whiteList.includes(to.path)) {
next()
return
}

// 放行
next()

})

export default router;


13

自定义组件

component->custom 这目录下封装了一些常用的组件,这些组件我会放入到附件中。

ZIP
custom-component.zip
7.31KB
14

登录页面

<script setup lang="ts">
import CustomFromItem from "@components/custom/CustomFromItem.vue";
import CustomInput from "@components/custom/CustomInput.vue";
import CustomFrom from "@components/custom/CustomFrom.vue";
import {reactive, ref} from "vue";
import {InputValidator} from "@/types/interface/validators/InputValidator.ts";
import {getUserExist} from "@/api/user/user.ts";
import CustomButton from "@/components/custom/CustomFromBtn.vue";
import RegisterFooter from "@/view/register/components/RegisterFooter.vue";
import {useUserStore} from "@/store/user.ts";
import {useRouter} from "vue-router";
import type {LoginInfo} from "@/types/interface/login.ts";

// 表单输入校验
const rules = {
username: [
{required: true, message: "请输入邮箱", trigger: "blur"},
{pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: '邮箱格式不正确', trigger: "blur"},
{
validator: async (value: string) => {
return getUserExist(value).then(res => {
return res.data.code != 200 ? '' : "邮箱未注册"
})
}
}
],
password: [
{required: true, message: "请输入至少六位数的密码", trigger: "blur"},
{min: 6, message: '请输入至少六位的密码', trigger: "blur"}
],
}

const loginInfoForm = ref<InputValidator | null>(null)

const loginInfo = reactive<LoginInfo>({
username: '',
password: ''
})
const userStore = useUserStore();
const router = useRouter();
// 登录
const handlerLogin = () => {
// 登录
userStore.login(loginInfo).then(res => {
if (res) {
// 跳转到首页
router.push("/")
}
})
}


</script>

<template>
<div class="login-wrapper">
<div class="login-header-box">
<p class="login-title">欢迎回来</p>
<p class="login-des">登录手迹,继续你的创作之旅</p>
</div>
<custom-from :validator="true" :rules="rules" ref="loginInfoForm">
<custom-from-item label="邮箱地址">
<custom-input placeholder="请输入邮箱" name="email" type="email" icon="src/assets/img/login/email.svg"
v-model:input-value="loginInfo.username"/>
</custom-from-item>
<custom-from-item label="密码">
<custom-input placeholder="至少输入6位" name="password" type="password"
icon="src/assets/img/login/password.svg" v-model:input-value="loginInfo.password"/>
</custom-from-item>
<p class="forget-pass-title">
<router-link class="forget-pass-a" to="/forgetPassword">忘记密码?
</router-link>
</p>
<custom-button label="登录" @click="handlerLogin"/>
</custom-from>
<register-footer title="还没有账户?" router-label="立即注册→" index-link="/register"/>
</div>

</template>

<style scoped lang="scss">
//注册容器
.login-wrapper {
margin: 0;
border-radius: 24px;
border: 1px solid rgb(243, 244, 246);
padding: 48px;
background-color: #ffffff;
box-shadow: rgba(0, 0, 0, 0) 0 0 0 0, rgba(0, 0, 0, 0) 0 0 0 0, rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px;
width: 400px;
}

// 忘记密码
.forget-pass-title {
text-align: right;
margin: 0
}

// 忘记密码A标签
.forget-pass-a {
font-size: 14px;
color: #4f39f6;
}

// 创建头部容器
.login-header-box {
margin-bottom: 32px
}

// 标题
.login-title {
font-size: 36px;
font-weight: 700;
line-height: 36px;
color: #9810fa;
margin-bottom: 16px;
}

// 描述
.login-des {
font-weight: 400;
font-size: 16px;
line-height: 24px;
color: #4a5565;
}

// 发送验证码按钮
.send-code {
width: 100%;
padding: 12px 0;
line-height: 24px;
font-size: 16px;
color: rgb(156, 163, 175);
background-color: #E5E7EB;
border-radius: 8px;
display: flex;
justify-content: center;
margin-top: 20px;
font-weight: 600;
border: none;
outline: none;
}
</style>


ZIP
handwriting.zip
56.83MB
阅读记录0
点赞0
收藏0
禁止 本文未经作者允许授权,禁止转载
猜你喜欢
评论/提问(已发布 0 条)
评论 评论
收藏 收藏
分享 分享
pdf下载 下载
pdf下载 举报