-
新建一个项目,选择Spring Initializr ,点击next
-
填写group 和 artifact ,点击next,出现如下界面
- 注意勾选springWeb, JDBC API, Mybatis framework, MySQL Driver,一直next即可
- 在src/main/resources中新建一个application.yml(可选,本身的application.properties也可)
- 在src/main/resources下新建一个mapper文件夹
- 要在application.yml文件中编写一些配置文件(mysql ,mybatis和 server)
# mysql
spring:
datasource:
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/easyproject?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
username: root
password: root
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.demo.model
server:
port: 9000
-
运行,并且在浏览器中输入localhost:9000(server中我自己配置的是9000),出现以下界面,即成功
@RequestMapping **注解为控制器指定可以处理哪些 URL 请求
@Controller 注解是专门用于处理 Http 请求处理的,是以 MVC 为核心的设计思想的控制层
@RestController:@Controller和@ResponseBody的合集,用于标注控制层组件(如struts中的action),配置在controller层表示该控制层里面的方法是以json的格式进行输出。
前后端分离的项目要注意跨域请求,以前不分离的项目都是配置在同一个tomcat下,但是前后端分离的项目,前端在一个tomcat下,后端在一个tomcat下,因此需要处理跨域请求
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子:
http://www.123.com/index.html 调用 http://www.123.com/server.PHP (非跨域)
http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.php(子域名不同:abc/def,跨域)
http://www.123.com:8080/index.html调用 http://www.123.com:8081/server.php(端口不同:8080/8081,跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.php(协议不同:http/https,跨域)
请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
当域名www.abc.com下的js代码去访问www.def.com域名下的资源,就会受到限制。
@CrossOrigin可以处理跨域请求,让你能访问不是一个域的文件。
这个注解放在某个方法上,这个方法就跨域了,放在整个controller上,整个controller就跨域了
- 在src/main/java/<自己定义的包名>下新建util文件夹,再新建一个WebConfig 的java class ,这个文件是做一些web配置,来处理跨域请求
@Configuration用于定义配置类,可替换xml配置文件
- 创建前端项目,在终端输入vue ui,会打开一个浏览器,选择自己想要在的文件夹,创建vue项目,填写名称,包管理器选择npm,git 填写 init project ,点击next, 选择手动,点击next,选择使用配置文件,Router,css, 将Linter/Formatter去掉,点击next
- 选择插件,添加插件,element ui, 安装element ui, 安装完成后,一定要选择完成安装,让该插件安装到项目中
- 选择依赖,添加依赖, axios,less-loader,less
-
点击任务,点击serve,点击运行,项目就已经启动成功了,点击启动app,出现以下界面,即vue已经创建好了
- 用idea 或者vscode打开该项目,在src下有app.vue,里面就是界面,把一些没有用的删掉,
<template>
<div id="app">
App 根结点
</div>
</template>
<script>
</script>
<style>
</style>
此时,界面会变成这样
项目中只能有一个id叫做app的
- 把views下的About.vue Home.vue 删掉,然后将报错的文件中和她们相关的配置都删掉即可
目录结构中,public 放置一些公共的东西, node_moudles 放置后台中的jar包,src中放置自己写的代码, src/assets 是一些公共资源(such as 样式), src/plugin是自己的插件,src/components 是自己写的一些组件,main.js : 引入第三方的资源或者自己的全局配置
在vue中开发不会选择普通的html,而是用组件的形式
- 在components中新建文件Login.vue,书写模版如下
<template>
<!-- 一定加上div,需要有一个根div的存在-->
<div>
</div>
</template>
<script>
export default {
}
</script>
<!--书写样式-->
<style lang = "less" scoped>
</style>
在上述div块中写入 “login 页面”, 刷新界面,会发现界面没有变化,因为在index.vue中还没有配置路由
- 在index.vue中首先引入刚才的login
import Login from '../components/Login'
然后在配置路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login'
Vue.use(VueRouter)
const routes = [
{
path : "/",
redirect : "/login"
},
{
path : "/login",
component : Login
}
]
const router = new VueRouter({
routes
})
export default router
在App.vue的div块中的内容删掉,刷新界面会发现界面变空,再写入<router-view></router-view> 如下
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
</script>
<style lang="scss">
</style>
刷新界面,即可看到如下界面
- 再 Login.vue中写入如下代码
<template>
<!-- 一定加上div,需要有一个根div的存在-->
<div class = "login_container">
<div class= "login_box">
<div class="avatar_box">
<img src="../assets/logo.png" alt/>
</div>
</div>
</div>
</template>
<script>
export default {
}
</script>
<!--书写样式-->
<style lang = "less" scoped>
</style>
如下界面
但是由于这个图标的样式什么的不美观,因此要调整样式
- 添加全局样式 assets/css/global.css
/*全局样式*/
html,body,#app{
height: 100%;
margin: 0;
padding:0;
}
还要引入 到main.js 中,因为main.js是全局的
import './assets/css/global.css'
17.添加login等组件,在Login.vue中写入
<template>
<!-- 一定加上div,需要有一个根div的存在-->
<div class = "login_container">
<!-- 登陆块-->
<div class= "login_box">
<!-- logo-->
<div class="avatar_box">
<img src="../assets/logo.png" alt/>
</div>
<!-- 表单区域-->
<el-form ref="loginFormRef" :model="loginForm" class = "login_form" label-width="0">
<!-- 用户名-->
<el-form-item >
<el-input v-model="loginForm.username " prefix-icon="el-icon-user"></el-input>
</el-form-item>
<!-- 密码-->
<el-form-item >
<el-input v-model="loginForm.password" prefix-icon="el-icon-search"></el-input>
</el-form-item>
<!-- 按钮-->
<el-form-item >
<el-button type="primary" disabled>提交</el-button>
<el-button type="info" disabled>重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loginForm : {
username : "用户名",
password : "password"
}
}
}
}
</script>
<!--书写样式-->
<style lang = "less" scoped>
</style>
以上代码中所有的组件都是从element ui中寻找的
刷新界面,如下所示:
-
更改表单样式中的图标
在iconfont中,选在好自己想要的图标(我自己是找了用户名和密码的图标试试水)然后下载到本地,更改文件名为font,放到项目的assets文件夹下,再通过文件夹下的demo_index.html 文件,查看如何使用图标
由上图可知,图标已更改
样式很难看,所以现在开始进行样式添加
- 打开login.vue,在<style>标签中进行添加样式
<!--书写样式-->
<style lang = "less" scoped>
//根结点样式
.login_container {
background-color: #2b4b6b;
height: 100%;
}
.login_box {
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px; //边框圆角
position: absolute; //绝对定位,有了绝对定位以后才好向左向右移动
left: 50%; //居左居中
top: 50% ; //居上居中
transform: translate(-50%, -50%);
}
</style>
可以看到结果如下
translate:移动,transform的一个方法
通过 translate() 方法,元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数
- 给头像做一个样式大小的调整,还有各种样式的调整
<!--书写样式-->
<style lang = "less" scoped>
//根结点样式
.login_container {
background-color: #2b4b6b;
height: 100%;
}
.login_box {
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px; //边框圆角
position: absolute; //绝对定位,有了绝对定位以后才好向左向右移动
left: 50%; //居左居中
top: 50% ; //居上居中
transform: translate(-50%, -50%);
.avatar_box{
width: 130px;
height: 130px;
border: 1px solid #eee;
border-radius: 50%;
padding: 5px;
box-shadow: 0 0 2px #ddd;
position: absolute; //绝对定位,有了绝对定位以后才好向左向右移动
left: 50%; //居左居中
//top: 50% ; //居上居中
transform: translate(-50%, -50%);
background-color: #0ee;
img{
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #eee;
}
}
.btns{
display: flex;
justify-content: flex-end;
}
.login_form{
position: absolute;
bottom: 0%;
width: 100%;
padding: 10px;
box-sizing: border-box;
}
}
</style>
border : 边框
border-radius:圆角
box-shadow 属性用于在元素的框架上添加阴影效果
content-box 是默认值。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。
border-box 告诉浏览器:你想要设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含它的border和padding,内容区的实际宽度是width减去(border + padding)的值。大多数情况下,这使得我们更容易地设定一个元素的宽高。
绝对定位是相对于父标签决定位置,一般用于相对定位标签里面,JS特效经常用到。
相对定位是相对于上一个相对定位的。一般用于浮动定位标签里面,一般跟绝对定位配合使用。
- 预检测
1.添加校验属性 - 编写校验规则
- 校验元素和规则对应的标签进行绑定
在表单区域加上rules ,在表单区域的下级标签加上prop,再在<script>标签下加入rules的具体实现方法,具体请关注https://element.eleme.cn/#/zh-CN/component/form
<template>
<!-- 一定加上div,需要有一个根div的存在-->
<div class = "login_container">
<!-- 登陆块-->
<div class= "login_box">
<!-- logo-->
<div class="avatar_box">
<img src="../assets/logo.png" alt/>
</div>
<!-- 表单区域-->
<el-form ref="loginFormRef" :rules="loginRules" :model="loginForm" class = "login_form" label-width="0px">
<!-- 用户名-->
<el-form-item prop="username">
<el-input v-model="loginForm.username " prefix-icon="iconfont icon-user"></el-input>
</el-form-item>
<!-- 密码-->
<el-form-item prop="password">
<el-input v-model="loginForm.password" prefix-icon="iconfont icon-mima"></el-input>
</el-form-item>
<!-- 按钮-->
<el-form-item >
<el-button type="primary" disabled>提交</el-button>
<el-button type="info" disabled>重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
//表单数据
data() {
return {
loginForm : {
username : "用户名",
password : "password"
},
//验证
loginRules:{
//校验用户名
username: [
{required:true, message:"用户名", trigger:'blur'}, //必填项
{ min: 5, max: 12, message: '长度在 5 到 12 个字符', trigger: 'blur' } //长度验证
],
//校验密码
password: [
{required:true, message:"用户密码", trigger:'blur'}, //必填项
{ min: 6, max: 10, message: '长度在 6 到 10 个字符', trigger: 'blur' } //长度验证
],
},
}
}
}
</script>
<!--书写样式-->
<style lang = "less" scoped>
//根结点样式
.login_container {
background-color: #2b4b6b;
height: 100%;
}
.login_box {
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px; //边框圆角
position: absolute; //绝对定位,有了绝对定位以后才好向左向右移动
left: 50%; //居左居中
top: 50% ; //居上居中
transform: translate(-50%, -50%);
.avatar_box{
width: 130px;
height: 130px;
border: 1px solid #eee;
border-radius: 50%;
padding: 5px;
box-shadow: 0 0 2px #ddd;
position: absolute; //绝对定位,有了绝对定位以后才好向左向右移动
left: 50%; //居左居中
//top: 50% ; //居上居中
transform: translate(-50%, -50%);
background-color: #0ee;
img{
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #eee;
}
}
.btns{
display: flex;
justify-content: flex-end;
}
.login_form{
position: absolute;
bottom: 0%;
width: 100%;
padding: 10px;
box-sizing: border-box;
}
}
</style>
- 重置按钮
在main.js中引入axios
import axios from "axios"
//挂载axios
Vue.prototype.$http = axios
//设置访问跟路径
axios.defaults.baseURL = "http://localhost:9000"
在按钮中加入 @click="resetLoginForm
<!-- 按钮-->
<el-form-item >
<el-button type="primary" >提交</el-button>
<el-button type="info" @click="resetLoginForm">重置</el-button>
</el-form-item>
在<script>中加入
resetLoginForm(){
this.$refs.loginFormRef.resetFields();
},
- 加入新页面,在component下创建Home.vue,并且记得一定要在index.js 中导入它,并且把路径配置一下
import Home from '../components/Home'
{
path : "/home",
component: Home
}
home.js
<template>
<div>
Home 首页!!!
</div>
</template>
<script>
</script>
<style>
</style>
在Login.vue中实现跳转
此时后端一定要开着
login(){
this.$refs.loginFormRef.validate(async valid => {
if(!valid) return;
const {data:res}=await this.$http.post('test'); //解析res
console.log(res);
if(res == "ok") {
this.$message.success("操作成功!!!")
this.$router.push({path:"/home"})
}else{
this.$message.error("操作失败!!!")
}
})
}