Write directory title here
Login page and effect realization:
- Realize the login function
Front-end code:
Create a new Vue project
There are many tutorials on the Internet for creating a new vue project, so I won’t give examples here. If you don’t know, you can use Baidu Kangkang tutorial. Here I use vue scaffolding. On the cmd command line, first switch the path you want to create a new project (cd xx disk), and then enter the vue ui command. You can view the version of vue through the vue -V command! (You must use vue3.0 version to use the graphical page, otherwise an error will be reported)。
- New Project
- Then set the project name, according to your own needs to develop
- Click on manual configuration
- Check the four components of Babel , Router , CSS , and use configuration files .
- After creating a new project, download dependencies and plugin
project directories
- Open the newly created project through vscode, the project directory is as follows Change the following configuration in the
APP.vue file
<template>
<div id="app">
<router-view></router-view>
<!-- 进行页面的渲染 -->
</div>
</template>
<script>
</script>
<style>
</style>
Configure routing in the router.js file
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from "../views/login/index" //引入Login的组件
`const routes = [
{
path: "/",
redirect: "/login",//重定向到登录页面
},
{
path: "/login",
component: Login,
hiddren: true,
name: 'login'
},
const router = new VueRouter({
routes
})
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) {
if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
return originalPush.call(this, location).catch(err => err)
}
export default router//暴露出去
- Import the required dependencies on demand in the main.js file to reduce the resources of the project (the import method is as follows)
//仅仅是举例子,真正情况按照自己的项目需要的项目导入。
import {
Pagination,
Dialog,
} from 'element-ui';
Vue.use(Pagination)
Vue.use(Dialog)
- Mount an axios instance
Create a new util folder, create a new request.js, and create an axios instance
import axios from 'axios'//导入axios组件
// 对axios的全局配置
// 全局请求拦截器配置
// axios.interceptors.request.use(
// config => {
// return config
// }
// )
// 创建axios实例
const service = axios.create(
{
// baseURL:'/api', // 域名地址,需要加request url
// baseURL: '/api',
baseURL:"http://localhost:9000",
timeout: 5000 // 默认超时5秒
}
)
// 请求拦截器,只跟用service实例发起请求的请求有关
service.interceptors.request.use(
config => {
// 对需要token的api进行调用
// config.headers['Access-Control-Allow-Origin'] = '*'
// config.headers['X-Token']
let accessToken = sessionStorage.getItem("token");
//console.log(accessToken)
config.headers['token'] = accessToken;
return config;
},
error => {
console.log(error)
return Promise.reject(error)
}
)
// service的响应拦截器
service.interceptors.response.use(
response => {
// 在需要的时候,可以直接把data值放进res
const res = response.data
// 判断返回的code 200
// if(res.code !== 200) {
// console.log('error')
// 判断检查是否登陆,是否有toke
// 返回出错误状态
// return Promise.reject('error')
// }else{
// return res
// }
return res
},
error => {
console.log('err')
return Promise.reject(error)
}
)
export default service
- Create a new api folder for requests to interact with the backend port. Then create a new
import request from '../../util/request.js'
//登录方法实现
export function login(params) {
return request({
url: '/auth/user/login',//http://127.0.0.1:9000/api/auth/login
method: 'post',
params
})
}
//注销方法实现
export function logout() {
return request({
url: '/auth/user/logout',//http://127.0.0.1:9000/api/auth/login
method: 'get'
})
}
- Create a new login folder and create a new index.vue file
- Page Layout
<template>
<!-- 主体布局 -->
<div class="login_container">
<!-- 登录区域 -->
<div class="login_box">
<!-- 头像区域 -->
<div class="avatar_box">
<img src="../../assets/images/管理.png" alt="" />
</div>
<!-- 登录区域,绑定form表单的模型为LoginForm,rules是指验证的规则,名字自定义 -->
<el-form
:model="LoginForm"
:rules="LoginForm_Rule"
ref="LoginFormRef"
label-width="0px"
class="login_form"
>
<!--用户名 v-model:双向绑定 -->
<el-form-item prop="username">
<el-input v-model="LoginForm.username" prefix-icon="el-icon-user">
</el-input
><!-- 设置模型为表单下的username属性, prefix-icon:设置前缀的头像-->
</el-form-item>
<!-- 登录密码 type指的是将类型设置为password -->
<el-form-item prop="password">
<el-input
type="password"
v-model="LoginForm.password"
prefix-icon="el-icon-lock"
>
</el-input
><!-- 设置模型为表单下的password属性, prefix-icon:设置前缀的头像-->
</el-form-item>
<!-- 为btn嵌套一个div样式,使按钮控件向中对齐 -->
<div class="btn">
<!-- 登录按钮 -->
<el-form-item class="btns">
<el-button type="primary" @click="submitForm">登录</el-button>
<el-button type="info" @click="resetLoginForm">重置</el-button>
<!-- <el-button :plain="true" type="primary" @click="login('LoginForm')"
>登录</el-button
> 为改动之前-->
<!-- <el-button type="info" @click="resetLoginForm('LoginForm')"
>重置</el-button
> -->
</el-form-item>
</div>
</el-form>
</div>
<div class="login-footer">
<span>Copyright © 2021-05-10 kk楷楷 All Rights Reserved.</span>
</div>
</div>
</template>
- css style (the pictures used here can be found online)
<!--lang需要将L设置为大写,否则会出错-->
<style Lang="less" scoped>
/* 设置主布局 */
.login_container {
background: url("../../assets/images/login-backgroud.jpg"); /* 引入图片资源 */
background-repeat: no-repeat; /* 设置图片不重复 */
background-size: 100% 100%;
width: 100%;
position: fixed; /* 充满全屏 */
height: 100%;
}
/* 设置登录盒子布局 */
.login_box {
/* 盒子居中的方法:①margin:0 auto ②弹性布局 ③相对布局 ④transform */
width: 450px;
height: 300px;
background-color: white; /* 设置背景颜色为白色 */
border-radius: 5px; /* 设置盒子的边框为圆形 */
position: absolute; /* 位置设置为绝对定位,进行位移 */
left: 50%; /* 向左占百分之50 */
top: 50%; /* 向右占百分之50 */
transform: translate(-50%, -50%); /* 横轴移动,中轴移动 */
}
/* 设置头像区域样式 */
.avatar_box {
height: 130px;
width: 130px;
border: 1px solid #eee; /* 设置盒子的边框 */
border-radius: 50%; /* 将盒子边框圆形弧度 */
padding: 10px; /* 设置上下左右内边距为10px */
box-shadow: 0 0 10px #ddd; /* 设置盒子的阴影,css3新增属性 */
position: absolute; /* 设置盒子布局为绝对定位 */
left: 50%; /* 向左移动自己宽度的50% */
transform: translate(-50%, -50%); /* 后面的50%是按照高度来进行集散的 */
background-color: #fff;
}
/* 设置图片样式 */
img {
width: 100%; /* 设置图片和主布局大小一致 */
height: 100%;
border-radius: 50%; /* 设置圆角弧度 */
background-color: #eee;
}
.login_form {
position: absolute;
bottom: 0px;
width: 100%;
padding: 0px 20px; /* 两个参数代表:第一个0代表上下,第二个元素代表左右 */
box-sizing: border-box; /*盒子溢出处理,不使用该配置的话,盒子会向右突出 */
/* border-box:以边界为界限调整边距,content-box以内容为边界表调整 */
}
.btns {
display: flex; /* 弹性布局 */
justify-content: flex-end;
}
.btn {
text-align: center;
float: left;
padding-left: 130px;
}
/* 设置底部样式 */
.login-footer {
position: fixed;
bottom: 0px;
height: 50px;
width: 100%;
text-align: center;
color: #fff;
}
</style>
- Enter the npm run build command on the command line
- Effect realization (input localhost:8080 in the browser)
Backend code implementation:
Entity class (1.User)
用户实体类,使用以下注解需要下载Lombok插件以及在pom文件中引入依赖!
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;//角色id
private String username;//用户名
private String password;//用户密码
private String email;//用户邮箱
private String role;//用户角色
private Boolean state;//用户状态,判断是否能够进入后台
}
Entity class (2.Token)
/**
* 用户凭证
*/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Token {
/**
* 键
*/
private String tokenKey;
/**
* 有效期 2小时-7200s
*/
private Long expire;
/**
* 创建时间
*/
private Date createDate;
}
Tool class (3.ResultUtil)
/**
* 结果工具类
*/
public class ResultUtil {
public static ObjectResult okObjectResult(Object data){
ObjectResult result=new ObjectResult();
result.setCode(200);
result.setMsg("ok");
result.setSuccess("success");
result.setResultType("object");
result.setData(data);
return result;
}
public static ObjectResult failObjectResult(String message){
ObjectResult result=new ObjectResult();
result.setCode(200);
result.setMsg(message);
result.setSuccess("fail");
result.setResultType("object");
return result;
}
Control layer (AuthController)
@RestController
@RequestMapping(value = "/auth/user")//前端请求的路径
public class AuthController {
@Resource
private UserService userService;
@Resource
private RedisManager redisManager;
@RequestMapping(value = "/login")
public ObjectResult<Token> login(@RequestParam(value = "username") String username,
@RequestParam(value = "password") String password){
//调用userService来完成登录的业务功能
Token token = userService.login(username, password);
if (token!=null){
return ResultUtil.okObjectResult(token);
}
return ResultUtil.failObjectResult("用户或密码不正确!!!");
}
service layer (UserService)
public interface UserService {
/**
* 登录
* @param username
* @param password
* @return
*/
Token login(String username, String password);
Service implementation class (UserServiceImpl)
@Override
public Token login(String username, String password) {
//调用dao,查数据库
User user = userMapper.login(username);
if (user!=null && user.getPassword().equals(password)){
//用户名和密码是正确
//生成
Token token = tokenService.generateToken(user);
//保存redis
tokenService.saveToken(token,user);
return token;
}
return null;
}
Dao layer (UserMapper)
/**
*
*
* 用户dao
*/
public interface UserMapper {
/**
* 用户登录
* 使用用户名查数据,速度
* @param username 用户名
* @return 用户
*/
User login(@Param("username") String username);
Mapper file:
<mapper namespace="com.kk.system.dao.UserMapper">
<select id="login" resultType="User">
select * from sys_user where username=#{
username}
</select>
</mapper>