用IDEA开发Springboot+VUE项目 第一部分

  1. 新建一个项目,选择Spring Initializr ,点击next


    image.png
  2. 填写group 和 artifact ,点击next,出现如下界面


    image.png
  3. 注意勾选springWeb, JDBC API, Mybatis framework, MySQL Driver,一直next即可
  4. 在src/main/resources中新建一个application.yml(可选,本身的application.properties也可)
  5. 在src/main/resources下新建一个mapper文件夹
  6. 要在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
  1. 运行,并且在浏览器中输入localhost:9000(server中我自己配置的是9000),出现以下界面,即成功


    image.png

@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就跨域了

  1. 在src/main/java/<自己定义的包名>下新建util文件夹,再新建一个WebConfig 的java class ,这个文件是做一些web配置,来处理跨域请求

@Configuration用于定义配置类,可替换xml配置文件

  1. 创建前端项目,在终端输入vue ui,会打开一个浏览器,选择自己想要在的文件夹,创建vue项目,填写名称,包管理器选择npm,git 填写 init project ,点击next, 选择手动,点击next,选择使用配置文件,Router,css, 将Linter/Formatter去掉,点击next
  2. 选择插件,添加插件,element ui, 安装element ui, 安装完成后,一定要选择完成安装,让该插件安装到项目中
  3. 选择依赖,添加依赖, axios,less-loader,less
  4. 点击任务,点击serve,点击运行,项目就已经启动成功了,点击启动app,出现以下界面,即vue已经创建好了


    image.png
  5. 用idea 或者vscode打开该项目,在src下有app.vue,里面就是界面,把一些没有用的删掉,
<template>
  <div id="app">
App 根结点
  </div>
</template>

<script>

</script>

<style>

</style>

此时,界面会变成这样


image.png

项目中只能有一个id叫做app的

  1. 把views下的About.vue Home.vue 删掉,然后将报错的文件中和她们相关的配置都删掉即可

目录结构中,public 放置一些公共的东西, node_moudles 放置后台中的jar包,src中放置自己写的代码, src/assets 是一些公共资源(such as 样式), src/plugin是自己的插件,src/components 是自己写的一些组件,main.js : 引入第三方的资源或者自己的全局配置

在vue中开发不会选择普通的html,而是用组件的形式

  1. 在components中新建文件Login.vue,书写模版如下
<template>
<!--  一定加上div,需要有一个根div的存在-->
  <div>

  </div>
</template>

<script>
export default {

}
</script>

<!--书写样式-->
<style lang = "less" scoped>

</style>

在上述div块中写入 “login 页面”, 刷新界面,会发现界面没有变化,因为在index.vue中还没有配置路由

  1. 在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>

刷新界面,即可看到如下界面


image.png
  1. 再 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>

如下界面


image.png

但是由于这个图标的样式什么的不美观,因此要调整样式

  1. 添加全局样式 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中寻找的

刷新界面,如下所示:


image.png
  1. 更改表单样式中的图标
    在iconfont中,选在好自己想要的图标(我自己是找了用户名和密码的图标试试水)然后下载到本地,更改文件名为font,放到项目的assets文件夹下,再通过文件夹下的demo_index.html 文件,查看如何使用图标


    image.png

    由上图可知,图标已更改

样式很难看,所以现在开始进行样式添加

  1. 打开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>

可以看到结果如下


image.png

translate:移动,transform的一个方法
通过 translate() 方法,元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数

  1. 给头像做一个样式大小的调整,还有各种样式的调整
<!--书写样式-->
<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. 预检测
    1.添加校验属性
  2. 编写校验规则
  3. 校验元素和规则对应的标签进行绑定
    在表单区域加上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>
  1. 重置按钮
    在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();
    },
 
  1. 加入新页面,在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("操作失败!!!")
        }
      })
    }
image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容