springboot+vue实现登录功能的最新方法整理

目录
  • 一、介绍
  • 二、环境工具
  • 三、搭建后端spring-boot框架
    • 1、选择Spring Initializr创建新项目
    • 2、CommonResult类
    • 3、IErrorCode 接口
    • 4、ResultCode 枚举
    • 5、User类
    • 6、LoginController类
    • 7、修改DemoApplication
    • 8、更改端口号在application.yml
    • 9、不同端口需要解决跨域问题
  • 四、搭建前端Vue框架
    • 1、创建Vue项目
    • 2、添加项目依赖框架
      • 2.1 使用Vue项目管理器添加依赖
      • 2.2 使用命令代码添加依赖
    • 3、测试运行项目
    • 4、编写view层面代码
      • 4.1 登陆页面:login.vue
      • 4.2  登陆成功页面:success.vue
      • 4.3 登陆失败页面:error.vue
    • 5、设置路由统一管理页面
      • 5.1 创建路由文件
      • 5.2 将创建好的路由引入到项目中
      • 5.3 设置路由的出入口
    • 6、配置网络请求
      • 6.1 封装请求工具
      • 6.2 登录页面接口 API
      • 6.3 封装 axios
  • 五、实现登录功能
    • 1、启动两端程序,进入locallhost:8080
    • 2、输入账号密码
      • 2.1 正确登录
      • 2.2 错误登录
  • 总结

一、介绍

搜索了关于spring boot+vue的前后端分离实践项目很多,但是对于最基础登录功能的博客却是几年前的了。于是学习了好几个大神的文章后,自己通过实践解决了vue改版等众多问题后实现了登录功能。

二、环境工具

  • vue2.0
  • element-ui
  • axios
  • vue-router
  • vuex
  • Java
  • spring-boot
  • vscode
  • idea

三、搭建后端spring-boot框架

1、选择Spring Initializr创建新项目

展现最终项目结构如下,方便下面步骤实现

2、CommonResult类

package cn.eli.vue.api;

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;
    }

    /**
     * 成功返回结果
     *
     * @param data 获取的数据
     */
    public static <T> CommonResult<T> success(T data) {
        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
    }

    /**
     * 成功返回结果
     *
     * @param data    获取的数据
     * @param message 提示信息
     */
    public static <T> CommonResult<T> success(T data, String message) {
        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
    }

    /**
     * 失败返回结果
     *
     * @param errorCode 错误码
     */
    public static <T> CommonResult<T> failed(IErrorCode errorCode) {
        return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
    }

    /**
     * 失败返回结果
     *
     * @param message 提示信息
     */
    public static <T> CommonResult<T> failed(String message) {
        return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
    }

    /**
     * 失败返回结果
     */
    public static <T> CommonResult<T> failed() {
        return failed(ResultCode.FAILED);
    }

    /**
     * 参数验证失败返回结果
     */
    public static <T> CommonResult<T> validateFailed() {
        return failed(ResultCode.VALIDATE_FAILED);
    }

    /**
     * 参数验证失败返回结果
     *
     * @param message 提示信息
     */
    public static <T> CommonResult<T> validateFailed(String message) {
        return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
    }

    /**
     * 未登录返回结果
     */
    public static <T> CommonResult<T> unauthorized(T data) {
        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
    }

    /**
     * 未授权返回结果
     */
    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;
    }
}

3、IErrorCode 接口

package cn.eli.vue.api;

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

4、ResultCode 枚举

package cn.eli.vue.api;

public enum ResultCode implements IErrorCode {
    SUCCESS(200, "操作成功"),
    FAILED(500, "操作失败"),
    VALIDATE_FAILED(404, "参数检验失败"),
    UNAUTHORIZED(401, "暂未登录或token已经过期"),
    FORBIDDEN(403, "没有相关权限");
    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;
    }
}

5、User类

package cn.eli.vue.entity;

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;
    }
}

6、LoginController类

package cn.eli.vue.controller;

import cn.eli.vue.api.CommonResult;
import cn.eli.vue.entity.User;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {

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

7、修改DemoApplication

package cn.eli.vue;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

8、更改端口号在application.yml

Vue前端位于8080端口,后端修改到8088,不要在同一端口:

server:
  port: 8088

9、不同端口需要解决跨域问题

Vue端口位于8080,需要访问8088端口服务器,需要修改CorsConfig 类,在后端处理即可。

package cn.eli.vue.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@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);
    }
}

到这里,springboot端的配置已经全部完成,运行可以成功启动。

四、搭建前端Vue框架

1、创建Vue项目

创建Vue项目可以使用电脑自带cmd,也可以使用gitbush,这里我通过vscode自带终端里面的gitbush进行创建。

vue create code1

(“code1”为vue项目名,可以自己设置)

(由于vue3对于以前的依赖和一些代码的不兼容,而且目前适用范围不是很广,这里我就继续选择vue2进行操作)

创建完成后,进入项目并运行,检查项目创建是否有误

cd code1
npm run serve

运行成功图如下:

浏览器进入已经运行的vue项目

上面为vue2的默认界面,可以成功进入代表创建项目成功,接下来便开始添加本次功能的依赖

2、添加项目依赖框架

这里可以继续使用gitbash通过代码进行添加,但是由于目前vue版本和依赖版本更新的有些乱,也因为我自己技术水平不够,代码添加的依赖经常不兼容跑错,于是直接使用Vue项目管理器的可视化编辑,大大提高依赖兼容成功性

2.1 使用Vue项目管理器添加依赖

进入code1项目后,使用vue ui 命令打开Vue项目管理器

vue ui

随即会跳转到浏览器,未跳转可以自行输入端口进入

在依赖里面搜索我们所需的四个依赖:

  • element-ui,一个 element 风格的 UI 框架
  • axios,用于网络请求
  • Vuex,用于管理状态
  • vue-router,用于实现两个 Vue 页面的跳转

手动添加后一般都是适应当前vue版本的,不用担心兼容报错问题

2.2 使用命令代码添加依赖

进入code1项目后,按照下列命令依次添加依赖(由于本人学艺不精,命令添加始终无法成功运行element框架,有成功的大神希望可以评论或者私信指导一二,谢谢!)

vue add element
npm install axios
npm install vuex --save
npm install vue-router

3、测试运行项目

添加成功依赖后,输入命令npm run serve运行,出现如下图界面即为成功

这里先贴图一下最后的Vue目录架构:

4、编写view层面代码

4.1 登陆页面:login.vue

<template>
  <div>
    <el-card class="login-form-layout">
      <el-form
        autocomplete="on"
        :model="loginForm"
        ref="loginForm"
        label-position="left"
      >
        <div style="text-align: center">
          <svg-icon icon-class="login-mall" style="width: 56px;height: 56px;color: #409EFF"></svg-icon>
        </div>
        <h2 class="login-title color-main">mall-admin-web</h2>
        <el-form-item prop="username">
          <el-input
            name="username"
            type="text"
            v-model="loginForm.username"
            autocomplete="on"
            placeholder="请输入用户名"
          >
            <span slot="prefix">
              <svg-icon icon-class="user" class="color-main"></svg-icon>
            </span>
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            name="password"
            :type="pwdType"
            @keyup.enter.native="handleLogin"
            v-model="loginForm.password"
            autocomplete="on"
            placeholder="请输入密码"
          >
            <span slot="prefix">
              <svg-icon icon-class="password" class="color-main"></svg-icon>
            </span>
            <span slot="suffix" @click="showPwd">
              <svg-icon icon-class="eye" class="color-main"></svg-icon>
            </span>
          </el-input>
        </el-form-item>
        <el-form-item style="margin-bottom: 60px">
          <el-button
            style="width: 100%"
            type="primary"
            :loading="loading"
            @click.native.prevent="handleLogin"
          >登录</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}
                });
              } else {
                this.$router.push({
                  path: "/error",
                  query: { message: response.data.message }
                });
              }
            })
            .catch(() => {
              this.loading = false;
            });
        } else {
          // eslint-disable-next-line no-console
          console.log("参数验证不合法!");
          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>

4.2  登陆成功页面:success.vue

<template>
  <div>
    <h1>Welcome!{{msg}}, <br>操作信息: {{mes}},<br>状态码{{cod}}</h1>
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg: this.$route.query.data.data,
      mes: this.$route.query.data.message,
      cod: this.$route.query.data.code
    };
  },
}
</script>

4.3 登陆失败页面:error.vue

<template>
  <div>
    <h1>登录错误:{{msg}}</h1>
  </div>
</template>
<script>
export default {
  data() {
    return {
      msg: null
    };
  },
  created() {
    this.msg = this.$route.query.message;
  }
};
</script>

5、设置路由统一管理页面

5.1 创建路由文件

建立的 router 文件夹下创建一个 index.js 文件,内容如下

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
export const constantRouterMap = [
    { path: '/', component: () => import('@/views/login')},
    { path: '/success', component: () => import('@/views/success')},
    { path: '/error', component: () => import('@/views/error'), hidden: true }
]

export default new VueRouter({
    scrollBehavior: () => ({ y: 0 }),
    routes: constantRouterMap
})

5.2 将创建好的路由引入到项目中

在项目的 src 目录根节点下,找到 main.js,修改内容如下:

import Vue from 'vue'
import App from './App.vue'
import './plugins/element.js'
import router from './router'
Vue.config.productionTip = false

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

5.3 设置路由的出入口

路由还需要一个出入口,这个出入口用来告诉路由将路由的内容显示在这里。上面 main.js 配置的第一个 vue 显示页面为 App.vue ,因此我们修改 App.vue 内容如下:

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

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

6、配置网络请求

6.1 封装请求工具

使用axios 这个网络请求构架进行 http 的请求,在 utils 包下封装一个请求工具类 request.js:

import axios from 'axios'
import baseUrl from '../api/baseUrl'
const service = axios.create({
  baseURL: baseUrl,
  timeout: 15000,
})
export default service

6.2 登录页面接口 API

在 api 文件夹下,创建一个登录API文件login.js:

import request from '@/utils/request'
export function login(username, password) {
  return request({
    url: '/admin/login',
    method: 'post',
    data: {
      username,
      password
    }
  })
}

6.3 封装 axios

使用 Vuex,先封装Vuex 中的module,在 store 文件夹下创建一个 modules 文件夹,在此文件夹下创建 user.js 文件:

import { login } from '@/api/login'

const user = {
  actions: {
    Login({ commit }, userInfo) {
      const username = userInfo.username.trim()
      return new Promise((resolve, reject) => {
        login(username, userInfo.password).then(response => {
          commit('')
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },
  }
}
export default user

创建 Vuex,在 store 文件夹下创建一个 index.js 文件:

import Vue from 'vue'
import Vuex from 'vuex'

import user from './modules/user'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    user
  }
})

将 Vuex 引入项目,修改之前的 main.js 文件如下:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'

Vue.config.productionTip = false

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

五、实现登录功能

1、启动两端程序,进入locallhost:8080

2、输入账号密码

2.1 正确登录

点击登录,进入后还会显示登陆状态、操作信息和状态码,

注意:这里修改了账户名为:test

2.2 错误登录

总结

到此,就通过springboot+vue实现了最基础的登录功能。在这次学习中借鉴了Eli Shaw大神的文章,由于vue版本及其依赖更新换代比较快,springboot也有部分更新不可用的,以前的代码会有报错,这篇文章希望可以提供一些帮助,有很多不足和缺点问题也希望可以提出,十分感谢!

在Github上有这个功能完整的项目:mirrors / macrozheng / mall-admin-web · GitCode

到此这篇关于springboot+vue实现登录功能的文章就介绍到这了,更多相关springboot+vue登录功能内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot+VUE实现登录注册

    本文实例为大家分享了springboot+VUE实现登录注册的具体代码,供大家参考,具体内容如下 一.springBoot 创建springBoot项目 分为三个包,分别为controller,service, dao以及resource目录下的xml文件. UserController.java package springbootmybatis.controller; import org.springframework.web.bind.annotation.CrossOrigin; im

  • vue+springboot实现登录功能

    本文实例为大家分享了vue+springboot实现登录功能的具体代码,供大家参考,具体内容如下 1. 登录功能的实现 实现提交表单的代码如下: async submitForm(user) { this.$refs[user].validate((valid) => { if(valid){ alert("user"); this.$axios.post("http:localhost:8087/user/login?code="+this.code,use

  • vue+springboot前后端分离实现单点登录跨域问题解决方法

    最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登录咯,至于不知道什么是单点登录的同学,建议去找一下万能的度娘. 刚接到这个需求的时候,老夫心里便不屑的认为:区区登录何足挂齿,但是,开发的过程狠狠的打了我一巴掌(火辣辣的一巴掌)...,所以这次必须得好好记录一下这次教训,以免以后再踩这样的坑. 我面临的第一个问题是跨域,浏览器控制台直接报CORS,

  • springboot+vue实现登录功能

    本文实例为大家分享了springboot+vue实现登录功能的具体代码,供大家参考,具体内容如下 目录结构 前端端口:8080 后端端口:8900 login.vue <template> <div class="login_content"> <!-- 登录块 --> <div class="login_box"> <!-- 头像 --> <div class="avatar_box&qu

  • vue+springboot实现登录验证码

    本文实例为大家分享了vue+springboot实现登录验证码的具体代码,供大家参考,具体内容如下 先看效果图 在login页面添加验证码html 在后端pom文件添加kaptcha依赖 <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </depen

  • springboot+vue实现登录功能的最新方法整理

    目录 一.介绍 二.环境工具 三.搭建后端spring-boot框架 1.选择Spring Initializr创建新项目 2.CommonResult类 3.IErrorCode 接口 4.ResultCode 枚举 5.User类 6.LoginController类 7.修改DemoApplication 8.更改端口号在application.yml 9.不同端口需要解决跨域问题 四.搭建前端Vue框架 1.创建Vue项目 2.添加项目依赖框架 2.1 使用Vue项目管理器添加依赖 2.

  • SpringBoot+Vue实现EasyPOI导入导出的方法详解

    目录 前言 一.为什么做导入导出 二.什么是 EasyPOI 三.项目简介 项目需求 效果图 开发环境 四.实战开发 核心源码 前端页面 后端核心实现 五.项目源码 小结 前言 Hello~ ,前后端分离系列和大家见面了,秉着能够学到知识,学会知识,学懂知识的理念去学习,深入理解技术! 项目开发过程中,很大的需求都有 导入导出功能,我们依照此功能,来实现并还原真实企业开发中的实现思路 一.为什么做导入导出 为什么做导入导出 导入 在项目开发过程中,总会有一些统一的操作,例如插入数据,系统支持单个

  • springboot+vue实现验证码功能

    本文实例为大家分享了springboot+vue实现验证码功能的具体代码,供大家参考,具体内容如下 1.工具类 直接用不用改 package com.example.demo.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.ht

  • ThinkPHP登录功能的实现方法

    登陆功能是PHP程序设计中常见的功能.本文ThinkPHP实例主要完成注册成功后进入首页,并告诉你是登录用户的功能.具体实现步骤如下: 第一步:在config.php文件中加上: 'USER_AUTH_KEY'=>'authId' 示例如下: <?php if(!defined('THINK_PATH')) exit(); return array( // 定义数据库连接信息 'DB_TYPE'=> 'mysql',// 指定数据库是mysql 'DB_HOST'=> 'local

  • Spring Security 表单登录功能的实现方法

    1.简介 本文将重点介绍使用 Spring Security 登录. 本文将构建在之前简单的 Spring MVC示例 之上,因为这是设置Web应用程序和登录机制的必不可少的. 2. Maven 依赖 要将Maven依赖项添加到项目中,请参阅Spring Security with Maven 一文. 标准的 spring-security-web 和 spring-security-config 都是必需的. 3. Spring Security Java配置 我们首先创建一个扩展 WebSe

  • vue实现登录功能

    1.背景 完成了登录的表单输入框界面如下: 代码: <!-- 输入框--> <el-form label-width="0px" class="login_form"> <!-- 用户名 --> <el-form-item > <el-input prefix-icon="el-icon-s-custom"></el-input> </el-form-item>

  • Springboot整合第三方登录功能的实现示例

    springboot 项目的pom文件引入依赖 <dependency> <groupId>me.zhyd.oauth</groupId> <artifactId>JustAuth</artifactId> <version>{latest-version}</version> </dependency> 代码 登录端点(controller) import com.tarzan.cms.common.prop

  • SpringBoot整合微信登录功能的实现方案

    目录 1. OAuth2解决什么问题? 2. 微信扫描登录 2.1 添加必要的依赖 2.2 application.properties 添加配置 2.3 登录请求 2.4 前端 1. OAuth2解决什么问题? OAuth2:是针对特定问题一种解决方案 可以解决两个问题: a. 开放系统间授权 b. 分布式访问问题 解决方案: a. 方式一:用户名密码复制 b. 通用开发者key c. 办法令牌 2. 微信扫描登录 点击进行注册开发者认证 JWT配置 2.1 添加必要的依赖 <!--httpc

随机推荐