资源学习教程博客
1.后端和数据库详细使用教程
2.前端详细教程
1.使用的软件
1.2 后端 IDEA;前端WebStrom;数据库 MySQL
2.过程要点
2.1 数据库
(1)在cmd面板里,启动,打开数据库
所使用的命令:
net start mysql //启动
mysql -u root -p // 打开
(2)新建,进入数据库 demo
create database demo
use demo
(3)创建用户信息数据表
CREATE TABLE user
(
uid int(10) primary key NOT NULL AUTO_INCREMENT,
uname varchar(30) NOT NULL,
password varchar(255) NOT NULL,
UNIQUE (uname)
);
(4)配置数据库
打开IDEA项目,找到src<-main<resources下的application.properties 写入
# 配置端口号
server.port=8081
#数据库驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#其中demo是所建立的数据库名
spring.datasource.url=jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
# Mysql用户
spring.datasource.username=root
# Mysql密码
spring.datasource.password=123456
2.2 后端
(1)创建注意
(2) 项目文件分布
(3)各文件作用及代码
User实体类:连接所用的数据表user,生成相关属性的get和set方法
package com.******.domain;
import javax.persistence.*;
@Table(name = "user") //连接的数据表
@Entity
public class User {
public long getUid() { return uid;}
public void setUid(long uid) { this.uid = uid;}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long uid;
public String getUname() { return uname;}
public void setUname(String uname) { this.uname = uname; }
private String uname;
public String getPassword() { return password;}
public void setPassword(String password) { this.password = password; }
private String password;
}
UserDao接口:通过用户名来访问数据库进行查询
package com.******.repository;
import com.******.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserDao extends JpaRepository<User, Long> {
User findByUname(String uname);
User findByUnameAndPassword(String uname, String password);
}
UserService接口:登录注册业务逻辑,传递参数
package com.******.service;
import com.******.User;
public interface UserService {
User loginService(String uname, String password);
User registService(User user);
}
UserServiceImpl :实现登录注册业务逻辑的方法
package com.******.serviceImpl;
import com.******.User;
import com.******.UserDao;
import com.******.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
@Override
public User loginService(String uname, String password) {
User user = userDao.findByUnameAndPassword(uname, password);
if(user != null){ user.setPassword(""); }
return user;
}
@Override
public User registService(User user) {
if(userDao.findByUname(user.getUname())!=null){
return null;
}else{
User newUser = userDao.save(user);
if(newUser != null){ newUser.setPassword(""); }
return newUser; }
}
}
Result :模板类,很多静态方法可以用类名.方法名调用
package com.******.utils;
public class Result<T> {
private String code;
private String msg;
private T data;
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; }
public T getData() { return data; }
public void setData(T data) { this.data = data; }
public Result() { }
public Result(T data) { this.data = data; }
public static Result success() {
Result result = new Result<>();
result.setCode("0");
result.setMsg("成功");
return result;
}
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>(data);
result.setCode("0");
result.setMsg("成功");
return result;
}
public static <T> Result<T> success(T data,String msg) {
Result<T> result = new Result<>(data);
result.setCode("0");
result.setMsg(msg);
return result;
}
public static Result error(String code, String msg) {
Result result = new Result();
result.setCode(code);
result.setMsg(msg);
return result;
}
}
UserController :实现登录注册的控制,处理post请求方法@RequestMapping(“/user”)是控制器类的基路由
package com.******.controller;
import com.******.User;
import com.******.UserService;
import com.******.Result;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@PostMapping("/login")
public Result<User> loginController(@RequestParam String uname, @RequestParam String password){
User user = userService.loginService(uname, password);
if(user!=null){ return Result.success(user,"登录成功!");
}else{ return Result.error("123","账号或密码错误!"); }
}
@PostMapping("/register")
public Result<User> registController(@RequestBody User newUser){
User user = userService.registService(newUser);
if(user!=null){ return Result.success(user,"注册成功!");
}else{ return Result.error("456","用户名已存在!"); }
}
}
GlobalCorsConfig :全局跨域配置类,处理跨域问题,可有可无看具体运行是否报错,前后端分离
package com.******.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class GlobalCorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
.allowedOrigins("*") //开放哪些ip、端口、域名的访问权限
.allowCredentials(true) //是否允许发送Cookie信息
.allowedMethods("GET", "POST", "PUT", "DELETE") //开放哪些Http方法,允许跨域访问
.allowedHeaders("*") //允许HTTP请求中的携带哪些Header信息
.exposedHeaders("*"); 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
}
};
}
}
2.3 前端
(1)创建配置
config / index.js 中 更改以下部分,其中8081是后端设置好的端口号
proxy: {
'/api': {
target: 'http://localhost:8081',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
},
src / main.js 中 ,添加部分,引用element和axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(ElementUI) // element ui 插件
Vue.use(VueAxios, axios) // 使用 axios 插件
(2)文件目录
(3)Login.vue 登录页面
<template>
<div>
<el-card class="box-card">
<h2>登录</h2>
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-position="left" label-width="70px" class="login-from">
<el-form-item label="用户名" prop="uname">
<el-input v-model="ruleForm.uname"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div class="btnGroup">
<el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
<router-link to="/register">
<el-button style="margin-left: 10px">注册</el-button>
</router-link>
</div>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
ruleForm: {
uname: "",
password: "",
},
rules: {
uname: [
{ required: true, message: "用户名不能为空!", trigger: "blur" },
],
password: [
{ required: true, message: "密码不能为空!", trigger: "blur" },
],
}
};
},
methods: {
submitForm(formName) {
// 验证表单中的账号密码是否有效,因为在上面rules中定义为了必填 required: true
this.$refs[formName].validate((valid) => {
// 如果经过校验,账号密码都不为空,则发送请求到后端登录接口
if (valid) {
let _this = this;
// 使用 axios 将登录信息发送到后端
this.axios({
url: "/user/login", // 请求地址
method: "post", // 请求方法
headers: { // 请求头
"Content-Type": "application/json",
},
params: { // 请求参数
uname: _this.ruleForm.uname,
password: _this.ruleForm.password,
},
})
.then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息
if (res.data.code === "0") { // 当响应的编码为 0 时,说明登录成功
// 将用户信息存储到sessionStorage中
sessionStorage.setItem("userInfo", JSON.stringify(res.data.data));
// 跳转页面到首页
this.$router.push('/home');
}
else { // 当响应的编码不为 0 时,说明登录失败
this.$message({
message: res.data.msg,
type: "warning",
});
}
return false;
});
} else { // 如果账号或密码有一个没填,就直接提示必填,不向后端请求
console.log("error submit!!");
return false;
}
return false;
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
},
};
</script>
<style scoped>
/* 设置登录面板居中,宽度为400px */
.box-card {
margin: auto auto;
width: 400px;
}
/* 设置登录面板中的表单居中 */
.login-from {
margin: auto auto;
}
</style>
(4)Register.vue 注册页面
<template>
<div>
<el-card class="box-card">
<h2>注册</h2>
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm"
label-position="left" label-width="80px" class="demo-ruleForm">
<el-form-item label="用户名" prop="uname">
<el-input v-model="ruleForm.uname"></el-input>
</el-form-item>
<el-form-item label="密码" prop="pass">
<el-input
type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div class="btnGroup">
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
<el-button @click="goBack">返回</el-button>
</div>
</el-card>
</div>
</template>
<script>
export default {
data() {
var validatePass = (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入密码"));
} else {
if (this.ruleForm.checkPass !== "") {
this.$refs.ruleForm.validateField("checkPass");
}
callback();
}
};
var validatePass2 = (rule, value, callback) => {
if (value === "") {
callback(new Error("请再次输入密码"));
} else if (value !== this.ruleForm.pass) {
callback(new Error("两次输入密码不一致!"));
} else {
callback();
}
};
return {
ruleForm: {
uname: "",
pass: "",
password: "",
},
rules: {
uname: [{ required: true, message: "用户名不能为空!", trigger: "blur" }],
pass: [{ required: true, validator: validatePass, trigger: "blur" }],
password: [{ required: true, validator: validatePass2, trigger: "blur" }],
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let _this = this;
this.axios({ // axios 向后端发起请求
url: "/user/register", // 请求地址
method: "post", // 请求方法
headers: { // 请求头
"ContentType": "application/json",
},
data: { // 请求参数,为 data,与登录的 params 不太一样
uname: _this.ruleForm.uname,
password: _this.ruleForm.password,
},
}).then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息
if (res.data.code === '0') { // 当响应的编码为 0 时,说明注册成功
// 显示后端响应的成功信息
this.$message({
message: res.data.msg,
type: "success",
});
}
else{ // 当响应的编码不为 0 时,说明注册失败
// 显示后端响应的失败信息
this.$message({
message: res.data.msg,
type: "warning",
});
}
return false;
});
} else { // 如果账号或密码有一个没填,就直接提示必填,不向后端请求
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
goBack() {
this.$router.go(-1);
},
},
};
</script>
<style scoped>
/* 设置登录面板居中,宽度为400px */
.box-card {
margin: auto auto;
width: 400px;
}
/* 设置登录面板中的表单居中 */
.login-from {
margin: auto auto;
}
</style>
router - index.js 配置路径
import Vue from 'vue'
import Router from 'vue-router'
import Login from '../views/login/Login'
import Register from '../views/register/Register'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/', // 路径
name:'login',
redirect: '/login' // 重定向
component: Login
},
{
path: '/register', // 路径
name:'register',
component: Register // 跳转到的组件
},
{
path: '/home', // 路径
name:'Home',
component: Home // 跳转到的组件
}
]
})
后记碎碎念:
完整的小项目,数据库,后端,前端一起配合完成登录和注册
前前后后经历了一个月多的时间。
作为一个前端学习者,后端还是比较难,完全根据网上的博客和报错查询,做出来
逻辑还是不太清晰,但是其中需要注意的点是比较熟悉了。
继续加油吧!