springboot2.X整合vue3.x+登录功能的前后端接口实现

首先需要读者已经具备基本了解vue2.X和springboot2.X,element ui等技术

首先是登录页面的写法:

<template>
  <div class="login_container">
    <div class="login_box">
      <!-- 头像区域 -->
      <div class="avatar_box">
        <img src="../assets/logo.png" alt="">
      </div>
      <!-- 登录表单区域 -->
      <el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">
        <!-- 用户名 -->
        <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-3702mima" type="password"></el-input>
        </el-form-item>
        <!-- 按钮区域 -->
        <el-form-item class="btns">
          <el-button type="primary" @click="login">登录</el-button>
          <el-button type="info" @click="resetLoginForm">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Login',
    data() {
      return {
        // 这是登录表单的数据绑定对象
        loginForm: {
          username: 'admin',
          password: '123456'
        },
        // 这是表单的验证规则对象
        loginFormRules: {
          // 验证用户名是否合法
          username: [
            { required: true, message: '请输入登录名称', trigger: 'blur' },
            { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
          ],
          // 验证密码是否合法
          password: [
            { required: true, message: '请输入登录密码', trigger: 'blur' },
            { min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
          ]
        }
      }
    },
    methods:{
      // 点击重置按钮,重置登录表单
      resetLoginForm() {
        // console.log(this);
        this.$refs.loginFormRef.resetFields()//重置
      },
      login() {
        this.$refs.loginFormRef.validate(valid => {
          if (!valid) return;
          console.log('loginForm的值:',this.loginForm);
          this.$myAxios.post('api/login/loginIn',this.loginForm)
            .then(res=>{
              console.log('res的值:',res);
            });

          /*if (res.meta.status !== 200) return this.$message.error('登录失败!')
          this.$message.success('登录成功')
          // 1. 将登录成功之后的 token,保存到客户端的 sessionStorage 中
          //   1.1 项目中出了登录之外的其他API接口,必须在登录之后才能访问
          //   1.2 token 只应在当前网站打开期间生效,所以将 token 保存在 sessionStorage 中
          window.sessionStorage.setItem('token', res.data.token)
          // 2. 通过编程式导航跳转到后台主页,路由地址是 /home
          this.$router.push('/home')*/
        })
      }
    }
  }
</script>

<!--scoped防止各个组件之间样式冲突-->
<style 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 {
    height: 130px;
    width: 130px;
    border: 1px solid #eee;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 0 10px #ddd;
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: #fff;
  }
  img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-color: #eee;
  }

  .login_form {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 0 20px;
    box-sizing: border-box;
  }

  .btns {
    display: flex;
    justify-content: flex-end;
  }
</style>

 

对以上代码关键地方进行说明,首先读者需要自己解决掉跨域问题,然后登录表单绑定loginForm,并将输入的账号和密码也绑定到loginForm上,在data()中定义loginForm,这样当用户输入账号和密码时,就可以自动绑定到loginForm中。登录采用axios的post请求,利用res返回在控制台上打印输出结果,来判断是否获取到数据。

下面是springboot的关键代码部分

package com.smp.controller;
import com.smp.model.LoginForm;
import com.smp.model.VUser;
import com.smp.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("api/login")
@Slf4j
public class LoginController {

    @GetMapping("/hello")
    public String hello()
    {
        return  "hello";
    }

    @PostMapping("loginIn")
    public String loginIn(@RequestBody LoginForm loginForm){

        log.info("运行到loginIn方法来了.................");
        log.info("loginForm的值:",loginForm.toString());
        log.info("username的值:"+loginForm.getUsername());
        log.info("password的值:"+loginForm.getPassword());
        if(loginForm.getUsername()==null||loginForm.getPassword()==null) return null;
        if(loginForm.getUsername().equals("admin")&&loginForm.getPassword().equals("123456")){
            VUser vUser=new VUser();
            vUser.setId(500);
            vUser.setId(0);
            vUser.setUsername("admin");
            vUser.setMobile("123");
            vUser.setEmail("123@qq.com");
            return JwtUtils.getJsonWebToken(vUser);
        }
        return null;
    }
}

返回的jwt格式的token到前端,在springboot中定义一个LoginForm对象,里面只有账号和密码两个属性,跟前端的login.vue里面的保持一致。需要注意的是,需要使用@requestbody注解,否则无法获取到前端传过来的数据

下面是一些可以参考的代码

LoginForm类

package com.smp.model;

import lombok.Data;
import java.io.Serializable;

@Data
public class LoginForm implements Serializable {

    private String username;
    private String password;

}

vue.config.js

module.exports = {
  // 将部署应用程序的基本URL
  // 将部署应用程序的基本URL。
  // 默认情况下,Vue CLI假设您的应用程序将部署在域的根目录下。
  // https://www.my-app.com/。如果应用程序部署在子路径上,则需要使用此选项指定子路径。例如,如果您的应用程序部署在https://www.foobar.com/my-app/,集baseUrl到'/my-app/'.

  publicPath: process.env.NODE_ENV === 'production' ? './' : './',

  // outputDir: 在npm run build时 生成文件的目录 type:string, default:'dist'

  outputDir: 'dist',

  // pages:{ type:Object,Default:undfind }
  /*
  构建多页面模式的应用程序.每个“页面”都应该有一个相应的JavaScript条目文件。该值应该是一
  个对象,其中键是条目的名称,而该值要么是指定其条目、模板和文件名的对象,要么是指定其条目
  的字符串,
  注意:请保证pages里配置的路径和文件名 在你的文档目录都存在 否则启动服务会报错的
  */
  pages: {
    index: {
      //entry for the page
      entry: 'src/main.js',
      //the source template
      template: 'public/index.html',
      //output as dist/index.html
      filename: 'index.html'
    },
    // when using the entry-only string format,
    // template is inferred to be `public/subpage.html`
    // and falls back to `public/index.html` if not found.
    // Output filename is inferred to be `subpage.html`.
    // subpage: 'src/subpage/main.js'
  },

  //   lintOnSave:{ type:Boolean default:true } 问你是否使用eslint
  lintOnSave: true,
  // productionSourceMap:{ type:Bollean,default:true } 生产源映射
  // 如果您不需要生产时的源映射,那么将此设置为false可以加速生产构建
  productionSourceMap: false,
  // devServer:{type:Object} 3个属性host,port,https
  // 它支持webPack-dev-server的所有选项

  devServer: {
    port: 8080, // 端口号
    host: 'localhost',
    https: false, // https:{type:Boolean}
    open: true, //配置自动启动浏览器
    proxy: {// 配置跨域处理,只有一个代理
      "/api": {
        target: "http://localhost:8082/api", // 要访问的接口域名
        ws: true, // 是否启用websockets
        changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
        pathRewrite: {
          '^/api': "/" //这里理解成用'/api'代替target里面的地址,比如我要调用'http://40.00.100.100:3002/user/add',直接写'/api/user/add'即可
        }
      }
    }
    /*css: {
      loaderOptions: {
        css: {},
        postcss: {
          plugins: [
            /!*require('postcss-px2rem')({
              remUnit: 37.5
            })*!/
          ]
        }
      }
    }*/
  }
};
import axios from 'axios';
import { Message,Loading } from 'element-ui';
//import router from '../router/router';当判断登录失效时跳转用的

//载入动画配置
let loading;
function  startLoading() {
  loading=Loading.service({
    lock:true,
    text:'拼命加载中.......',
    background:'rgba(0,0,0,0,7)'
  });
}

function endLoading() {
    loading.close();
}

//以下为对axios的配置
axios.defaults.timeout = 5000; //超时终止请求
//axios.defaults.baseURL ='http://localhost:8080/'; //配置请求地址
//axios.defaults.withCredentials = true;
/*
const instance = axios.create({
  headers: {
    'content-type': 'application/json;charset=UTF-8'
  //  'token': 'one'
  },
 // baseURL: 'https://easy-mock.com/mock/5c01e1f6f221b94c907213d6/',
  timeout: 10000,
 // withCredentials: true
});*/

//request请求拦截
axios.interceptors.request.use(
  config=>{
    //加载动画
    startLoading();
   /* if(localStorage.eleToken){
      //设置统一的请求头
      config.headers.Authorization=localStorage.eleToken;

    }*/
    config.data=JSON.stringify(config.data);
    config.headers={
      'Content-Type':'application/json;charset=UTF-8'
    };
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);


//response响应拦截
axios.interceptors.response.use(
   response=>{
     //结束加载动画
     endLoading();
     return response;
   },
  error => {
     //错误提醒
    endLoading();
    Message.error(error.response.data);

    //获取错误状态码
    const status=error.response;
    if(status===401){
      Message.error('token失效,请重新登录');
      //清除token
     // localStorage.removeItem('eleToken');
      //跳转到登录页面
     // router.push('/login');
    }
    return Promise.reject(error);
  }
);

//为模块指定默认输出
export default axios;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值