从模板引擎到前后端分离-Vue
电脑需要先安装Git和Node.js
安装成功后,在系统变量里的path中会有如下的配置
从https://gitee.com网站上创建自己的仓库
Idea中要安装相应的插件
打开Files->Settings->Plugins
找到Vue.js和Gitee两个插件并安装上去
在idea上登录自己的gitee账号,并导入自己的仓库
登录自己的gitee账户
登录成功后,这里就出现你的仓库,然后clone即可
使用git命令来上传项目到Gitee
在仓库目录上点击右键找到Git,如下图所示
第一步:先Add一下
第二步:找到Commit Directory,并点击
第三步:找到Repository下的push,点击push把项目提交上去
提交成功后会显示Push successful
在仓库中创建Vue项目
在Local控制台上进入自己仓库目录下,输入vue ui
进入提示的网址 打开Vue项目管理器
在这个Vue项目管理器中创建Vue项目即可
预设选择手动
不勾选Linter/Formatter选项,勾选Router,Vues和Babel三个选项即可
创建项目,不保存预设
在控制台上输入cd Vue项目名,进入你所创建的Vue项目,安装所需依赖
如果电脑刚安装后Git和Node.js还没有安装vue,需要输入cmd打开电脑控制台,并输入npm install -g @vue/cli
接下来,输入npm install -g cnpm --registry=https://registry.npm.taobao.org命令来安装cnpm
在Idea的Local控制台中进入Vue项目下
安装Element-ui,如果cnpm install element-ui不管用的话,可以试试npm install element-ui
安装node-sass,命令为cnpm install node-sass
安装sass-loader(用于css样式),命令为npm install sass-loader
安装axios(axios封装了ajax,用于发送请求),命令为npm install axios
安装vue-axios,命令为npm install vue-axios
安装mock(用于模拟后端请求),命令为npm install mockjs
启动vue项目命令为npm run serve
前端Vue项目的目录
在assets中新建img,导入自己的背景图片
在assets中新建css,编写自己的公共css样式
style.css
body{
margin: 0;
padding: 0;
}
在src下新建mock文件夹,并在其里新建mock.js
mock.js
import Mock from 'mockjs'
//模拟后端请求
Mock.mock('http://localhost:80/api/user/register',{
"status_":0,//这个状态码是后端人员自己定义的状态码 不是Http协议的状态码
"data":{
"message":"Lain"
}
});
//登录的请求
Mock.mock('http://localhost:80/api/user/login',{
"status_":1,
"data":{
"message":"用户名或者密码错误"
}
});
改变router文件夹下的index.js内部代码
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/login'
import Register from '../views/register'
import Index from '../views/index'
Vue.use(VueRouter);
const routes = [
{
path: '/login',
name: 'Login',
component: Login
},
{
path:'/register',
name:'register',
component:Register
},
{
path:'/index',
name:'index',
component:Index
}
];
const router = new VueRouter({
mode:'history',
routes
});
export default router
在View文件夹下书写登录和注册页面
login.vue
<template>
<div class="bg">
<el-form :model="login_form " :rules="rules" ref="login_form" class="form-class">
<h2>用户登录</h2>
<br/>
<el-form-item prop="username">
<el-input placeholder="用户名" v-model="login_form.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="密码" v-model="login_form.password"></el-input>
</el-form-item>
<br/>
<el-form-item>
<el-button @click="loginButtonClick()" type="primary">登录</el-button>
<el-button @click="toRegister()">注册</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import Router from '../router/index'
import ElementUI from 'element-ui'
export default {
data(){
return{
login_form:{
username:'',
password:''
},
rules:{
username:[
{required:true,message:'请输入用户名',trigger:'blur'}
],
password:[
{required:true,message:'请输入密码',trigger:'blur'},
{min:4,max:8,message:'密码的长度是4到8位',trigger:'blur'}
]
}
}
},
name: "login.vue",
methods:{
//用户登录
loginButtonClick(){
let username = this.login_form.username;
let password = this.login_form.password;
//表单提交
this.$refs['login_form'].validate(valid=>{
if(valid){
console.log(username);
console.log(password);
//发送请求
console.log("发起请求");
this.axios.get("/user/login",{
params:{
"username":username,
"password":password
}
}).then(resp=>{
//成功
if(resp.status === 0){
//跳转页面
Router.push("/index");
}else{
//后台返回登录失败
ElementUI.Message({
message:resp.data.message,
duration:2000,
type:'error'
})
}
}).catch(error =>{
//异常
console.log(error);
})
}
else {
this.$message({
message:"表单有误",
duration:2000,
type:'error'
})
}
})
},
//用户注册
toRegister(){
this.$router.push("/register")
}
}
}
</script>
<style lang="scss" >
.bg{
background-image: url("../assets/img/login_bg.png");
width:100vw;
height: 100vh;
background-size: cover;
overflow: hidden;
.form-class{
height: 320px;
width: 300px;
background: #fff;
text-align: center;
margin: 280px auto;
border-radius: 5px;
box-shadow:0 0 20px #cac6c6;
border: 1px solid #eaeaea;
padding: 20px 20px;
}
}
</style>
register.vue
<template>
<div class="bg">
<el-form :model="user_register_form" class="form-class" :rules="rules" ref="register_form">
<h2>用户注册</h2>
<br>
<el-form-item prop="email">
<el-input type="text" v-model="user_register_form.email" placeholder="邮箱"></el-input>
</el-form-item>
<el-form-item prop="username">
<el-input type="text" v-model="user_register_form.username" placeholder="用户名"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" v-model="user_register_form.password" placeholder="密码"></el-input>
</el-form-item>
<br>
<el-form-item>
<el-button @click="registerButtonClick()" type="primary">注册</el-button>
<el-button @click="backLogin()">返回</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import router from "../router/index";
export default {
name: "register",
data(){
return{
user_register_form:{
email:'',
username:'',
password:''
},
rules:{
username:[
{required:true,message:'请输入用户名',trigger:'blur'}
],
email:[
{required:true,message:'请输入邮箱',trigger:'blur'}
],
password:[
{required:true,message:'请输入密码',trigger:'blur'},
{min:4,max:8,message:'长度在4~8个字符之间',trigger:'blur'}
]
}
}
},
methods:{
//注册表单提交
registerButtonClick(){
this.$refs['register_form'].validate((valid)=>{
//数据校验
if(valid){
//访问后台保存用户
let username = this.user_register_form.username;
let email = this.user_register_form.email;
let password = this.user_register_form.password;
var parames = new URLSearchParams();
parames.append("username",username);
parames.append("password",password);
parames.append("email",email);
console.log(username+' '+password+' '+email);
this.axios.post('/user/register',parames).then(function (response) {
console.log(response);
//返回成功 跳转登录页面
if(response.status === 0) {
//注册成功
router.push("/login")
}else{
//注册失败
console.log(response.data.message)
}
}).catch(function (response) {
//请求失败
alert("数据请求失败");
})
}else{
this.$message({
message:'数据有误',
duration:2000,
type:'error'
})
}
})
},
backLogin(){
//登录跳转
this.$router.push("/login")
}
}
}
</script>
<style lang="scss">
.bg{
background-image: url("../assets/img/login_bg.png");
width:100vw;
height: 100vh;
background-size: cover;
overflow: hidden;
.form-class{
height: 350px;
width: 300px;
background: #fff;
text-align: center;
margin: 280px auto;
border-radius: 5px;
box-shadow:0 0 20px #cac6c6;
border: 1px solid #eaeaea;
padding: 20px 20px;
}
}
</style>
index.vue
<template>
<div>
<h1>登陆成功</h1>
</div>
</template>
<script>
export default {
name: "index"
}
</script>
<style scoped>
</style>
编写App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
<style>
@import "./assets/css/style.css";
</style>
在main.js中引入各种依赖
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'
import axios from 'axios'
import VueAxios from 'vue-axios'
// mock开关
const mock = false;
if(mock){
require('./mock/mock.js')
}
//引入ElementUI样式
import 'element-ui/lib/theme-chalk/index.css'
//使用element-UI
Vue.use(ElementUI);
//Vue使用axios
Vue.use(VueAxios,axios);
//添加向后端发起请求的服务器地址
axios.defaults.baseURL = "http://localhost:80/api";
//设置超时时间
axios.defaults.timeout = 5000;
//对接口request进行拦截
axios.interceptors.request.use(function (config) {
console.log("pre-axios");
return config;
});
//接口response错误的拦截
axios.interceptors.response.use(function (response) {
console.log("after-axios");
//状态码的拦截 如果后端返回的状态码不是200则提示用户
if(response.status !== 200){
this.$message({
message:'xxx',
type:'error',
duration:2000
});
return Promise.reject(response)
}else{
//如果状态码是200
return response.data;
}
});
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
package.json
{
"name": "login-test",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.20.0",
"cnpm": "^6.1.1",
"core-js": "^3.6.5",
"element-ui": "^2.13.2",
"mockjs": "^1.1.0",
"sass": "^1.26.10",
"sass-loader": "^10.0.1",
"vue": "^2.6.11",
"vue-axios": "^2.1.5",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
在仓库中创建springboot的Maven项目
后端工作目录
在application.properties中添加数据库
#连接的数据库
spring.datasource.url=jdbc:mysql://::1:3306/demo?serverTimezone=UTC&characterEncoding=utf-8&useSSL=true
spring.datasource.username=login
spring.datasource.password=123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
domain
User
package com.sikiedu.logindemo.domain;
public class User {
private Integer id;
private String username;
private String password;
private String email;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
utils
CommonResult
package com.sikiedu.logindemo.utils;
public class CommonResult<T> {
private int status;
private T data;
//构造方法
protected CommonResult(){
}
protected CommonResult(int status,T data){
this.status=status;
this.data=data;
}
//返回成功的一种 不带用data信息
public static <T>CommonResult<T> success(){
return new CommonResult<T>(0,null);
}
//返回成功的一种 带有data信息
public static <T>CommonResult<T> success(T data){
return new CommonResult<T>(0,data);
}
//返回失败的函数
public static <T>CommonResult<T> failed(int status,T data){
return new CommonResult<T>(status,data);
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
Message
package com.sikiedu.logindemo.utils;
public class Message {
private String message;
//构造方法
public Message(String message){
this.message=message;
}
//创建一个消息
public static Message createMessage(String message){
return new Message(message);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
vo
User
package com.sikiedu.logindemo.vo;
//当前端给的数据很多的时候 我们就可以把前端的数据封装成一个综合类
public class User {
}
dao
UserMapper
package com.sikiedu.logindemo.dao;
import com.sikiedu.logindemo.domain.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
//查询用户是否存在
@Select("select count(*) from user where username = #{username}")
int findUserByUsername(String username);
@Insert("insert into user(username,password,email) values(#{username},#{password},#{email}) ")
void addUser(User user);
@Select("select count(*) from user where username =#{username} and password = #{password}")
int findUserByUsernameAndPassword(User user);
}
service
UserService
package com.sikiedu.logindemo.service;
import com.sikiedu.logindemo.domain.User;
import org.springframework.stereotype.Service;
@Service
public interface UserService {
int register(User user);
int login(User user);
}
UserServiceImpl
package com.sikiedu.logindemo.service.impl;
import com.sikiedu.logindemo.dao.UserMapper;
import com.sikiedu.logindemo.domain.User;
import com.sikiedu.logindemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public int login(User user) {
//判断密码是否正确
int count = userMapper.findUserByUsernameAndPassword(user);
if(count == 1){
return 0;
}else{
//2表示用户名或者密码错误
return 2;
}
}
//用户注册
@Override
public int register(User user) {
//判断用户是否存在 存在则不能注册并给提示信息
int count = userMapper.findUserByUsername(user.getUsername());
if(count == 0){
//用户不存在 可以注册
//todo 可能会出现错误 会有返回值 返回的是影响数据库的条数 只有返回1才是正常的操作
userMapper.addUser(user);
return 0;
}else {
//用户已存在
return 1;
}
}
}
controller
UserController
package com.sikiedu.logindemo.controller;
import com.sikiedu.logindemo.domain.User;
import com.sikiedu.logindemo.service.UserService;
import com.sikiedu.logindemo.utils.CommonResult;
import com.sikiedu.logindemo.utils.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller()
@RequestMapping("/api/user")
//配置跨域访问
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
//用户登录
@GetMapping("/login")
@ResponseBody
public CommonResult<Message> login(String username,String password){
System.out.println(username+' '+password);
User user = new User();
user.setUsername(username);
user.setPassword(password);
System.out.println(user);
int status = userService.login(user);
if(status == 0){
return CommonResult.success(Message.createMessage("成功"));
}else if(status == 2){
return CommonResult.failed(status,Message.createMessage("用户名或者密码错误"));
}else{
return null;
}
}
@PostMapping("/register")
@ResponseBody
public CommonResult<Message> register(String username,String password,String email){
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setEmail(email);
//注册逻辑
int status = userService.register(user);
if(status == 0){
return CommonResult.success(Message.createMessage("成功"));
}
/*
一般的话 都是10001 用户名已经注册
10002 用户名或者密码错误
20001 商品已经存在
20002 .。 状态码都是这样的
*/
else if(status == 1){
return CommonResult.failed(status,Message.createMessage("用户已经注册,请更换用户名"));
}else{
return null;
}
}
}
esult.failed(status,Message.createMessage("用户名或者密码错误"));
}else{
return null;
}
}
@PostMapping("/register")
@ResponseBody
public CommonResult<Message> register(String username,String password,String email){
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setEmail(email);
//注册逻辑
int status = userService.register(user);
if(status == 0){
return CommonResult.success(Message.createMessage("成功"));
}
/*
一般的话 都是10001 用户名已经注册
10002 用户名或者密码错误
20001 商品已经存在
20002 .。 状态码都是这样的
*/
else if(status == 1){
return CommonResult.failed(status,Message.createMessage("用户已经注册,请更换用户名"));
}else{
return null;
}
}
}