编程知识 cdmana.com

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

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]所创,转载请带上原文链接,感谢

Scroll to Top