Springboot Vue login (implement springboot + Vue login from scratch)

MarkerHub 2020-11-12 18:17:39
springboot vue login implement springboot


Small Hub Reading :

A complete Spirngboot+vue A small example of how to log in , I was there before. vueblog China has also done , ha-ha , Let's review !


author :Eli Shaw

https://blog.csdn.net/xiaojin...

One 、 sketch

Recently learned to use Vue Realize the separation of front end and back end , stay Github There's a good open source project on :mall, As the saying goes, one practice is better than one hundred looks , I've done it myself Springboot+Vue Login operation of , Take a note of the pit you've stepped on here .

At the end of the article, we add GitHub Code , Why put it last , Because the article is very detailed , It will be more helpful to operate it , If there is a big discrepancy, you can compare the original code , Looking for problems .

Two 、 development tool

VSCode

IDEA

Vue The installation of , There are many articles , however Springboot+Vue There are relatively few integrated articles , So I mainly record the content of the integration at both ends .

(Vue After installation, there will be npm  or cnpm, The corresponding introduction will not say ,Vue You can check it on the official website )

One 、 open cmd establish Vue project , And add Vue Dependency framework :

1\. establish Vue  project ( Enter the folder you want to create , I put it in D:\VSCodeWorkSpace), Create statement vue create vue-spring-login-summed, Arrow keys to select the creation method , The default I chose

2\. Go to the created Vue Project directory , Add dependency framework :

cd vue-spring-login-summed ( Go to the project root )
vue add element ( add to element, One element Style UI frame )
npm install axios ( install axios, For network requests )
npm install vuex --save( install Vuex, For managing state )
npm install vue-router ( install route , Used to implement two Vue Page Jump )

A screenshot of the above command is shown below :

1) add to Element

2) add to axios

3) add to Vuex

4) add to route

The shelf package of this related dependency has been added , Input code .  open  VSCode

Two 、 Add directory structure

stay  VSCode  I can see  Vue  The overall project structure is as follows

Now you need to create the directory structure of the corresponding function , Do layered development , Need to be in  src  Create the following directories under directory

api ( Network request interface package )
router ( Routing configuration package )
store (Vuex State management pack )
utils ( tool kit )
views (vue View package , Store all vue Code , According to the function module, the corresponding subcontract can be carried out )

The directory structure after creation is as follows

3、 ... and 、 Run the project

Now you can run the project , stay VSCode  Choose... From the menu bar : terminal ——  Run the task ...

What we use here is serve  Pattern , That is, the project running in development mode

Type in the browser :http://localhost:8080/

This is a Vue Default page , On behalf of the successful creation of the project , Before code development , First paste the overall structure of the project , Prevent not knowing where to create

Four 、View  Layer code writing

Write three vue  file :login.vue( The login page )、success.vue( Login success page )、error.vue( Login failure page )

1.login.vue 

The code is as follows ( Compare the lazy , Directly from mall  Stripped code , Removed some features )

<template>
<div>
<el-card>
<el-form
autocomplete="on"
:model="loginForm"
ref="loginForm"
label-position="left"
>
<div>
<svg-icon icon-class="login-mall"></svg-icon>
</div>
<h2>mall-admin-web</h2>
<el-form-item prop="username">
<el-input
type="text"
v-model="loginForm.username"
autocomplete="on"
placeholder=" Please enter a user name "
>
<span slot="prefix">
<svg-icon icon-class="user"></svg-icon>
</span>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
:type="pwdType"
@keyup.enter.native="handleLogin"
v-model="loginForm.password"
autocomplete="on"
placeholder=" Please input a password "
>
<span slot="prefix">
<svg-icon icon-class="password"></svg-icon>
</span>
<span slot="suffix" @click="showPwd">
<svg-icon icon-class="eye"></svg-icon>
</span>
</el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
:loading="loading"
@click.native.prevent="handleLogin"
> Sign in </el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
export default {
name: "login",
data() {
return {
loginForm: {
username: "admin",
password: "123456"
},
loading: false,
pwdType: "password",
};
},
methods: {
showPwd() {
if (this.pwdType === "password") {
this.pwdType = "";
} else {
this.pwdType = "password";
}
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
this.$store
.dispatch("Login", this.loginForm)
.then(response => {
this.loading = false;
let code = response.data.code;
if (code == 200) {
this.$router.push({
path: "/success",
query: { data: response.data.data }
});
} else {
this.$router.push({
path: "/error",
query: { message: response.data.message }
});
}
})
.catch(() => {
this.loading = false;
});
} else {
// eslint-disable-next-line no-console
console.log(" Parameter validation is illegal !");
return false;
}
});
}
}
};
</script>
<style scoped>
.login-form-layout {
position: absolute;
left: 0;
right: 0;
width: 360px;
margin: 140px auto;
border-top: 10px solid #409eff;
}
.login-title {
text-align: center;
}
.login-center-layout {
background: #409eff;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
margin-top: 200px;
}
</style>

2.success.vue

<template>
<div>
<h1>Welcome!{{msg}}</h1>
</div>
</template>
<script>
export default {
data() {
return {
msg: this.$route.query.data
};
},
// data() { // This way, too
// return {
// msg: null
// };
// },
// created() {
// this.msg = this.$route.query.data;
// }
}
</script>

3.error.vue

<template>
<div>
<h1> Login error :{{msg}}</h1>
</div>
</template>
<script>
export default {
// data() {
// return {
// msg: this.$route.query.data
// };
// }, // In this way, you can also show msg
data() {
return {
msg: null
};
},
created() {
this.msg = this.$route.query.message;
}
};
</script>

5、 ... and 、 route

The page is finished , We need to show these three pages in turn , Here we use route To manage the display page , For the official routing documents, see :vue route

Practice first , The code farmer learning method of post understanding . Let's first use routing to display three pages , To understand Vue Routing this function point .

1\. Create routing profile

It's just established router  Create one under the folder index.js  file , The contents are as follows

import Vue from 'vue' // introduce Vue
import VueRouter from 'vue-router' // introduce Vue route
Vue.use(VueRouter); // Installing a plug-in
export const constantRouterMap = \[
// Configure the default path , By default, the login page is displayed
{ path: '/', component: () => import('@/views/login')},
// Configure login success page , You need to use path Path to achieve jump
{ path: '/success', component: () => import('@/views/success')},
// Configure login failure page , You need to use path Path to achieve jump
{ path: '/error', component: () => import('@/views/error'), hidden: true }
\]
export default new VueRouter({
// mode: 'history', // The back end can be opened
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap // Specify route list
})

2\. Add route to program entry

The routing configuration file is written , We need to introduce him to main.js  in , In the project src  Under the directory root node , find main.js, Add the following :

import Vue from 'vue'
import App from './App.vue'
import './plugins/element.js'
import router from './router' // Introduce routing configuration
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router, // Use routing configuration
}).$mount('#app')

3\. Configure the gateway of the route

Now routing has been fully introduced into the project , But routing also needs an entry and exit , This gateway is used to tell the route to display the contents of the route here . above main.js  The first one to configure vue  The display page is App.vue , So we modified it  App.vue  The contents are as follows

<template>
<div>
<!-- The gateway of the route , The contents of the route will be displayed here -->
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>

<router-view/>  It's the gateway to show the route .

Now save  App.vue  After the document , The current project will be reloaded and run , In the interface just browsed, you will see the login interface as follows :

4\. Routing jump

stay login.vue  Can be used in this.$router.push({path: " route "})  To jump to the routing component of the specified path , The following is a route to jump to error.vue  And success.vue Code for

this.$router.push({path: "/success"}); // Jump to success page
or
this.$router.push({path: "/error"}); // Jump to the failed page 

6、 ... and 、 Use  Vuex + Axios  Network request mode

1.Axios

axios  It's a network request Architecture , It's officially recommended to use this method  http  Request .

1)  stay utils  Package encapsulates a request tool class request.js

import axios from 'axios' // introduce axios
import baseUrl from '../api/baseUrl' // Using environment variables + The way patterns define the basis URL
// establish axios example
const service = axios.create({
baseURL: baseUrl, // api Of base\_url
timeout: 15000, // Request timeout
})
export default service

there baseUrl  involve Vue CLI3  The concept of environmental variables and patterns , see :Vue Environment variables and patterns ( Set general baseUrl)

2)  Login request interface API

stay api  Under the folder , Create a login API file :login.js

import request from '@/utils/request' // Introduce packaged axios request
export function login(username, password) { // Login interface
return request({ // Use packaged axios Make a network request
url: '/admin/login',
method: 'post',
data: { // Data submitted
username,
password
}
})
}

2\. Use Vuex  encapsulation axios

Vuex  It's a state management framework , Official documents :Vuex

1) encapsulation Vuex Medium module

stay store  Create one under the folder modules  Folder , Then create a... Under this folder user.js  file

import { login } from '@/api/login'// Introduce login api Interface
const user = {
actions: {
// Sign in
Login({ commit }, userInfo) { // Definition Login Method , Use in components this.$store.dispatch("Login") call
const username = userInfo.username.trim()
return new Promise((resolve, reject) => { // Encapsulates a Promise
login(username, userInfo.password).then(response => { // Use login Interface for network requests
commit('') // To submit a mutation, Notification status change
resolve(response) // Encapsulate the results into Promise
}).catch(error => {
reject(error)
})
})
},
}
}
export default user

The code here is worth explaining : Official documents correspond to :Vuex actions

1\. First introduce login  Interface , Then use the login interface to make network requests .

2\. Define a   be known as Login  Of action  Method ,Vue Components through this.$store.dispatch("Login") call

3.Promise, This class is very interesting , The official explanation is “store.dispatch  Can handle triggered action The handler function of Promise, also  store.dispatch  Still back Promise”. In the component dispatch  The return is still a Promise  class , So speculate Promise  Two of them  resolve() And reject() They correspond to each other dispatch  Medium  then  And  catch.

2) establish Vuex

stay store  Create one under the folder index.js  file

import Vue from 'vue' // introduce Vue
import Vuex from 'vuex' // introduce Vuex
import user from './modules/user' // introduce user module
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user // Use user.js Medium action
}
})
export default store

3)  take  Vuex  Add to main.js  file

Before modification main.js  The documents are as follows :

import Vue from 'vue'
import App from './App.vue'
import './plugins/element.js'
import router from './router' // Introduce routing configuration
import store from './store' // introduce Vuex State management
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router, // Use routing configuration
store // Use Vuex Conduct status management
}).$mount('#app')

Rerun the project , stay Chrome Enter debug mode in browser , Click the login button

You can see that there is a 8088 Port requests , thus Vue All the code on the side has been completed .

\-------------------------------Springboot  Development -------------------------------

Let's not mention project creation , There are many on the Internet , Just use Spring Assistant  Just create it .

The overall directory structure is as follows

1\. stay application.yml Modify port number

Do not mix Vue In a 8080 On port :

server:
port: 8088

2\. Solving cross domain problems

There's a cross domain problem here , namely Vue Use 8080  port , To visit 8088  Port server , Will report a mistake . The error message is as follows :

Access to XMLHttpRequest at 'http://localhost:8088/admin/login' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No'Access-Control-Allow-Origin' header is present on the requested resource.

The question is Vue  End or in Springboot End processing can be , I am here Springboot End processing , Write a CorsConfig  Class contents are as follows , Don't forget to  @Configuration annotation .

@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("\*"); // 1
corsConfiguration.addAllowedHeader("\*"); // 2
corsConfiguration.addAllowedMethod("\*"); // 3
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/\*\*", buildConfig()); // 4
return new CorsFilter(source);
}
}

3.IErrorCode  Interface

Java edition

public interface IErrorCode {
long getCode();
String getMessage();
}

Kotlin edition

interface IErrorCode {
fun getCode(): Long
fun getMessage(): String
}

4.CommonResult class

Java  edition

public class CommonResult<T> {
private long code;
private String message;
private T data;
protected CommonResult() {
}
protected CommonResult(long code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
/\*\*
\* Successfully returned results
\*
\* @param data Acquired data
\*/
public static <T> CommonResult<T> success(T data) {
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
}
/\*\*
\* Successfully returned results
\*
\* @param data Acquired data
\* @param message Prompt information
\*/
public static <T> CommonResult<T> success(T data, String message) {
return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
}
/\*\*
\* Failure returns result
\*
\* @param errorCode Error code
\*/
public static <T> CommonResult<T> failed(IErrorCode errorCode) {
return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
}
/\*\*
\* Failure returns result
\*
\* @param message Prompt information
\*/
public static <T> CommonResult<T> failed(String message) {
return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
}
/\*\*
\* Failure returns result
\*/
public static <T> CommonResult<T> failed() {
return failed(ResultCode.FAILED);
}
/\*\*
\* Parameter validation failed return result
\*/
public static <T> CommonResult<T> validateFailed() {
return failed(ResultCode.VALIDATE\_FAILED);
}
/\*\*
\* Parameter validation failed return result
\*
\* @param message Prompt information
\*/
public static <T> CommonResult<T> validateFailed(String message) {
return new CommonResult<T>(ResultCode.VALIDATE\_FAILED.getCode(), message, null);
}
/\*\*
\* No login returned result
\*/
public static <T> CommonResult<T> unauthorized(T data) {
return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
}
/\*\*
\* Unauthorized return result
\*/
public static <T> CommonResult<T> forbidden(T data) {
return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
}
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

Kotlin  edition

class CommonResult<T> {
var code: Long = 0
var message: String? = null
var data: T? = null
constructor(code: Long, message: String, data: T?) {
this.code = code
this.message = message
this.data = data
}
companion object {
/\*\*
\* Successfully returned results
\* @param data Acquired data
\*/
fun <T> success(data: T): CommonResult<T> {
return CommonResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data)
}
/\*\*
\* Successfully returned results
\* @param data Acquired data
\* @param message Prompt information
\*/
fun <T> success(data: T, message: String): CommonResult<T> {
return CommonResult(ResultCode.SUCCESS.getCode(), message, data)
}
/\*\*
\* Failure returns result
\* @param errorCode Error code
\*/
fun <T> failed(errorCode: IErrorCode): CommonResult<T> {
return CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null)
}
/\*\*
\* Failure returns result
\* @param message Prompt information
\*/
fun <T> failed(message: String): CommonResult<T> {
return CommonResult<T>(ResultCode.FAILED.getCode(), message, null)
}
/\*\*
\* Failure returns result
\*/
fun failed(): CommonResult<Any> {
return failed(ResultCode.FAILED)
}
/\*\*
\* Parameter validation failed return result
\*/
fun validateFailed(): CommonResult<Any> {
return failed(ResultCode.VALIDATE\_FAILED)
}
/\*\*
\* Parameter validation failed return result
\* @param message Prompt information
\*/
fun <T> validateFailed(message: String): CommonResult<T> {
return CommonResult<T>(ResultCode.VALIDATE\_FAILED.getCode(), message, null)
}
/\*\*
\* No login returned result
\*/
fun <T> unauthorized(data: T): CommonResult<T> {
return CommonResult(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data)
}
/\*\*
\* Unauthorized return result
\*/
fun <T> forbidden(data: T): CommonResult<T> {
return CommonResult(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data)
}
}
}

5.ResultCode  enumeration

Java  edition

public enum ResultCode implements IErrorCode {
SUCCESS(200, " Successful operation "),
FAILED(500, " operation failed "),
VALIDATE\_FAILED(404, " Parameter test failed "),
UNAUTHORIZED(401, " Not logged in or token It's overdue "),
FORBIDDEN(403, " There is no relevant authority ");
private long code;
private String message;
private ResultCode(long code, String message) {
this.code = code;
this.message = message;
}
public long getCode() {
return code;
}
public String getMessage() {
return message;
}
}

Kotlin  edition

enum class ResultCode(private val code: Long, private val message: String) : IErrorCode {
SUCCESS(200, " Successful operation "),
FAILED(500, " operation failed "),
VALIDATE\_FAILED(404, " Parameter test failed "),
UNAUTHORIZED(401, " Not logged in or token It's overdue "),
FORBIDDEN(403, " There is no relevant authority ");
override fun getCode(): Long {
return code
}
override fun getMessage(): String {
return message
}
}

6.User class

Java  edition

public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int 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;
}
}

Kotlin  edition

data class User(
val id: Int,
val username: String,
val password: String)

7.LoginController  class

Java  edition

@RestController
public class LoginController {
@RequestMapping(value = "/admin/login", method = RequestMethod.POST)
public CommonResult login(@RequestBody User user) {
if (user.getUsername().equals("admin") && user.getPassword().equals("123456"))
return CommonResult.success("admin");
else
return CommonResult.validateFailed();
}
}

Kotlin  edition

@RestController // The note is @ResponseBody and @Controller Combined notes for , Can return one JSON
class LoginController {
@RequestMapping(value = \["/admin/login"\], method = \[RequestMethod.POST\])
fun admin(@RequestBody user: User): CommonResult<\*> {
return if (user.username == "admin" && user.password == "123456") {
CommonResult.success("admin")
} else {
CommonResult.validateFailed()
}
}
}

Start both end programs

Enter the correct account password

Enter the wrong account and password

7、 ... and 、GitHub Source code address

vue End :https://github.com/xiaojinlai/vue-spring-login-summed

Java End :https://github.com/xiaojinlai/vue-login-java

Java End - Kotlin edition :https://github.com/xiaojinlai/vue-login-kotlin

notes :Kotlin It's just that I'm used to it myself Kotlin, In terms of function, it is related to Java It's the same . If you don't like it, you can ignore , If you are interested, you can have a look ,Kotlin  yes Google  A succinct language introduced , The main reason is that  Android  On , I like it after I used to it . It's not hard to learn , There's not much , Recommend a study  Kotlin  The website of :https://www.kotlincn.net/docs/reference/


( End )

Recommended reading :

B standing 100K Play volume ,SpringBoot+Vue Complete introduction to front and back separation !

Share a set of SpringBoot Develop blog system source code , And complete development documentation ! Speed saving !

Github The best thing to learn 100 individual Java Open source project , Covering a variety of technology stacks !

2020 The most recent interview questions and answers for enterprises in

版权声明
本文为[MarkerHub]所创,转载请带上原文链接,感谢

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple