Vue+Spring Boot简单用户登录(附Demo)


Posted in Javascript onNovember 12, 2020

1 概述

前后端分离的一个简单用户登录 Demo

2 技术栈

  • Vue
  • BootstrapVue
  • Kotlin
  • Spring Boot
  • MyBatis Plus

3 前端

3.1 创建工程

使用 vue-cli 创建,没安装的可以先安装:

sudo cnpm install -g vue @vue/cli

查看版本:

vue -V

出现版本就安装成功了。

创建初始工程:

vue create bvdemo

由于目前 Vue3 还没有发布正式版本,推荐使用 Vue2

Vue+Spring Boot简单用户登录(附Demo)

等待一段时间构建好了之后会提示进行文件夹并直接运行:

Vue+Spring Boot简单用户登录(附Demo)

cd bvdemo
yarn serve

直接通过本地的 8080 端口即可访问:

Vue+Spring Boot简单用户登录(附Demo)

Vue+Spring Boot简单用户登录(附Demo)

3.2 依赖

进入项目文件夹:

cd bvdemo

安装依赖:

cnpm install bootstrap-vue axios jquery vue-router

应该会出现 popper.js 过期的警告,这是 bootstrap-vue 的原因,可以忽略:

Vue+Spring Boot简单用户登录(附Demo)

依赖说明如下:

  • bootstrap-vue :一个结合了 VueBootstrap 的前端 UI 框架
  • axios 是一个简洁易用高效的 http 库,本项目使用其发送登录请求
  • jquery :一个强大的 JS
  • vue-routerVue 的官方路由管理器

3.3 开启补全

在正式编写代码之前开启对 bootstrap-vue 的补全支持,打开设置:

Vue+Spring Boot简单用户登录(附Demo)

将项目路径下的 node_modules 添加到库中,把前面的勾给勾上,接着更新缓存并重启(`File->Invalidate Cache/Restart`)。

3.4 App.vue

去掉默认的 HelloWorld 组件,并修改 App.vue 如下:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

<router-view> 是一个 functional 组件,渲染路径匹配到的视图组件,这里使用 <router-view> 根据访问路径(路由)的不同显示(渲染)相应的组件。

3.5 新建 vue 组件

删除默认的 HelloWorld.vue ,新建 Index.vue 以及 Login.vue

Vue+Spring Boot简单用户登录(附Demo)

3.6 添加路由

main.js 同级目录下新建 router.js ,内容如下:

import Vue from "vue"
import VueRouter from "vue-router"
import Login from "@/components/Login"
import Index from "@/components/Index"

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    component: Login,
    props: true
  },
  {
    path:'/index/:val',
    name:'index',
    component: Index,
    props: true
  }
]

const router = new VueRouter({
  mode:'history',
  routes:routes
})

export default router

routes 表示路由,其中包含了两个路由,一个是 Login 组件的路由 / ,一个是 Index 组件的路由 /index/:val ,后者中的 :val 是占位符,用于传递参数。 router 表示路由器, mode 可以选择 hashhistory

  • hash 会使用 URLhash 来模拟一个完整的 URL ,当 URL 改变时页面不会重新加载
  • history 就是普通的正常 URL

router 中的 routes 参数声明了对应的路由,最后要记得把 router 添加到 main.js 中。

3.7 vue.config.js

package.json 同级目录下创建 vue.config.js ,内容如下:

module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.transformAssetUrls = {
          img: 'src',
          image: 'xlink:href',
          'b-img': 'src',
          'b-img-lazy': ['src', 'blank-src'],
          'b-card': 'img-src',
          'b-card-img': 'src',
          'b-card-img-lazy': ['src', 'blank-src'],
          'b-carousel-slide': 'img-src',
          'b-embed': 'src'
        }
        return options
      })
  }
}

使用该配置文件主要是因为 <b-img>src 属性不能正常读取图片,添加了该配置文件后即可按路径正常读取。

3.8 main.js

添加依赖以及路由:

import Vue from 'vue'
import App from './App.vue'

import {BootstrapVue, BootstrapVueIcons} from 'bootstrap-vue'
import router from "@/router";
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Vue.use(BootstrapVue)
Vue.use(BootstrapVueIcons)
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

引入 BootstrapVue ,并把路由注册到 Vue 实例中(就是倒数第2行,作为创建 Vue 实例的参数,注意这个很重要,不然路由功能不能正常使用)。

3.9 登录组件

也就是 Login.vue ,内容如下:

<template>
  <div>
    <b-img src="../assets/logo.png"></b-img>
    <br>
    <b-container>
      <b-row>
        <b-col offset="3" cols="6">
          <b-input-group size="lg">
            <b-input-group-text>用户名</b-input-group-text>
            <b-form-input type="text" v-model="username"></b-form-input>
          </b-input-group>
        </b-col>
      </b-row>
      <br>
      <b-row>
        <b-col offset="3" cols="6">
          <b-input-group size="lg">
            <b-input-group-text>密码</b-input-group-text>
            <b-form-input type="password" v-model="password"></b-form-input>
          </b-input-group>
        </b-col>
      </b-row>
      <br>
      <b-row>
        <b-col offset="3" cols="6">
          <b-button variant="success" @click="login">
            一键注册/登录
          </b-button>
        </b-col>
      </b-row>
    </b-container>
  </div>
</template>

<script>
import axios from 'axios'
import router from "@/router"

export default {
  name: "Login.vue",
  data:function (){
    return{
      username:'',
      password:''
    }
  },
  methods:{
    login:function(){
      axios.post("http://localhost:8080/login",{
        username:this.username,
        password:this.password
      }).then(function (res){
        router.push({
          name:"index",
          params:{
            val:res.data.code === 1
          }
        })
      })
    }
  }
}
</script>

<style scoped>

</style>

采用了网格系统布局 <b-row> + <b-col> ,其他组件就不说了,大部分组件官网都有说明(可以 戳这里 ),发送请求采用了 axios ,参数包装在请求体中,注意需要与后端( @RequestBody ,写在请求头请使用 @RequestParm )对应。

另外还需要注意的是跨域问题,这里的跨域问题交给后端处理:

@CrossOrigin(http://localhost:8081)

(本地测试中后端运行在 8080 端口,而前端运行在 8081 端口)

发送请求后使用路由进行跳转,携带的是 res.data.code 参数 ,其中 res.data 是响应中的数据,后面的 code 是后端自定义的数据,返回 1 表示注册成功,返回 2 表示登录成功。

3.10 首页组件

首页简单地显示了登录或注册成功:

<template>
  <div>
    <b-img src="../assets/logo.png"></b-img>
    <b-container>
      <b-row align-h="center">
        <b-col>
          <b-jumbotron header="注册成功" lead="欢迎" v-if="val"></b-jumbotron>
          <b-jumbotron header="登录成功" lead="欢迎" v-else></b-jumbotron>
        </b-col>
      </b-row>
    </b-container>
  </div>
</template>

<script>
export default {
  name: "Index.vue",
  props:['val']
}
</script>

<style scoped>

</style>

props 表示 val 是来自其他组件的参数,并将其作为在 v-if 中进行条件渲染的参数。

这样前端就做好了。下面开始介绍后端。

4 后端

4.1 创建工程

采用 Kotlin + Gradle + MyBatisPlus 构建,新建工程如下:

Vue+Spring Boot简单用户登录(附Demo)

Vue+Spring Boot简单用户登录(附Demo)

Vue+Spring Boot简单用户登录(附Demo)

4.2 依赖

引入 MyBatis Plus 依赖即可:

implementation("com.baomidou:mybatis-plus-boot-starter:3.4.0")

4.3 数据表

create database if not exists test;
use test;
drop table if exists user;
create table user(
  id int auto_increment primary key ,
  username varchar(30) default '',
  password varchar(30) default ''
)

4.4 配置文件

数据库用户名+密码+ url

spring:
 datasource:
  url: jdbc:mysql://localhost:3306/test
  username: root
  password: 123456

4.5 新建包

新建如下六个包,分别表示配置类、控制层、持久层、实体类、响应类、业务层。

Vue+Spring Boot简单用户登录(附Demo)

4.6 实体类

package com.example.demo.entity

class User(var username:String,var password:String)

4.7 持久层

package com.example.demo.dao

import com.baomidou.mybatisplus.core.mapper.BaseMapper
import com.example.demo.entity.User
import org.apache.ibatis.annotations.Mapper
import org.apache.ibatis.annotations.Select

@Mapper
interface DemoMapper :BaseMapper<User>{
  @Select("select * from user where username=#{username} and password = #{password}")
  fun selectByUsernameAndPassword(username:String,password:String):List<User>
}

@Mapper 表示给 Mapper 接口生成一个实现类,并且不需要编写 xml 配置文件。 @Select 表示进行查询的 sql 语句。

4.8 响应体

package com.example.demo.response

class DemoResponse
{
  var data = Any()
  var code = 0
  var message = ""
}
package com.example.demo.response

class DemoResponseBuilder {
  private var response = DemoResponse()

  fun data(t:Any): DemoResponseBuilder
  {
    response.data = t
    return this
  }
  fun code(t:Int): DemoResponseBuilder
  {
    response.code = t
    return this
  }
  fun message(t:String): DemoResponseBuilder
  {
    response.message = t
    return this
  }
  fun build() = response
}

这里响应体分为:

  • 响应码
  • 响应体数据
  • 其他信息

与前端约定即可。生成响应体通过一个 Builder 类生成。

4.9 业务层

package com.example.demo.service

import com.demo.response.DemoResponse
import com.demo.response.DemoResponseBuilder
import com.example.demo.dao.DemoMapper
import com.example.demo.entity.User
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional
class DemoService
{
  @Autowired
  lateinit var mapper: DemoMapper

  fun login(username:String, password:String): DemoResponse
  {
    val result = mapper.selectByUsernameAndPassword(username,password).size
    if(result == 0)
      mapper.insert(User(username,password))
    return DemoResponseBuilder().code(if(result == 0) 1 else 2).message("").data(true).build()
  }
}

@Service 标记为业务层, @Transactional 表示添加了事务管理,持久层操作失败会进行回滚。 @Autowired 表示自动注入,在 Java
中可以使用直接使用 @Autowired ,而在 Kotlin 中需要使用 lateinit var

4.10 控制层

package com.example.demo.controller

import com.demo.response.DemoResponse
import com.example.demo.entity.User
import com.example.demo.service.DemoService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/")
@CrossOrigin("http://localhost:8081")
class DemoController {
  @Autowired
  lateinit var service: DemoService

  @PostMapping("login")
  fun login(@RequestBody user: User):DemoResponse
  {
    return service.login(user.username, user.password)
  }
}

主要就是添加了一个跨域处理 @CrossOrigin ,开发时请对应上前端的端口。

4.11 配置类

package com.example.demo.config

import org.mybatis.spring.annotation.MapperScan
import org.springframework.context.annotation.Configuration

@Configuration
@MapperScan("com.example.demo.dao")
class MyBatisConfig

@MapperScan 表示扫描对应包下的 @Mapper

4.12 测试

package com.example.demo

import com.example.demo.service.DemoService
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
class DemoApplicationTests {

  @Autowired
  lateinit var service: DemoService

  @Test
  fun contextLoads() {
    println(service.login("123", "456"))
  }

}

测试通过后后端就算完成了。

5 总测试

先运行后端, Kotlin 不像 Java ,生成工程时能自动配置了启动配置,需要手动运行启动类中的 main

Vue+Spring Boot简单用户登录(附Demo)

再运行前端:

npm run serve

不想用命令行的话可以使用图形界面配置一下:

Vue+Spring Boot简单用户登录(附Demo)

根据控制台输出打开 localhost:8081

Vue+Spring Boot简单用户登录(附Demo)

Vue+Spring Boot简单用户登录(附Demo)

随便输入用户名与密码,不存在则创建,存在则登录:

Vue+Spring Boot简单用户登录(附Demo)

Vue+Spring Boot简单用户登录(附Demo)

注册的同时后端数据库会生成一条记录:

Vue+Spring Boot简单用户登录(附Demo)

再次输入相同的用户名和密码会显示登录成功:

Vue+Spring Boot简单用户登录(附Demo)

这样就正式完成了一个简单的前后端分离登录 Demo

到此这篇关于Vue+Spring Boot简单用户登录(附Demo)的文章就介绍到这了,更多相关Vue+Spring Boot 用户登录 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jQuery ajax(复习)—Baidu ajax request分离版
Jan 24 Javascript
2016年最热门的15 款代码语法高亮工具,美化你的代码
Jan 06 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
May 21 Javascript
浅谈js之字面量、对象字面量的访问、关键字in的用法
Nov 20 Javascript
JavaScript表单验证完美代码
Mar 02 Javascript
JS排序之选择排序详解
Apr 08 Javascript
jQuery选取所有复选框被选中的值并用Ajax异步提交数据的实例
Aug 04 jQuery
JS获取input[file]的值并显示在页面的实现方法
Mar 09 Javascript
微信小程序实现页面下拉刷新和上拉加载功能详解
Dec 03 Javascript
Vue组件跨层级获取组件操作
Jul 27 Javascript
JavaScript实现点击图片换背景
Nov 20 Javascript
vue中控制mock在开发环境使用,在生产环境禁用方式
Apr 06 Vue.js
vue 获取url里参数的两种方法小结
Nov 12 #Javascript
带你使用webpack快速构建web项目的方法
Nov 12 #Javascript
vue项目实现减少app.js和vender.js的体积操作
Nov 12 #Javascript
详解vue 组件的实现原理
Nov 12 #Javascript
Vant Weapp组件踩坑:picker的初始赋值解决
Nov 12 #Javascript
vue 图片裁剪上传组件的实现
Nov 12 #Javascript
js前端传json后台接收‘‘被转为quot的问题解决
Nov 12 #Javascript
You might like
Email+URL的判断和自动转换函数
2006/10/09 PHP
php SQL之where语句生成器
2009/03/24 PHP
PHP中通过加号合并数组的一个简单方法分享
2011/01/27 PHP
php实现的树形结构数据存取类实例
2014/11/29 PHP
Laravel 5 学习笔记
2015/03/06 PHP
详解WordPress中分类函数wp_list_categories的使用
2016/01/04 PHP
Yii框架上传图片用法总结
2016/03/28 PHP
php json中文编码为null的解决办法
2016/12/14 PHP
打造基于jQuery的高性能TreeView(asp.net)
2011/02/23 Javascript
jquery常用特效方法使用示例
2014/04/25 Javascript
JavaScript获取指定元素位置的方法
2015/04/08 Javascript
js 简易版滚动条实例(适用于移动端H5开发)
2017/06/26 Javascript
使用vue构建一个上传图片表单
2017/07/04 Javascript
超级简易的JS计算器实例讲解(实现加减乘除)
2017/08/08 Javascript
axios 处理 302 状态码的解决方法
2018/04/10 Javascript
微信小程序实现折叠展开效果
2018/07/19 Javascript
JS+HTML5实现获取手机验证码倒计时按钮
2018/08/08 Javascript
深入探讨JavaScript的最基本部分之执行上下文
2019/02/12 Javascript
前端插件之Bootstrap Dual Listbox使用教程
2019/07/23 Javascript
在Python中使用mongoengine操作MongoDB教程
2015/04/24 Python
Django小白教程之Django用户注册与登录
2016/04/22 Python
Python中index()和seek()的用法(详解)
2017/04/27 Python
Python利用递归和walk()遍历目录文件的方法示例
2017/07/14 Python
浅析Python 3 字符串中的 STR 和 Bytes 有什么区别
2018/10/14 Python
解决python3捕获cx_oracle抛出的异常错误问题
2018/10/18 Python
python递归函数求n的阶乘,优缺点及递归次数设置方式
2020/04/02 Python
一文带你掌握Pyecharts地理数据可视化的方法
2021/02/06 Python
西班牙汉普顿小姐:购买帆布鞋和太阳镜
2016/10/23 全球购物
英国灯具和灯泡网上商店:Lights.co.uk
2018/02/02 全球购物
JBL英国官网:JBL UK
2018/07/04 全球购物
哥德堡通行证:Gothenburg Pass
2019/12/09 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
有abstract方法的类一定要用abstract修饰吗
2016/03/14 面试题
Python Pandas pandas.read_sql函数实例用法
2021/06/21 Python
SpringBoot+VUE实现数据表格的实战
2021/08/02 Java/Android
【海涛dota】偶遇拉娜娅 质量局德鲁伊第一视角解说
2022/04/01 DOTA